Foro de elhacker.net

Seguridad Informática => Análisis y Diseño de Malware => Mensaje iniciado por: APOKLIPTICO en 13 Noviembre 2012, 15:17 pm



Título: Hooking ntQuerySystemInformation.
Publicado por: APOKLIPTICO en 13 Noviembre 2012, 15:17 pm
Hola! Estoy desarrollando un programa para hacer api hooking sin necesidad de dll injection, es decir, con code injection. Por ahora funciona bien en la api EnumProcesses y OpenProcess, mi técnica se basa en antes de poner el hook a mi función inyectada, copio la llamada original a una parte (previamente desprotegida para la ejecución con virtualprotect()) asignada de la memoria y después cuando llaman a mi función, directamente redirijo los parámetros y llamo a la función original. Después de esto, manipulo la salida y devuelvo la información según sea conveniente.

El problema es que cuando trato de hacerlo con ntQuerySystemInformation, que es la función que utiliza el task manager para ver los procesos, me da un error de access violation cuando trata de acceder a "00000000". El hook funciona perfecto y todo se ejecuta según corresponde. Acá les dejo dónde es el fallo:

Código
  1. 00A30079  ^75 C2            JNZ SHORT 00A3003D
  2. 00A3007B   8D4424 1C        LEA EAX,DWORD PTR SS:[ESP+1C]
  3. 00A3007F   8B5424 20        MOV EDX,DWORD PTR SS:[ESP+20]
  4. 00A30083   8B4C24 2C        MOV ECX,DWORD PTR SS:[ESP+2C]
  5. 00A30087   8D1411           LEA EDX,DWORD PTR DS:[ECX+EDX]
  6. 00A3008A   42               INC EDX
  7. 00A3008B   8910             MOV DWORD PTR DS:[EAX],EDX
  8. 00A3008D   8B4424 1C        MOV EAX,DWORD PTR SS:[ESP+1C]
  9. 00A30091   85C0             TEST EAX,EAX
  10. 00A30093   0F84 A3000000    JE 00A3013C
  11. 00A30099   8B5424 1C        MOV EDX,DWORD PTR SS:[ESP+1C]
  12. 00A3009D   8B4424 58        MOV EAX,DWORD PTR SS:[ESP+58]
  13. 00A300A1   894424 08        MOV DWORD PTR SS:[ESP+8],EAX
  14. 00A300A5   8B4424 54        MOV EAX,DWORD PTR SS:[ESP+54]
  15. 00A300A9   894424 04        MOV DWORD PTR SS:[ESP+4],EAX
  16. 00A300AD   8B4424 50        MOV EAX,DWORD PTR SS:[ESP+50]
  17. 00A300B1   890424           MOV DWORD PTR SS:[ESP],EAX
  18. 00A300B4   FFD2             CALL EDX                 -------->> Aca se llama a la call original guardada en la heap.
  19. 00A300B6   83EC 0C          SUB ESP,0C
  20. 00A300B9   884424 3B        MOV BYTE PTR SS:[ESP+3B],AL
  21. 00A300BD   C74424 30 000000>MOV DWORD PTR SS:[ESP+30],0
  22. 00A300C5   EB 52            JMP SHORT 00A30119
  23. -----------------------------------------------------------------------
  24. 00A30119   8B4424 58        MOV EAX,DWORD PTR SS:[ESP+58]
  25. 00A3011D   8B00             MOV EAX,DWORD PTR DS:[EAX]  --->> Aca trata de asignar el valor de EAX, pero este tiene el valor "00000000"
  26. 00A3011F   C1E8 02          SHR EAX,2
  27. 00A30122   3B4424 30        CMP EAX,DWORD PTR SS:[ESP+30]
  28. 009E0122   3B4424 30        CMP EAX,DWORD PTR SS:[ESP+30]
  29. 009E0126   0F97C0           SETA AL
  30. 009E0129   84C0             TEST AL,AL
  31. 009E012B  ^75 9A            JNZ SHORT 009E00C7
  32. 009E012D   8B4424 58        MOV EAX,DWORD PTR SS:[ESP+58]
  33. 009E0131   8B00             MOV EAX,DWORD PTR DS:[EAX]
  34. 009E0133   8D50 FC          LEA EDX,DWORD PTR DS:[EAX-4]
  35. 009E0136   8B4424 58        MOV EAX,DWORD PTR SS:[ESP+58]
  36. 009E013A   8910             MOV DWORD PTR DS:[EAX],EDX
  37. 009E013C   8A4424 3B        MOV AL,BYTE PTR SS:[ESP+3B]
  38. 009E0140   83C4 4C          ADD ESP,4C
  39. 009E0143   C2 0C00          RETN 0C

