elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Parcheo de EAT y de IAT automático
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Parcheo de EAT y de IAT automático  (Leído 1,500 veces)
85

Desconectado Desconectado

Mensajes: 206



Ver Perfil WWW
Parcheo de EAT y de IAT automático
« en: 2 Marzo 2013, 09:59 am »

NIVEL: Beginner
TEST: win XP SP3

En este post a modo de tutorial se han utilizado dos rutinas, googleadas de las miles que hay, que hacen los parches respectivos (EAT e IAT), automáticamente,  encontrando la ubicación de la entrada correspondiente a una función, dentro de estas tablas. Para el ejemplo del parcheo de IAT se procede a usar la IAT local  del ejecutable, mientras que para el parcheo de EAT se hace en la EAT de la librería (DLL) kernel32.dll.

El objetivo de esta demostración es interceptar la función
GetProcAddress con ningún propósito más que demostrar como
se puede interceptar una función.

Se pueden valorar los casos que se pueden dar en los siguientes
dos ejemplos de programas:

En el primer programa contamos con un EXE el cual tiene dos opciones
que se le ofrecen al usuario:

1_ parchear la eat de kernel32.dll
2_ parchear la iat local


luego de elegir una de ambas opciones, se procede a cargar una DLL
en el proceso (ver el código de la DLL para ver que hace).

DEMO 1

