¡Cómo ENGANCHAR una función API en C#!
HOOK API es un tema eterno Sin HOOK, muchas tecnologías serán difíciles de implementar, o quizás imposibles de implementar.
La API mencionada aquí es una API en un sentido amplio, que incluye interrupciones en DOS, API en WINDOWS, servicios de interrupción, filtrado IFS y NDIS.
Filtrado NDIS, etc. Por ejemplo, el software de traducción instantánea con el que todos están familiarizados se implementa mediante las dos funciones HOOK TextOut () o ExtTextOut () antes de que el sistema operativo use estas dos funciones para generar el texto, el inglés correspondiente se reemplaza por chino. traducción instantánea; lo mismo ocurre con el filtrado IFS y NDIS. Antes de leer y escribir discos y enviar y recibir datos, el sistema llamará a la función de devolución de llamada proporcionada por un tercero para determinar si la operación es diferente de la normal. HOOK. Está permitido por el sistema operativo y el sistema operativo proporciona una interfaz para instalar la función de devolución de llamada.
Incluso si no hay HOOK, no habrá virus, porque ya sea un virus en DOS o un virus en WINDOWS,
todos dependen del servicio del sistema HOOK para realizar sus funciones: los virus de DOS en Windows dependen de HOOK INT 21 para infectar archivos (virus de tipo archivo) y HOOK INT 13 para infectar sectores de arranque (los virus de tipo de arranque en WINDOWS dependen de la API del sistema HOOK (incluida la capa RING0); y capa RING3), o instalar IFS (el método utilizado por los virus CIH) para infectar archivos. Por lo tanto, se puede decir que "sin HOOK, hoy no existiría el colorido mundo del software".
Debido a patentes y derechos de propiedad intelectual, o secretos comerciales, Microsoft no ha recomendado HOOK para la API de su sistema.
Proporcionar otras interfaces de filtrado como IFS y NDIS también se adapta a Anti. -Se requiere software antivirus y firewall antes de abrir. Entonces, la mayoría de las veces, HOOK API tiene que confiar en su propia fuerza.
HOOK API tiene un principio, y este principio es: las funciones originales de HOOK API no pueden verse afectadas de ninguna manera. Al igual que un médico que salva a la gente, si el virus en el cuerpo del paciente muere y el paciente muere, entonces "salvar a la gente" no tiene sentido.
Si después de ENGANCHAR la API, se logra su propósito, pero la función original de la API falla, no es un ENGANCHE sino un REEMPLAZO Las funciones normales del sistema operativo se verán afectadas o incluso fallarán. .
La tecnología de HOOK API no es complicada de decir, es una tecnología que cambia el flujo del programa. Entre las instrucciones de la CPU, hay varias instrucciones que pueden cambiar el flujo del programa: JMP, CALL, INT, RET, RETF, IRET y otras instrucciones.
En teoría, siempre que cambies cualquier código de máquina de la entrada y salida de la API, puedes engancharlo, pero la implementación real es mucho más complicada porque es necesario abordar los siguientes problemas:
1. Problema de longitud de las instrucciones de la CPU: en sistemas de 32 bits, la longitud de una instrucción JMP/CALL es de 5 bytes, por lo que solo puede reemplazar el código de máquina en la API que tenga más de 5 bytes de longitud (o reemplazar varias instrucciones La longitud total de las instrucciones es de 5 bytes); de lo contrario, afectará a varias instrucciones después del código de máquina modificado que tenga menos de 5 bytes, e incluso el flujo del programa se verá interrumpido, lo que provocará consecuencias impredecibles
2. Problema de parámetros Para acceder a los parámetros de la API original, debe hacer referencia a los parámetros a través de EBP o ESP, por lo que debe tener muy claro el valor de EBP/ESP en su código HOOK en este momento. ¿Cuánto cuesta?
3. Es una cuestión de tiempo. Algunos HOOK deben estar al principio de la API y otros deben estar al final de la API, como HOOK CreateFilaA().
Si realiza un ENGANCHE al final de la API API, no podrá escribir archivos ni siquiera acceder a ellos en este momento;
Si realiza un ENGANCHE en el encabezado de la API; y no has recibido datos en este momento, puedes verificar RECV() Por supuesto que no hay búfer de recepción en él
Debes esperar a que RECV() se ejecute normalmente, HOOK al final de RECV() y luego verifique el búfer de RECV(),
Solo se pueden encontrar los datos deseados dentro;
4. Problemas de contexto, algunos códigos HOOK no pueden realizar ciertas operaciones; de lo contrario, el contexto de la API original se destruirá y la API original dejará de ser válida;
5. Para problemas de sincronización, intente no utilizar variables globales en el código HOOK, pero utilice variables locales. programas modulares;
6. Lo último a tener en cuenta es que la función original de la instrucción de la CPU reemplazada debe simularse en algún lugar del código HOOK.
A continuación se utiliza send() en ws2_32.dll como ejemplo para ilustrar cómo ENGANCHAR esta función:
Fn() exportado: enviar - Ord:0013h
Dirección código ensamblador del código máquina
:71A21AF4 55 push ebp //Código máquina que será ENGANCHADO (primer método)
:71A21AF5 8BEC mov ebp, esp //Será ENGANCHADO Código máquina (método 2)
:71A21AF7 83EC10 sub esp, 00000010
:71A21AFA 56 push esi
:71A21AFB 57 push edi
: 71a21afc 33ff xor edi, edi
: 71a21afe 813d1c20a371931ca271 cmp dword ptr [71a3201c], 71a21c93 // el código de la máquina se enganchará (el cuarto método)
: 71a21b08 0f848484848484848484848484 SU 71A25893
:71A21B0E 8D45F8 lea eax, dword ptr [ebp-08]
:71A21B11 50 push eax
:71A21B12 E869F7FFFF llamada 71A21 280
:71A21B17 3BC7 cmp eax, edi
:71A21B19 8945FC mov dword ptr [ebp-04], eax
:71A21B1C 0F85C4940000 jne 71A2AFE6
: 71A21B22 FF7508 push [ebp+08]
:71A21B25 E826F7FFFF call 71A21250
:71A21B2A 8BF0 mov esi, eax
:71A21B2C 3BF7 cmp esi, edi p>
:71A21B2E 0F84AB940000 je 71A2AFDF
:71A21B34 8B4510 mov eax, dword ptr [ebp+10]
:71A21B37 53 push ebx
: 71A21B38 8D4DFC lea ecx, dword ptr [ebp-04]
:71A21B3B 51 push ecx
:71A21B3C FF75F8 push [ebp-08]
:71A21B3F 8D4D08 lea ecx, dword ptr [ebp+08]
:71A21B42 57 push edi
:71A21
B43 57 push edi
:71A21B44 FF7514 push [ebp+14]
:71A21B47 8945F0 mov dword ptr [ebp-10], eax
:71A21B4A 8B450C mov eax, dword ptr [ebp+0C]
:71A21B4D 51 push ecx
:71A21B4E 6A01 push 00000001
:71A21B50 8D4DF0 lea ecx, dword ptr [ ebp-10]
:71A21B53 51 push ecx
:71A21B54 FF7508 push [ebp+08]
:71A21B57 8945F4 mov dword ptr [ebp-0C] , eax
:71A21B5A 8B460C mov eax, dword ptr [esi+0C]
:71A21B5D FF5064 llamada [eax+64]
:71A21B60 8BCE mov ecx , esi
:71A21B62 8BD8 mov ebx, eax
:71A21B64 E8C7F6FFFF call 71A21230 //El código de máquina que será enganchado (el tercer método)
: 71A21B69 3BDF cmp ebx, edi
:71A21B6B 5B pop ebx
:71A21B6C 0F855F940000 jne 71A2AFD1
:71A21B72 8B4508 mov eax, dword ptr [ebp+08]
:71A21B75 5F pop edi
:71A21B76 5E pop esi
:71A21B77 C9 dejar
:71A21B78 C21000 ret 0010
Los siguientes son 4 métodos para conectar esta API:
1. Reemplace la primera instrucción de la entrada de la API, que es la instrucción PUSH EBP (código de máquina 0x55) con INT 3 (código de máquina 0xcc).
Luego use la función de depuración proporcionada por WINDOWS para ejecutar su propio código. Este método es ampliamente utilizado por DEBUGER como SOFT ICE.
Utiliza BPX para establecer un INT 3. el lugar correspondiente para establecer un punto de interrupción. Sin embargo, este método no se recomienda porque
entrará en conflicto con WINDOWS o las herramientas de depuración, y básicamente es necesario depurar el código ensamblador;
2. Cambie el segundo mov ebp, reemplace el instrucción esp (código de máquina 8BEC, 2 bytes) con la instrucción INT F0 (código de máquina CDF0),
Luego configure una puerta de interrupción en el IDT para que apunte a nuestro código.
Aquí doy un código HOOK:
lea ebp,[esp+12] //Simula la función del comando original mov ebp,esp
pushfd //Guarda la escena p>
pushad //Guardar la escena
//Haz lo que quieras hacer aquí
popad //Restaurar la escena
popfd // Restaurar la escena
iretd //Regresar a la siguiente instrucción de la instrucción original para continuar ejecutando la función original (en la dirección 71A21AF7)
Este método es muy bueno, pero la desventaja es que se debe configurar una puerta de interrupción en el IDT, que también ingresa RING0.
3. Cambie la dirección relativa de la instrucción CALL (las CALL están en 71A21B12, 71A21B25 y 71A21B64 respectivamente, pero hay una condición antes de las dos primeras CALL.
Las instrucciones de salto Es posible que no se ejecute, por lo que debemos CONECTAR la instrucción CALL en 71A21B64). ¿Por qué deberíamos comenzar con la instrucción CALL?
Debido a que todas son instrucciones de 5 bytes y todas son instrucciones CALL, siempre que el código de operación 0xE8 permanezca sin cambios y se cambie la dirección relativa posterior, se puede transferir a nuestro HOOK.
El código se ejecuta y luego va a la dirección de destino para su ejecución después de nuestro código HOOK.
Supongamos que nuestro código HOOK está en 71A20400, luego cambiamos la instrucción CALL en 71A21B64 a CALL 71A20400 (la instrucción original es así: CALL 71A21230)
Y el HOOK en 71A20400 El código es así:
71A20400:
pushad
//Haz lo que quieras hacer aquí
popad
jmp 71A21230 // Salte a la dirección de destino de la instrucción CALL original La instrucción original es así: llame a 71A21230
Este método está muy oculto, pero es difícil encontrarlo 5-. byte Para la instrucción CALL, calcular la dirección relativa también es complicado.
4. Reemplace el cmp dword ptr [71A3201C] en la dirección 71A21AFE con la instrucción 71A21C93 (código de máquina: 813D1C20A371931CA271, 10 bytes) para convertirse en
llamada 71A20400
<. p> nopnop
nop
nop
nop
(código máquina: E8 XX XX XX XX 90 90 90 90 90, 10 bytes)
El código HOOK en 71A20400 es:
pushad
mov edx,71A3201Ch //Simula la instrucción original cmp dword ptr [71A3201C], 71A21C93
cmp dword ptr [edx],71A21C93h //Simula el comando original cmp dword ptr [71A3201C], 71A21C93
pushfd
// Haz lo que quieras aquí
popfd
popad
ret
Este método es el más oculto, pero no todos. Cada La API tiene dichas instrucciones y es necesario utilizarlas en situaciones específicas.
Los métodos anteriores se usan comúnmente. Vale la pena mencionar que muchas personas cambian los primeros 5 bytes de la API, pero ahora muchos software antivirus usan este método.
Compruebe si el La API ha sido enganchada, u otros virus y troyanos han cambiado los primeros 5 bytes después de usted, por lo que se sobrescribirán entre sí y la operación de la última API HOOK es válida.