Esta es la llamada a la función que luego es reemplazada por JMP (Address función):

Código
  1. 7C90D92E > B8 AD000000      MOV EAX,0AD
  2. 7C90D933   BA 0003FE7F      MOV EDX,7FFE0300
  3. 7C90D938   FF12             CALL DWORD PTR DS:[EDX]
  4. 7C90D93A   C2 1000          RETN 10

Alguien puede darme una mano con esto??
Muchas gracias!
APOKLIPTICO.


Título: Re: Hooking ntQuerySystemInformation.
Publicado por: Karcrack en 13 Noviembre 2012, 18:25 pm
Sin poder debuggear es díficil. ¿Qué debería contener ESP+58?


Título: Re: Hooking ntQuerySystemInformation.
Publicado por: APOKLIPTICO en 14 Noviembre 2012, 01:01 am
Okay parece que el problema (haciendo un poco de debugging) es que ESP+58 (Probablemente un puntero a la dirección de memoria con el valor de salida) está apuntando a 0x0007F678 de la stack cuando en la instrucción en la memoria 0x00A3009D estaba apuntando a 0x0007F674 de la stack. Fijándome en el momento del error, 0x0007F674 parece contener un valor (7000), el cual era el mismo que antes de hacer el call. El tema es que en la siguiente instrucción (en la que ocurre el error), está buscando una dirección de memoria y 7000 no es una dirección, sino un valor... Eso genera otro access violation...

Por si ayuda, esta es la función reemplazante:

Código
  1. DWORD __stdcall myNtQuerySystemInformation(
  2. SYSTEM_INFORMATION_CLASS SystemInformationClass,
  3. PVOID SystemInformation,
  4. ULONG SystemInformationLength,
  5. PULONG ReturnLength)
  6. {
  7.    #define COMPARE_PID 0
  8.    DWORD dwParlen = 0;
  9.    DWORD (WINAPI *doNtQuerySystemInformation) (SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
  10.    DWORD dwGetProcAddress;
  11.    DWORD dwGetModuleHandle;
  12.    DWORD dwParameters;
  13.    dwGetProcAddress = 0xFBAFBACC; //Esta direccion es modificada por el hook conteniendo una llamada a GetProcAddress().
  14.    dwGetModuleHandle = 0xBBBCACDD; //Esta direccion es modificada por el hook conteniendo una llamada a GetModuleHandle().
  15.    dwParameters = 0xBABABABA; //Esta direccion es modificada por el hook conteniendo los parametros de la función.
  16.    unsigned int i = 0;
  17.    BYTE *pPars = (BYTE*) dwParameters;
  18.    for(i = 12; i < 300;i++) if(pPars[i] == 0x90 && pPars[i+1] == 0x90) //Aca avanza por los parametros hasta encontrar dos NOPs
  19.    {                                                                //que indican el comienzo de la llamada original.
  20.        dwParlen = i +1;
  21.        break;
  22.    }
  23.    *(FARPROC *)&doNtQuerySystemInformation = (FARPROC) (dwParameters + dwParlen + 1);
  24.    DWORD dwRetval;
  25.    dwRetval = doNtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); // Como se ve, le pasa los mismos parametros.
  26.    return dwRetval;
  27. }

Agregué el resto del código (En el primer post) hasta el RETN por si sirve.


Título: Re: Hooking ntQuerySystemInformation.
Publicado por: APOKLIPTICO en 16 Noviembre 2012, 04:14 am
Ufff, ya se lo que pasó. Como el genio que soy, le estaba pasando la función de reemplazo para otra función.
Perdón por haberles hecho dar vueltas la cabeza XD
Gracias!
Un abrazo
APOKLIPTICO.


Título: Re: Hooking ntQuerySystemInformation.
Publicado por: Distorsion en 16 Noviembre 2012, 21:47 pm
Perdón por la ignorancia, pero por que accedes a 00000? Es la base de la tabla de importaciones?


Título: Re: Hooking ntQuerySystemInformation.
Publicado por: APOKLIPTICO en 16 Noviembre 2012, 21:53 pm
No, el 0x00000000 (8 ceros porque es una dirección de 32 bits) es un error, no se puede acceder a esa dirección de memoria. Es por eso que crasheaba el programa.