EXE
Código
  1. //
  2. // By 85
  3. // PatchEAT, PatchIAT (Googleadas en 5 segundos XD)
  4. // elhacker.net
  5. // etalking.com.ar
  6. // 2013
  7. //
  8.  
  9. #include<windows.h>
  10. #include<stdio.h>
  11.  
  12. //
  13. FARPROC (WINAPI* pGetProcAddress) ( HMODULE hModule, LPCSTR lpProcName );
  14.  
  15. typedef FARPROC (WINAPI* GetProcAddress_t) ( HMODULE hModule, LPCSTR lpProcName );
  16.  
  17. //
  18. FARPROC WINAPI newGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
  19. {
  20. FARPROC nResult;
  21. nResult=pGetProcAddress(hModule, lpProcName);
  22. if (HIWORD(lpProcName))
  23. {
  24. if (!lstrcmp(lpProcName, "GetProcAddress"))
  25. {
  26. return (FARPROC) &newGetProcAddress;
  27. }
  28. }
  29. return nResult;
  30. }
  31.  
  32. //
  33. bool PatchEAT(HMODULE hTargetMod,CHAR* FuncName,VOID* newAdd,VOID** OrigAdd)
  34. {
  35.  
  36. #define _sword sizeof(WORD) //AddressOfNameOrdinals
  37. #define _sdword sizeof(DWORD)
  38.    DWORD addEAT,beforeProtection;
  39.    IMAGE_DOS_HEADER* dos_header=(IMAGE_DOS_HEADER*)hTargetMod;
  40.    IMAGE_NT_HEADERS* nt_header=NULL;
  41.    if(dos_header->e_magic!=IMAGE_DOS_SIGNATURE)
  42. return false;
  43.  
  44. nt_header=((PIMAGE_NT_HEADERS)((DWORD)(dos_header)+(DWORD)(dos_header->e_lfanew)));
  45. if(nt_header->Signature!=IMAGE_NT_SIGNATURE)
  46. return false;
  47.  
  48.    addEAT=nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  49.    IMAGE_EXPORT_DIRECTORY* pEAT=(IMAGE_EXPORT_DIRECTORY*)((DWORD)addEAT+(DWORD)hTargetMod);
  50.    for(DWORD i=0;i<pEAT->NumberOfFunctions;i++){
  51.        DWORD* pName=(DWORD*)((DWORD)hTargetMod+((DWORD)pEAT->AddressOfNames+(_sdword*i)));
  52. //printf("add nombre 0x%X\n",pName);
  53. //system("pause");
  54.        if(strcmp((char*)((DWORD)hTargetMod+*pName),FuncName) == 0){
  55.            WORD* AddNamePtrs=(WORD*)((DWORD)hTargetMod+((DWORD)pEAT->AddressOfNameOrdinals+(i*_sword)));
  56.            DWORD* AddFuncRVA=(DWORD*)((DWORD)hTargetMod+((DWORD)pEAT->AddressOfFunctions+(_sdword**AddNamePtrs)));
  57.  
  58.  
  59. //if(!strcmp((char*)((DWORD)hTargetMod+*pName),"GetProcAddress")){
  60. //printf("AddNamePtrs 0x%X\n",AddNamePtrs);
  61. // printf("Add de la func rva 0x%X\n",AddFuncRVA);
  62. // printf("Add func 0x%X\n",*AddFuncRVA+DWORD(hTargetMod));
  63. // system("pause");
  64. //}
  65.  
  66. if(!VirtualProtect(AddFuncRVA,_sdword,PAGE_READWRITE,&beforeProtection))
  67. return false;
  68.  
  69. *OrigAdd=(void*)(*AddFuncRVA+DWORD(hTargetMod));
  70.            *AddFuncRVA=(((DWORD)newAdd)-DWORD(hTargetMod));//copia el nuevo rva
  71.            if(!VirtualProtect(AddFuncRVA,_sdword,beforeProtection,&beforeProtection))
  72. return false;
  73.  
  74. break;
  75.        }
  76.    }
  77.    return true;
  78. }
  79.  
  80. //
  81. BOOL PatchIAT(HMODULE ModHandle, DWORD OriginalFunc, DWORD HookFunc, void **pOriginalFunc)
  82. {
  83. DWORD pe_offset,CurAddr,CurPointer,IATanfang,IATende,base;
  84. BOOL Hooked=FALSE;
  85. IMAGE_NT_HEADERS *pehdr;
  86.  
  87. if(!ModHandle || !OriginalFunc || !HookFunc)
  88. return FALSE;
  89.  
  90. base=(DWORD)ModHandle;
  91.  
  92. memcpy(&pe_offset,(void *)(base+0x3C),sizeof(DWORD));
  93. pehdr=(IMAGE_NT_HEADERS *)((DWORD)base + pe_offset);
  94.  
  95. IATanfang=(DWORD)base+pehdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
  96. IATende=IATanfang+pehdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
  97.  
  98. CurAddr=IATanfang;
  99.  
  100. while(CurAddr<IATende)
  101. {
  102. memcpy(&CurPointer,(void *)CurAddr,sizeof(DWORD));
  103.  
  104. if(CurPointer==OriginalFunc)
  105. {
  106. if(pOriginalFunc)
  107. *pOriginalFunc=(PVOID)CurPointer;
  108. DWORD old_attributes,old_attributes2;
  109. if(!VirtualProtect((void *)CurAddr,sizeof(DWORD), PAGE_EXECUTE_READWRITE, &old_attributes))
  110. return FALSE;
  111. memcpy((void *)CurAddr,&HookFunc,sizeof(DWORD));
  112. if(!VirtualProtect((void *)CurAddr,sizeof(DWORD), old_attributes, &old_attributes2))
  113. return FALSE;
  114. Hooked=TRUE;
  115. }
  116.  
  117. CurAddr+=sizeof(DWORD);
  118. }
  119. return Hooked;
  120. }
  121.  
  122. //
  123. int main(){
  124.  
  125. /*DWORD test0a = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
  126. DWORD test0b = (DWORD)GetProcAddress(GetModuleHandle(NULL),"GetProcAddress");
  127. //printf("GPA original: 0x%X\n",pGetProcAddress);
  128. printf("GPA hook: 0x%X\n",newGetProcAddress);
  129. printf("GPA es ahora (k32): 0x%X\n",test0a);
  130. printf("GPA es ahora (EXE): 0x%X\n",test0b);
  131. system("pause");*/
  132. ////////////////////////////////
  133.  
  134. HINSTANCE lib;
  135. int Res=0;
  136. int hookmode=0;
  137. while( hookmode<1||hookmode>3){
  138.  
  139. system("cls");
  140. printf("Bienvenido!\n");
  141. printf("Ingrese 1 para realizar un EAT HOOK\n");
  142. printf("Ingrese 2 para realizar un IAT HOOK\n");
  143. scanf("%d",&hookmode);
  144. }
  145.  
  146. if(hookmode == 1) __asm jmp eathook;
  147. else if(hookmode == 2) __asm jmp iathook;
  148. else if(hookmode == 3) __asm jmp salida;
  149.  
  150. /////////////////////////////////////////////////
  151. // EAT HOOK
  152.  
  153. eathook:
  154. Res = PatchEAT(GetModuleHandle("kernel32.dll"),"GetProcAddress",
  155. ((VOID*)(&newGetProcAddress)),((VOID**)(&pGetProcAddress)));
  156.  
  157. if(!Res){
  158.  
  159. printf("No se ha modificado la EAT objetivo!\n");
  160. ExitProcess(0);
  161. }
  162.  
  163. // Test 1
  164. DWORD test1a = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
  165. DWORD test1b = (DWORD)GetProcAddress(GetModuleHandle(NULL),"GetProcAddress");
  166. printf("GPA original: 0x%X\n",pGetProcAddress);
  167. printf("GPA hook: 0x%X\n",newGetProcAddress);
  168. printf("GPA es ahora (k32): 0x%X\n",test1a);
  169. printf("GPA es ahora (EXE): 0x%X\n",test1b);
  170. system("pause");
  171.  
  172. lib = LoadLibrary("loaddll.dll");
  173. FreeLibrary(lib);
  174. return 0;
  175. //
  176.  
  177. ////////////////////////////////////////////////
  178. // IAT HOOK
  179.  
  180. iathook:
  181. Res = PatchIAT(GetModuleHandle(NULL),(DWORD)GetProcAddress,
  182. (DWORD)newGetProcAddress,(void **)&pGetProcAddress);
  183.  
  184. if(!Res){
  185.  
  186. printf("No se ha modificado la IAT objetivo!\n");
  187. ExitProcess(0);
  188. }
  189.  
  190. // Test 2
  191. DWORD test2a = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
  192. DWORD test2b = (DWORD)GetProcAddress(GetModuleHandle(NULL),"GetProcAddress");
  193. printf("GPA original: 0x%X\n",pGetProcAddress);
  194. printf("GPA hook: 0x%X\n",newGetProcAddress);
  195. printf("GPA es ahora (k32): 0x%X\n",test2a);
  196. printf("GPA es ahora (EXE): 0x%X\n",test2b);
  197. system("pause");
  198.  
  199. lib = LoadLibrary("loaddll.dll");
  200. FreeLibrary(lib);
  201. return 0;
  202. //
  203.  
  204. /////////////////////////////////////////////////
  205. //
  206. salida:
  207. return 0;
  208. }
  209.  
  210. //
  211.  

