Bueno estoi intentando hookear una API desde una DLL creada en Fasm pero no lo consigo y nose que estoi haciendo mal, este es el código de la dll:
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32ax.inc'
section '.code' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
locals
proteccion dd ?
endl
invoke LoadLibrary,'user32.dll'
invoke GetProcAddress,eax,"MessageBoxA"
mov ebx,eax; ebx = direccion MessageBoxA
invoke VirtualProtect,-1,ebx,5,PAGE_EXECUTE_READWRITE,edx
mov ebx,0xE9
inc ebx
mov dword[ebx],hook
add ebx,4
ret
endp
proc hook,uno,dos,tres,cuatro
invoke MessageBox,0,0,0,0
mov eax,0
ret
endp
; VOID ShowErrorMessage(HWND hWnd,DWORD dwError);
proc ShowErrorMessage hWnd,dwError
local lpBuffer:DWORD
lea eax,[lpBuffer]
invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,[dwError],LANG_NEUTRAL,eax,0,0
invoke MessageBox,[hWnd],[lpBuffer],NULL,MB_ICONERROR+MB_OK
invoke LocalFree,[lpBuffer]
ret
endp
; VOID ShowLastError(HWND hWnd);
proc ShowLastError hWnd
invoke GetLastError
stdcall ShowErrorMessage,[hWnd],eax
ret
endp
section '.data' data readable writeable
mensajito db ?
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'
import kernel,\
GetLastError,'GetLastError',\
SetLastError,'SetLastError',\
FormatMessage,'FormatMessageA',\
LocalFree,'LocalFree',\
LoadLibrary,'LoadLibraryA',\
GetProcAddress,'GetProcAddress',\
VirtualProtect,'VirtualProtectEx'
import user,\
MessageBox,'MessageBoxA'
section '.edata' export data readable
export 'ERRORMSG.DLL',\
ShowErrorMessage,'ShowErrorMessage',\
ShowLastError,'ShowLastError'
section '.reloc' fixups data discardable
Esperando repuesta...
salu2!
Mira la declaración de VirtualProtectEx:
http://msdn.microsoft.com/en-us/library/aa366899(v=vs.85).aspx
CitarhProcess [in]
A handle to the process whose memory protection is to be changed. The handle must have the PROCESS_VM_OPERATION access right. For more information, see Process Security and Access Rights.
No dice que pueda ser NULL. Y además:
CitarlpflOldProtect [out]
A pointer to a variable that receives the previous access protection value of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.
Saludos
Edito: Además, en el jmp con el que pisas el comienzo de la api, no tienes que poner la dirección hacia la que quieres saltar, sinó la distancia de salto.
Edioto 2:
Además, con esta línea:
mov ebx,0xE9
Te estás cargando el puntero, tú quieres hacer mov byte[ebx],0xE9
Este es el código que he reparado con los errores que me diiste Zero pero sigue sin funcionar:
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32ax.inc'
section '.code' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
locals
proteccion dd ?
endl
invoke LoadLibrary,'user32.dll'
invoke GetProcAddress,eax,"MessageBoxA"
mov ebx,eax; ebx = direccion MessageBoxA
invoke VirtualProtect,ebx,5,PAGE_EXECUTE_READWRITE,addr proteccion
mov byte[ebx],0xE9
inc ebx
call distancia
distancia:
pop ecx
add ecx,4
sub ecx,hook
mov dword[ebx],ecx
add ebx,4
ret
endp
proc hook,uno,dos,tres,cuatro
invoke MessageBox,0,'Juan te hookeo',0,0
mov eax,0
ret
endp
; VOID ShowErrorMessage(HWND hWnd,DWORD dwError);
proc ShowErrorMessage hWnd,dwError
local lpBuffer:DWORD
lea eax,[lpBuffer]
invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,[dwError],LANG_NEUTRAL,eax,0,0
invoke MessageBox,[hWnd],[lpBuffer],NULL,MB_ICONERROR+MB_OK
invoke LocalFree,[lpBuffer]
ret
endp
; VOID ShowLastError(HWND hWnd);
proc ShowLastError hWnd
invoke GetLastError
stdcall ShowErrorMessage,[hWnd],eax
ret
endp
section '.data' data readable writeable
mensajito db ?
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'
import kernel,\
GetLastError,'GetLastError',\
SetLastError,'SetLastError',\
FormatMessage,'FormatMessageA',\
LocalFree,'LocalFree',\
LoadLibrary,'LoadLibraryA',\
GetProcAddress,'GetProcAddress',\
VirtualProtect,'VirtualProtect'
import user,\
MessageBox,'MessageBoxA'
section '.edata' export data readable
export 'ERRORMSG.DLL',\
ShowErrorMessage,'ShowErrorMessage',\
ShowLastError,'ShowLastError'
section '.reloc' fixups data discardable
salu2! y gracias por la ayudaaa
Estás calculando mal la distancia, es la distancia desde la api hasta la dirección donde está hook una vez carga la DLL.
Saludos
Muchas gracias una vez más :-[ :-* jajaja
Este es el código funcional, lo comente para que mas gente lo comprenda tambien :)
;##########################################################
;## Ejemplo API Hoking by Drinky94 ##
;## Agradecimientos a: ##
;## [Zero] por todo en lo que me ayuda ##
;## YST por su funcion ASCIITOUNICODE ##
;##########################################################
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32ax.inc'
section '.code' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
locals
proteccion dd ?
endl
stdcall ASCIITOUNICODE,mensajito,buffer;pasamos la cadena que se mostrara en MessageBoxW a Unicode
invoke LoadLibrary,'user32.dll' ;Cargamos User32
invoke GetProcAddress,eax,"MessageBoxA" ;obtenemos la direccion de la api
mov ebx,eax; ebx = direccion MessageBoxA
mov eax,hook ;Calculamos la distancia entre el jmp y la funcion donde saltaremos
sub eax,ebx
sub eax,4
mov ecx,eax
push ebx
push ecx
invoke VirtualProtect,ebx,5,PAGE_EXECUTE_READWRITE,addr proteccion ;le damos a 5 bytes permiso de escritura
pop ecx
pop ebx
mov byte[ebx],0xE9 ;escribimos un jmp
inc ebx
mov dword[ebx],ecx ;escriimos la longitud del salto
add ebx,4
ret
endp
proc hook,uno,dos,tres,cuatro ;funcion que remplaza a MesasgeBoxA
invoke MessageBox,0,buffer,0,0 ;Si se llama a MessageBoxA, mostramos nuestro mensagito :PP
mov eax,0 ;devolvemos cero
jmp ebx ;saltamos donde nos quedamos para continuar la ejecucion.
endp
proc ASCIITOUNICODE,Cadena,Buffer
;Funcion By YST
push ecx ebx
mov eax,[Cadena]
mov ebx,[Buffer]
dec eax
sub ebx,2
.bucle:
inc eax
cmp byte[eax],0
je .salir
add ebx,2
mov cl,byte[eax]
mov byte[ebx],cl
mov byte[ebx+1],0
jmp .bucle
.salir:
pop ebx ecx
ret
endp
proc ShowErrorMessage hWnd,dwError
local lpBuffer:DWORD
lea eax,[lpBuffer]
invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,[dwError],LANG_NEUTRAL,eax,0,0
invoke MessageBox,[hWnd],[lpBuffer],NULL,MB_ICONERROR+MB_OK
invoke LocalFree,[lpBuffer]
ret
endp
; VOID ShowLastError(HWND hWnd);
proc ShowLastError hWnd
invoke GetLastError
stdcall ShowErrorMessage,[hWnd],eax
ret
endp
section '.data' data readable writeable
mensajito db 'Msgbox Hookeado',0
buffer db ?
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'
import kernel,\
GetLastError,'GetLastError',\
SetLastError,'SetLastError',\
FormatMessage,'FormatMessageA',\
LocalFree,'LocalFree',\
LoadLibrary,'LoadLibraryA',\
GetProcAddress,'GetProcAddress',\
VirtualProtect,'VirtualProtect'
import user,\
MessageBox,'MessageBoxW'
section '.edata' export data readable
export 'ERRORMSG.DLL',\
ShowErrorMessage,'ShowErrorMessage',\
ShowLastError,'ShowLastError'
section '.reloc' fixups data discardable
salu2!
Tienes un error, ese jmp ebx que haces en la función que recibe el hook no va a ir a donde tu quieres, ahí ebx puede valer cualquier cosa, tienes que obtener la dirección de la API y saltar a dirAPI+5 si quieres volver a la API o sacar los parámetros y la dirección de retorno de la pila para volver al código que llamó a MessageBoxA.
Saludos
A mi me funciona perfectamente Zero, sigue perfectamente la ejecucion del programa...
Cita de: Drinky94 en 5 Mayo 2011, 15:33 PM
A mi me funciona perfectamente Zero, sigue perfectamente la ejecucion del programa...
Seguro? Con el jmp ebx ahí?
Saludos
si :)
salu2!
parece ser que no se altera el registro ebx hasta llegar a ese procedimiento.
Nox.