FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
|||
|
|||
Como prueba de mi interés...
Me gustaría disponer de ese código delphi al completo, como prueba no mostraré mis desastres en delphi, mostraré un medio éxito en fasm(si se me permite) que es a propósito del tema en cuestión, debido a las múltiples pruebas que realicé puede contener comentarios de lineas de código ya extintas, asi como variables que no se usan, creo que este era el código que era capaz de inyectar una función en la api drawtextw(tengo varias pruebas), aunque no parece cambiar los textos antes de ser escritos, ... para muestra un botón...
Api Hooking por inyección de código, aproximación en fasm. Código:
include 'd:\fasm\include\win32ax.inc' .data HookApi db 'DrawTextW' , 0 ; Nombre del api a hookear HookDll db 'user32.dll' , 0 ; Nombre de la dll que contiene el api a hookear dirapi dd ? ; Dirección del api a hookear texto db 'hello' process dd ? ; El handle del proceso donde inyectaremos pid dd 1240 ; El pid del proceso donde inyectaremos--estesalio del taskmanager y fue notepad ;PONER PID ADECUADO Y COMPILAR DE NUEVO x dd 5 ; --------------------api DrawTextW ; ;-------------------------------------- total 5 bytes si esta es la teoría lo dijo ollydbg y punto. ; El número de bytes que tiene al principio el api a hookear (suelen ser 5 ó 7) buffercall dd ? ; Puntero al buffer para llamar al api (en nuestro propio proceso) inibuffer dd ? ; siempre guardada la direccion original del inicio del buffer inidirapi dd ? ; siempre guardado el inicio del api inifun dd ? ; siempre guardado el inicio de mi funcion tamfun dd ? ; Tamaño de la función que suplantará al api ;---------------------------------------------------------------------------------------------- dircode dd ? ; La dirección donde esta escribe la estructura una vez INYECTADA Prote dd ? ; Necesario para VirtualProtect saltoapi dd ? ; la direccion calculada a la api+5 buffsaltoami dd ? tamtotal dd ? ;1+tamfun+1+5+5 .code start: ; Obtenemos el handle del proceso donde inyectaremos mov eax, PROCESS_VM_OPERATION or eax, PROCESS_VM_WRITE ; mov eax,PROCESS_ALL_ACCESS invoke OpenProcess, eax, FALSE, [pid] mov [process], eax ; ; Obtenemos la dirección del api a Hookear invoke GetModuleHandle, HookDll invoke GetProcAddress, eax, HookApi mov [dirapi], eax ; vale la dir de la api mov [inidirapi],eax ; siempre guardado sin alterar el inicio ;Vamos a ver , reservamos espacio para pushad+(tamaño de mi funcion)+popad+(5 bytes de la api)+jmp dirapi+5 = ; 1+tamfun+1+5+5 ;ahi es na ;a ver el tamaño de la función ; Calculamos el tamaño de la función a inyectar mov eax, FIN_drawtextexw sub eax, Mydrawtextexw mov [tamfun], eax ;pues eso ; 1+tamfun+1+5+5 ; mov eax, 1 add eax, [tamfun] add eax,1 add eax,[x] add eax,5 mov [tamtotal],eax ; tamtotal tiene el tamaño del buffer invoke LocalAlloc, LPTR, [tamtotal] ; espacio local reservado para escritura del buffer mov [buffercall], eax ; aqui la direccion inicio del buffer mov [inibuffer],eax ;aqui también para no perderla, por variables va a ser mov eax,[buffercall] mov byte [eax],0x90 ; 60 pushad 90 es nop inc eax mov [buffercall],eax ;puesto el opcode e incrementado el buffer ;ahora a copiar aqui la funcion mov ebx,CAMBIO ;direccion de la funcion mov [inifun],ebx ;aqui tambien, no perderla invoke RtlMoveMemory, [buffercall],ebx,[tamfun]; la función al buffer mov eax,[buffercall] add eax,[tamfun] ; incrementamos el buffer hasta el fin de la funcion mov [buffercall],eax ; copia la funcion y ademas incrementa buffercall ;ahora el opcode de popad 61 90 es nop mov eax,[buffercall] mov byte [eax],0x90 ;despues de la funcion pues popad o noP inc eax mov [buffercall],eax ;uno mas para empezar con la api ;ahora vienen los 5 bytes de la api ;los bytes del api al final del buffer, pero le resto 4, si no no rula mov eax, [buffercall] sub eax,4 mov [buffercall],eax ; visto con ollydbg invoke WaitForInputIdle,[process],1000 ; si señor, esto ya es otra cosa, si no peta. ; desde dirapi 5 bytes al buffer invoke RtlMoveMemory, [buffercall], [dirapi], [x] ; Copiamos los x primeros bytes del api mov eax, [buffercall] add eax, [x] ;entonces incrementamos el buffer en x bytes mov [buffercall],eax ; se supone que ahora lo que falta es el salto a la api+5 (o +4?) ;para esto necesito la direccion donde voy a inyectar el codigo mov eax, MEM_RESERVE or eax, MEM_COMMIT invoke VirtualAllocEx, [process], NULL, [tamtotal], eax, PAGE_EXECUTE_READWRITE mov [dircode],eax ;direccion para inyectar el codigo en proceso remoto ;dirapi debe estar mas arriba mov eax,[dirapi];no ha cambiado, la seguimos usando entonces add eax,5 ; ya cambio, dirapi es ahora dirapi+5 mov ebx,[dircode] add ebx,[tamtotal] ; ja! el salto es desde el final del jmp o justo desde antes? ; que problema no saberlo, intentemos asi y si no decremento 4 o 5, 4 despues del jmp ; antes de los 4 bytes del salto, 5, antes del jmp y los 4 bytes del salto. sub eax,ebx ; a ver si... (dirapi+5)-(dircode+tamaño total buffer)=direccion del salto a api+5 mov [saltoapi],eax mov eax,[buffercall] mov byte [eax],0xE9 inc eax mov [buffercall],eax ;insertado opcode jmp e incrementado buffer mov ebx,[saltoapi] ; coño, el salto se queda 4 bytes corto!!!!!!! ; add ebx,4 ;asi supongo que salte donde debe mov dword [eax],ebx; con esto se suponen 4 bytes del dword del salto ;ahora podemos escribir el buffer en el espacio de la aplicacion ;que previamente reservamos ;debemos indicar el tamaño total claro ;el buffer se supone escrito, ahora lo volcamos en el proceso remoto ;invoke VirtualProtect, [dircode-5],[tamtotal+5],PAGE_EXECUTE_READWRITE,NULL invoke WriteProcessMemory, [process],[dircode],[inibuffer],[tamtotal],NULL ; y ahora claro esta tendremos que insertar el salto en la api ; a nuestro codigo ; si dirapi esta por encima como coño hago un salto negativo? ; y además permisos a los 5 bytes de la api claro esta invoke LocalAlloc, LPTR, 5 mov [buffsaltoami],eax mov eax,[dircode] mov ebx,[dirapi] sub eax,ebx sub eax,5; por algun motivo que no se, salta a la dirección ;no entiendo yo este problema con los... si lo pongo salta desde api a pushad ;sino lo pongo salta bytes mas allá. Asi que ... mov [saltoapi],eax ;mmmmmmm dir del salto mov eax,[buffsaltoami] mov byte [eax],0xE9 inc eax ; mov [buffsaltoami],eax mov ebx,[saltoapi] mov dword [eax],ebx mov eax, MEM_RESERVE ; eax = MEM_RESERVE | MEM_COMMIT or eax, MEM_COMMIT invoke VirtualAllocEx, [process], [dirapi], 5, eax, PAGE_EXECUTE_READWRITE invoke WriteProcessMemory, [process], [dirapi], [buffsaltoami], 5, NULL ; y colorin colorado... invoke ExitProcess,0 CAMBIO: proc Mydrawtextexw dc, lpstring,ncount,lprect,uformat nop mov byte [lpstring],0x41 mov byte [ncount],1 nop ;referencias mias en la inyección endp FIN_drawtextexw: .end start - Se supone que la filosofia de esto es: -en el inicio de la función api se inserta un salto a una función propia. -después de ejecutar la nueva función, se inserta en esta otro salto a la api original posterior al salto a nuestra función. |
#2
|
|||
|
|||
Una preguntita ya que estoy
Podrias probar si tu código funciona con drawtextw? Gracias.
|
#3
|
||||
|
||||
Hola callbacking. He hecho la prueba que comentabas en tu anterior post, pero inyectando dll. He realizado un Hook a las APIs DrawTextA y DrawTextW. La inyección la he hecho en el notepad, como en tu ejemplo y también en el explorer. No he tenido problemas en capturar el texto o cambiarlo.
El problema mas común al hacer un Hook a una API suele ser la corrupción de la pila, no cuando un programa llama directamente a esa API, sino cuando la llamada se realiza desde otra API. Es fácil darse cuenta si el Hook lo hacemos en ASM y hacemos un debug. En el último ret nos vamos de bareta pues la pila se corrompió. Los experimentos los he realizado en C y básicamente el sistema ha sido asi: Código:
// Definición del tipo Puntero a la función API que vamos a Hookear. typedef INT (__stdcall *PDrawTextW)(HDC hDC, LPCWSTR lpWStr, INT nCount, LPRECT lpRect, UINT uFormat); // Declaración de un tpunero de ese tipo. PDrawTextW Ini_DrawTextW = 0; //............ // Preparación del Hook // Sustitución de los 5 primeros Bytes de DrawText por JMP HookDrawText // Ini_DrawText es un puntero a una función con la copia de los Bytes sustituidos de la API original seguido de JMP al 6º Byte de esa API. Para esto se reserva espacio de 10 Bytes mínimo. //........... // Función Hookeada: // Fundamental que sea __stdcall para no corroper la pila.... INT __stdcall HookDrawText(HDC hDC, LPCWSTR lpWStr, INT nCount, LPRECT lpRect, UINT uFormat) { ...... ...... // Lamada a la API original. En este punto podemos volver a tomar el control antes de retornar. return Ini_DrawTextW(hDC, lpWStr, nCount, lpRect, uFormat); } El tema es engorroso Saludos. |
#4
|
|||
|
|||
Que buena explicación de este tema para avanzar mas gracias
|
#5
|
|||
|
|||
Y al final ?
Bueno, al final me quede sin saber como Inyectar código. Nunca se termino el hilo.
|
#6
|
||||
|
||||
El hilo quedó incompleto. si tienes interés en estos temas, puedes encontrar información aquí:
Inyección directa de código en C y en delphi Inyección directa de código II HOOK a la API en delphi y en C HOOK a la API64 API UnHooker deshaciendo un Hook a la API tipo trampolín ¿Protegernos contra inyecciones dll? Shellcode en C compatible con distintas inyecciones Encriptando funciones hasta conseguir un shellcode en delphi Seguro que me dejo cosas en el tintero Saludos. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Thread y servidor DCOM externo al proceso ( EXE ) | Aldo | OOP | 1 | 15-09-2006 17:39:47 |
Como utilizar un componente externo? | Sergei | OOP | 2 | 24-01-2006 19:12:24 |
Inyectar proceso | conde | API de Windows | 4 | 10-09-2005 15:52:17 |
Como se puede programar directamente??? | Antuan | Varios | 10 | 04-08-2005 08:04:38 |
Como correr un archivo externo? | fayala | Firebird e Interbase | 3 | 07-04-2005 03:56:00 |
|