DLL
Código
  1.  
  2. //
  3. // By 85
  4. // PatchEAT, PatchIAT (googleadas en 5 segundos XD)
  5. // elhacker.net
  6. // etalking.com.ar
  7. // 2013
  8. //
  9.  
  10. #include<windows.h>
  11. #include<stdio.h>
  12.  
  13. //////////////////////////
  14.  
  15. BOOL APIENTRY DllMain(
  16. HANDLE hModule, // Handle to DLL module
  17. DWORD ul_reason_for_call,
  18. LPVOID lpReserved ) // Reserved
  19. {
  20. switch ( ul_reason_for_call )
  21. {
  22. case DLL_PROCESS_ATTACH:
  23. // A process is loading the DLL.
  24.  
  25. {
  26.  
  27. DWORD res1 = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
  28. DWORD res2 = (DWORD)GetProcAddress(GetModuleHandle(NULL),"GetProcAddress");
  29. printf("GPA desde la dll mod=k32 0x%X\n", res1);
  30. printf("GPA desde la dll mod=EXE 0x%X\n", res2);
  31. system("pause");
  32. }
  33.  
  34.  
  35. break;
  36. case DLL_THREAD_ATTACH:
  37. // A process is creating a new thread.
  38. break;
  39. case DLL_THREAD_DETACH:
  40. // A thread exits normally.
  41. break;
  42. case DLL_PROCESS_DETACH:
  43. // A process unloads the DLL.
  44. break;
  45. }
  46. return TRUE;
  47. }
  48.  
  49. ////////////////
  50.  

En el segundo programa, contamos con un EXE el cual es un programa
simple. Sólo carga una DLL (Ver código de la DLL).

El código de la DLL se trata de realizar una de dos opciones.

1_ parchear la EAT kernel32.dll
2_ parchear la IAT del ejecutable

En realidad, se propone sólamente modificar la IAT del ejecutable,
el código del otro parche está deshabilitado.

En realidad el segundo programa no tiene mucho sentido tal cual está
expuesto, pero cobra sentido si nosotros quisiéramos aplicar este
método para algo relacionado al hacking.

Si queremos cambiar algo dentro de un proceso (por ejemplo un juego),
entonces una posible idea sería cargar una DLL en dicho proceso y
realizar un parche a la IAT del EXE. Siempre que sepamos que el EXE
hace uso de GetProcAddress para resolver alguna dirección interesante
para nosotros XD.

Un escenario en el cual se puede encontrar utilidad para esto pueder
ser, por ejemplo un programa (EXE) que utilice GetProcAddress para
resolver la dirección de ciertas funciones en una DLL que está cargada
en el proceso.

Al estár interceptada GetProcAddress, nosotros podemos arreglar que
retorne las direcciones de nuestros hooks en lugar de las direcciones
originales.

DEMO 2

EXE
Código
  1.  
  2. //
  3. // By 85
  4. // elhacker.net
  5. // etalking.com.ar
  6. // 2013
  7. //
  8.  
  9. #include<windows.h>
  10. #include<stdio.h>
  11.  
  12. //
  13. int main(){
  14.  
  15.  
  16. HINSTANCE lib = LoadLibrary("loaddll2.dll");
  17. FreeLibrary(lib);
  18.  
  19. printf("GPA original desde el EXE: 0x%X\n", GetProcAddress);
  20. system("pause");
  21. return 0;
  22. }
  23.  
  24. //
  25.  
  26.  

DLL
Código
  1.  
  2. //
  3. // By 85
  4. // PatchEAT, PatchIAT (googleadas en 5 segundos XD)
  5. // elhacker.net
  6. // etalking.com.ar
  7. // 2013
  8. //
  9.  
  10. #include<windows.h>
  11. #include<stdio.h>
  12.  
  13. /////////////////////
  14.  
  15. FARPROC (WINAPI* pGetProcAddress) ( HMODULE hModule, LPCSTR lpProcName );
  16.  
  17. typedef FARPROC (WINAPI* GetProcAddress_t) ( HMODULE hModule, LPCSTR lpProcName );
  18.  
  19. //
  20. FARPROC WINAPI newGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
  21. {
  22. FARPROC nResult;
  23. // nResult=pGetProcAddress(hModule, lpProcName);
  24. nResult=GetProcAddress(hModule, lpProcName);
  25. if (HIWORD(lpProcName))
  26. {
  27. if (!lstrcmp(lpProcName, "GetProcAddress"))
  28. {
  29. return (FARPROC) &newGetProcAddress;
  30. }
  31. }
  32. return nResult;
  33. }
  34.  
  35. //
  36. bool PatchEAT(HMODULE hTargetMod,CHAR* FuncName,VOID* newAdd,VOID** OrigAdd)
  37. {
  38.        // misma que el anterior programa
  39. ...
  40. }
  41.  
  42. //
  43. BOOL PatchIAT(HMODULE ModHandle, DWORD OriginalFunc, DWORD HookFunc, void **pOriginalFunc)
  44. {
  45. // misma que el anterior programa
  46. ...
  47. }
  48.  
  49. //
  50. //////////////////////////
  51.  
  52. BOOL APIENTRY DllMain(
  53. HANDLE hModule, // Handle to DLL module
  54. DWORD ul_reason_for_call,
  55. LPVOID lpReserved ) // Reserved
  56. {
  57. switch ( ul_reason_for_call )
  58. {
  59. case DLL_PROCESS_ATTACH:
  60. // A process is loading the DLL.
  61.  
  62. {
  63. int Res=0;
  64. //
  65.  
  66. //////////////////////////
  67. // EAT HOOK
  68.  
  69. /* Res = PatchEAT(GetModuleHandle("kernel32.dll"),"GetProcAddress",
  70. ((VOID*)(&newGetProcAddress)),((VOID**)(&pGetProcAddress)));
  71.  
  72. if(!Res){
  73.  
  74. printf("No se ha modificado la EAT objetivo!\n");
  75. ExitProcess(0);
  76. }
  77.  
  78. // Test 1
  79. DWORD test1a = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
  80. DWORD test1b = (DWORD)GetProcAddress(GetModuleHandle(NULL),"GetProcAddress");
  81. //DWORD test1b = (DWORD)GetProcAddress(GetModuleHandle("loaddll2.dll"),"GetProcAddress");//NO
  82. printf("DLL: GPA original: 0x%X\n",pGetProcAddress);
  83. printf("DLL: GPA original: 0x%X\n",GetProcAddress);
  84. printf("DLL: GPA hook: 0x%X\n",newGetProcAddress);
  85. printf("DLL: GPA es ahora (k32): 0x%X\n",test1a);
  86. printf("DLL: GPA es ahora (EXE): 0x%X\n",test1b);
  87. system("pause");*/
  88.  
  89. /////////////////////////
  90. // IAT HOOK
  91.  
  92.  
  93. Res = PatchIAT(GetModuleHandle(NULL),(DWORD)GetProcAddress,
  94. (DWORD)newGetProcAddress,(void **)&pGetProcAddress);
  95.  
  96. if(!Res){
  97.  
  98. printf("No se ha modificado la IAT objetivo!\n");
  99. ExitProcess(0);
  100. }
  101.  
  102. // Test 2
  103. DWORD test2a = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
  104. DWORD test2b = (DWORD)GetProcAddress(GetModuleHandle(NULL),"GetProcAddress");
  105. //DWORD test2b = (DWORD)GetProcAddress(GetModuleHandle("loaddll2.dll"),"GetProcAddress");//NO
  106. printf("DLL: GPA original: 0x%X\n",pGetProcAddress);
  107. printf("DLL: GPA original: 0x%X\n",GetProcAddress);
  108. printf("DLL: GPA hook: 0x%X\n",newGetProcAddress);
  109. printf("DLL: GPA es ahora (k32): 0x%X\n",test2a);
  110. printf("DLL: GPA es ahora (EXE): 0x%X\n",test2b);
  111. system("pause");
  112.  
  113. }
  114.  
  115.  
  116. break;
  117. case DLL_THREAD_ATTACH:
  118. // A process is creating a new thread.
  119. break;
  120. case DLL_THREAD_DETACH:
  121. // A thread exits normally.
  122. break;
  123. case DLL_PROCESS_DETACH:
  124. // A process unloads the DLL.
  125. break;
  126. }
  127. return TRUE;
  128. }
  129.  
  130. ////////////////
  131.  

Dejo ambos proyectos en MSVC++ 6.0
http://www.mediafire.com/?ha8768ul77a300z
http://www.mediafire.com/?cdeog97h39c770i

Más información
http://msdn.microsoft.com/en-us/magazine/cc301805.aspx
http://www.reverse-engineering.info/SystemHooking/export.htm
http://www.masmforum.com/board/index.php?PHPSESSID=8d46cd4ecb1688be429ab49694ec53e6&topic=4286.0


hasta luego


« Última modificación: 2 Marzo 2013, 20:52 pm por 85 » En línea

Me cerraron el Windows Live Spaces, entonces me creé un WordPress XD
http://etkboyscout.wordpress.com/
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Como parcheo La PS2 para jugar en la red
Juegos y Consolas
V.P.M 0 1,492 Último mensaje 7 Junio 2004, 19:27 pm
por V.P.M
Parcheo de un programa de cartas
Ingeniería Inversa
aguml 1 1,809 Último mensaje 17 Abril 2007, 16:37 pm
por aguml
[Artículo] Parcheo de memoria en Drivers Externos « 1 2 »
Análisis y Diseño de Malware
Hendrix 11 8,968 Último mensaje 28 Julio 2010, 20:35 pm
por [L]ord [R]NA
Parcheo y obtencion serial del Crackme Renascense de Skapunky
Ingeniería Inversa
Jony Menter0 2 2,210 Último mensaje 12 Septiembre 2010, 01:34 am
por yako-_-
[ayuda] instalación y parcheo completo de rt37 bajo linux?
Wireless en Linux
P4nd3m0n1um 1 2,243 Último mensaje 30 Abril 2011, 02:33 am
por pianista
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines