• API Hooking con IAT Patching

 #365220  por Binary_Death
 22 Abr 2012, 16:00
Os dejo un código que estuve haciendo, que consiste en el API Hooking de siempre pero esta vez modificando la IAT.

En el foro de elhacker.net encontré un tutorial de API Hooking hecho por YST & Hacker_Zero, que me sirvió muchísimo, pero resulta que quedó a medias y el método de IAT patching no se explica. Con esa información y un poco de búsqueda salió esto:
Código: [ Debe registrarse para ver este enlace ]
.386
.model flat, stdcall
option casemap:none

assume fs:nothing

include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib


.data
	Process					db 'ejecutable.exe',0
	Kernel					db 'kernel32.dll',0
	GetProc					db 'GetProcAddress',0
.data?
	Function				dd ?
	FunctionLen				dd ?
	pInfo						PROCESS_INFORMATION <>
	sInfo						STARTUPINFO <>
function_start PROTO
.code
start:
		invoke CreateProcess,0,addr Process,0,0,0,0,0,0,addr sInfo,addr pInfo
		
		mov eax,offset function_end
		sub eax,offset function_start
		mov [FunctionLen],eax
		
		invoke VirtualAllocEx,[pInfo.hProcess],0,[FunctionLen],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE
		mov [Function],eax
		
		invoke GetModuleHandle,offset Kernel
		mov [KernelBase],eax
		push offset GetProcAddressName
		
		invoke GetProcAddress,eax,offset GetProc
		mov [pGetProcAddress],eax
		mov ebx,offset function_start
		
		invoke WriteProcessMemory,[pInfo.hProcess],[Function],offset function_start,[FunctionLen],0
		invoke CreateRemoteThread,[pInfo.hProcess],0,0,[Function],0,0,0
		invoke ExitProcess,0

;Injecting Function
function_start PROC
    call delta
		delta:
			pop ebp
			sub ebp, offset delta
			mov ebx, fs:[030h]
			;Getting host process IAT address and its size
			mov eax,[ebx+08h]
			mov ebx,[eax+03Ch]
			add ebx,eax
			mov edx,[ebx+0D8h]
			add edx,eax
			mov [ebp+pIAT],edx
			mov edx,[ebx+0DCh]
			mov [ebp+IATsize],edx
			
			;Getting the needed API's
				;GetModuleHandle
			mov ebx,offset GetModuleHandleName
			add ebx,ebp
			push ebx
			push dword ptr [ebp+KernelBase]
			call [ebp+pGetProcAddress]
			mov [ebp+pGetModuleHandle],eax
				;VirtualProtect
			mov ebx,offset VirtualProtectName
			add ebx,ebp
			push ebx
			push dword ptr [ebp+KernelBase]
			call [ebp+pGetProcAddress]
			mov [ebp+pVirtualProtect],eax
			;Getting address of MessageBox
			mov ebx,offset user32name
			add ebx,ebp
			push ebx
			call [ebp+pGetModuleHandle]
			mov ebx,offset MessageBoxName
			add ebx,ebp
			push ebx
			push eax
			call [ebp+pGetProcAddress]
			mov [ebp+pMessageBox],eax
			;Showing a MessageBox
			push MB_OK + MB_ICONINFORMATION
			push 0
			mov ebx,offset MsgInjected
			add ebx,ebp
			push ebx
			push 0
			call [ebp+pMessageBox]
			;Finding pointing address
			xor edx,edx
			mov eax,[ebp+IATsize]
			mov ecx,04h
			div ecx
			mov ecx,eax
			mov eax,[ebp+pMessageBox]
			mov edi,[ebp+pIAT]
			repnz scasd
			sub edi,04h
			;Patching the IAT
			mov ebx,offset OldProtect
			add ebx,ebp
			push ebx
			push PAGE_EXECUTE_READWRITE
			push 04h
			push edi
			call [ebp+pVirtualProtect]
			mov ebx,offset Hook
			add ebx,ebp
			mov [edi],ebx
			ret

pIAT dd ?
IATsize dd ?
BaseImage dd ?
KernelBase dd ?
pGetProcAddress dd ?
GetProcAddressName db "GetProcAddress",0
user32name db "user32.dll",0
MessageBoxName db "MessageBoxA",0
pMessageBox dd ?
GetModuleHandleName db "GetModuleHandleA",0
pGetModuleHandle dd ?
VirtualProtectName db "VirtualProtect",0
pVirtualProtect dd ?
OldProtect dd ?
MsgInjected db "The function has been injected!",0

Hook: 
	;Delta offset
	call deltahook
		deltahook:
			pop ebp
			sub ebp,offset deltahook
			pop ebx						;Saving to return after
			mov edi,offset msghook
			add edi,ebp
			mov [esp+04h],edi			;Changing the stack parameters
			call [ebp+pMessageBox]		;Calling the original address of MessageBox
			push ebx					;Setting the returning address
			ret
msghook 	db "MessageBox Hooked!", 0
function_start endp
function_end:
end start
Hay que cambiar muchas cosas y corregir otras tantas, pero ahí está la idea.
Por favor, si veis algo que cambiar decidmelo :P

Ah, por cierto. Si no usé invoke y demás directivas de masm es porque simplemente no me aclaro con la sintaxis de cada ensamblador, es lo que hay.
Lo siento si os resulta un poco difícil leer las llamadas a las API con push y call.

PD: Faltaría abrir un proceso en vez de crearlo. En ese ejemplo hookea la API MessageBox haciendo que siempre devuelva el mismo mensaje. Lo apliqué a un ejecutable que mostraba dos MessageBox, sin iniciar el proceso como suspendido. Así, el primero se mostraba normalmente y el segundo ya aparecía hookeado.

Un saludo!
 #367065  por linkgl
 05 May 2012, 20:07
Jeje no sabía yo como aplicar ese método parcheando la IAT muy bueno, y olvidate de las macros como invoke como dirían en h-sec, son para débiles haha saludos.