Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 21-01-2009
alquimista alquimista is offline
Miembro
 
Registrado: ene 2008
Posts: 203
Poder: 17
alquimista Va por buen camino
Thumbs up Hasta el infinito y mas alla...

Comentar que esto se estaba poniendo interesante.... y se ha parado...

Vulevo a animar a continuar con este hilo.... Todavia me cuesta seguir las explicaciones, pero me he apuntado a esto de la inyeccion y me parece interesantisimo.

Una pregunta esta técnica ¿activa la prevención de ejecución de datos (DEP) de Windows? Probe un ejemplo inyectando en el explorer.exe y se activo.


Un saludo y a ver si poco a poco me entero de algo mas..
Responder Con Cita
  #2  
Antiguo 22-01-2009
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por alquimista Ver Mensaje
Una pregunta esta técnica ¿activa la prevención de ejecución de datos (DEP) de Windows? Probe un ejemplo inyectando en el explorer.exe y se activo.
Teóricamente Microsoft diseñó el DEP para evitar la ejecución de código desde zonas de memoria no asignadas para ello en las aplicaciones. Los intentos de inyección de código, pueden disparar el DEP.

He realizado pruebas de inyección en el explorer.exe y en en el TaskManager, mediante varias técnicas. Todas las inyecciones las he realizado inyectando dll y con el DEP activado para todas las aplicaciones. En ninguna prueba me ha saltado el DEP. Esto puede ser explicado porque las dll en principio son código, o al menos pueden contenerlo. Posiblemente Microsoft no quiere interferir con ellas porque crearía muchos problemas con aplicaciones lícitas y con su propio sistema de Hooks.

Todas las técnicas de inyección de dll, (salvo las que se aprovechan de la API SetWindowHook para cargar una dll) requieren una pequeña inyección directa de código que es el que se encarga de cargar dicha dll. Ese código se coloca en la memoria del proceso (WriteProcessMemory) como se comenta en este hilo, aunque sólo contenga la API LoadLibraryA. Bien es verdad que es difícil escribir una aplicación que maneje, con la precisión suficiente, la paginación de memoria con permisos de ejecución de código, como para no dejar espacio para esa necesaria microinyección de esa API LoadLibraryA o unas cuantas intrucciones asm puro. Diferente sería el caso de la inyección directa de cantidades mayores de código, que pueden hacer saltar el DEP.

En cualquier caso, tener activo el DEP crea muchas falsas alarmas y molestias al usuario, y suele estar desactivado.

Saludos.

Última edición por escafandra fecha: 22-01-2009 a las 16:30:07.
Responder Con Cita
  #3  
Antiguo 27-01-2009
callbacking callbacking is offline
Registrado
 
Registrado: jul 2008
Posts: 9
Poder: 0
callbacking Va por buen camino
Thumbs up Enormemente interesado, sigue con ello.

De hecho ya habia perdido el interés por no haber conseguido casi nada de lo que quería con la inyección de código, incluso me molesté en aprender a usar Fasm y hacerlo en assembler con ayuda también de Ollydbg, hace casi un año escribí un post intentando conseguir ayuda y he acudido también a otros foros, he abandonado en Septiembre pasado, pero quizá saque ganas de nuevo. Nunca hubo oscuro propósito, intenté obtener los textos de drawtext y textout antes que windows los volcara en pantalla, conseguí hubicar mi función y las direcciones correctas de los saltos, pero no fui capaz de recuperar y modificar los datos sin que petara el sistema. Al igual que tu, me pareció mas sencillo ubicar la función que inyectar una .dll. No conseguí nada,

O SEASE, A MI SI ME INTERESA SEGUIR LEYENDO, EL ALGUNA PARTE ESTA LO QUE NECESITO PARA QUE MI RUTINA FUNCIONE, ES BUENA IDEA ESTE HILO.
CREIA QUE NADIE TENIA INTERÉS POR ALGO TAN INTERESANTE COMO ESTO.
Responder Con Cita
  #4  
Antiguo 27-01-2009
callbacking callbacking is offline
Registrado
 
Registrado: jul 2008
Posts: 9
Poder: 0
callbacking Va por buen camino
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.
Responder Con Cita
  #5  
Antiguo 27-01-2009
callbacking callbacking is offline
Registrado
 
Registrado: jul 2008
Posts: 9
Poder: 0
callbacking Va por buen camino
Talking Una preguntita ya que estoy

Podrias probar si tu código funciona con drawtextw? Gracias.
Responder Con Cita
  #6  
Antiguo 28-01-2009
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
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); 
}
Existe otro problema, una misma API puede precisar sobreescribir un número diferente de Bytes para producir el salto, dependiendo de las diferentes versiones del S.O. De forma que puede no funcionar en máquinas diferentes. Esto obliga a un estudio particular de la máquina en cuestión o a un desensamblado por código en una función Hook escrita para tal fin.

El tema es engorroso

Saludos.
Responder Con Cita
  #7  
Antiguo 31-10-2018
jairo10 jairo10 is offline
Registrado
NULL
 
Registrado: oct 2018
Posts: 4
Poder: 0
jairo10 Va por buen camino
Que buena explicación de este tema para avanzar mas gracias
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

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


La franja horaria es GMT +2. Ahora son las 20:27:36.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi