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)


  Mostrar Temas
Páginas: 1 2 [3] 4
21  Programación / Programación C/C++ / glTest 1: Interceptar Opengl32 con GPA en: 7 Marzo 2013, 02:41 am

NIVEL: Beginner
Test: WinXP SP3

Esto es una demostración de como puede aplicarse un IAT hook para interceptar funciones en un proceso. En este caso , se trata de un ejecutable que utiliza funciones de Opengl32 para crear una ventana y representar una imagen.



Para hacer uso de las funciones Opengl32 desde un ejecutable .EXE como en este caso, se puede hacer mediante vinculación dinámica (con DLL) o vinculación estática (con LIB).

Antes dejo unos enlaces donde consultar información:
http://msdn.microsoft.com/es-ar/library/253b8k2c.aspx
http://msdn.microsoft.com/es-es/library/1ez7dh12(v=vs.80).aspx
http://msdn.microsoft.com/es-ar/library/9se914de.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681914(v=vs.85).aspx
http://msdn.microsoft.com/es-es/library/ms235636(v=vs.80).aspx
http://msdn.microsoft.com/es-es/library/9yd93633(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681938(v=vs.85).aspx
http://msdn.microsoft.com/es-es/library/ms235627(v=vs.90).aspx
http://msdn.microsoft.com/es-es/library/ms235627(v=vs.80).aspx
http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/bed8a074-afe0-46a8-bdc5-5e4244ca55a6
http://msdn.microsoft.com/en-us/library/ms235627(v=vs.80).aspx
http://msdn.microsoft.com/es-es/library/abx4dbyh.aspx
http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx

Para construir este ejecutable de ejemplo, usé un código de ejemplo que ofrece el sitio oficial de Opengl..
http://www.opengl.org/archives/resources/code/samples/glut_examples/advanced/textrim.c
http://www.opengl.org/resources/libraries/glut/
http://www.opengl.org/archives/resources/code/samples/simple/
http://www.opengl.org/archives/resources/code/samples/glut_examples/examples/examples.html
http://www.opengl.org/archives/resources/code/samples/glut_examples/contrib/contrib.html

El programa de ejemplo original usa la vinculación estática, pero para poder realizar esta demostración tuvo que ser modificado XD.

Las modificaciones se dan para las llamadas a 3 funciones de Opengl32 que fueron elegidas para poder realizar la demostración.

las funciones son: glBegin, glBlendFunc y glViewport
Para saber acerca de estas funciones van a tener que recurrir a un manual de Opengl32, o busquen en el sitio oficial.

A estas 3 funciones se las desea interceptar para lograr cambiar el comportamiento del programa, la idea es cambiar lo que el programa muestra por pantalla.

Lo que se hace en el ejecutable es arreglar las llamadas a estas 3 funciones, que normalmente son llamadas por vinculación estática. En cambio ahora fueron modificadas para que la vinculación sea dinámica. Por eso se declararon punteros a función y se resuelven las direcciones correspondientes a las funciones dentro de Opengl32.DLL , en tiempo de ejecución. Esto se hace usando GetProcAddress.

Ahora que sabemos que el ejecutable de la demostración, hace uso de GetProcAddress para conseguir las direcciones de estas 3 funciones mencionadas, vamos a interceptar GetProcAddress para que devuelva otras direcciones. Digamos, las direcciones de nuestras funciones de reemplazo.

Esas funciones de reemplazo, o HOOKs, van a estar dentro de una DLL aparte que va a ser cargada al proceso. Una vez cargada en el proceso va a parchear la IAT en la entrada de GetProcAddress, de esa forma GetProcAddress queda interceptada.

Veamos el código del EXE:
Los includes necesarios, y las librerías estáticas requeridas para que compile.
Código
  1. #pragma comment (lib, "opengl32.lib")
  2. #pragma comment (lib, "GLUT32/glut32.lib")
  3. #include <windows.h>
  4. #include <math.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <time.h>
  9.  
  10. #include "GLUT32/glut.h"
  11. #include <gl\gl.h>
  12. #include <gl\glu.h>
  13.  
  14. #include "texture.h"
  15.  

Los punteros a función para las 3 funciones que vamos a interceptar.
Código
  1. // Opengl32 es APIENTRY
  2. typedef void(__stdcall* t_glBegin)(GLenum);
  3. typedef void(__stdcall* t_glBlendFunc)(GLenum, GLenum);
  4. typedef void(__stdcall* t_glViewport)(GLint,GLint,GLsizei,GLsizei);
  5.  
  6. // Declaramos unos punteros que van a contener la dirección de las funciones OGL32 que usemos.
  7. t_glBegin pOrig_glBegin = NULL;
  8. t_glBlendFunc pOrig_glBlendFunc = NULL;
  9. t_glViewport pOrig_glViewport = NULL;
  10.  

Punto de entrada. Como podemos ver, la DLL se carga con un simple LoadLibrary. No hacemos inyección de DLL o cualquier otra forma de cargar una DLL. "glhack1.dll" es la DLL la cual se encarga del patch a la IAT y contiene los hooks de GPA y Opengl32.
Código
  1. int main(int argc, char **argv)
  2. {
  3.  SetConsoleTitle("glTest");
  4.  
  5.  int opc=0;
  6.  while( 1){
  7.  
  8. system("cls");
  9. printf("Bienvenido!\n");
  10. printf("1: Interceptar OPENGL32\n");
  11. printf("2: NO Interceptar OPENGL32\n");
  12. printf("3: Salir\n");
  13. scanf("%d",&opc);
  14.  
  15. if(opc == 1||opc == 2||opc == 3) break;
  16.  }
  17.  
  18.  if(opc==3) ExitProcess(45);
  19.  
  20.  if(opc==1) //Al cargar la DLL, esta instala el hook a GPA para poder interceptar OGL32
  21.  {
  22.  if(!LoadLibrary("glhack1.dll")){
  23.  
  24.  MessageBox(0,0,0,0);
  25.  ExitProcess(0);
  26.  }
  27.  }
  28.  
  29.  printf("\n");
  30.  printf("EXE: GPA 0x%X\n", GetProcAddress);
  31.  printf("EXE: glBegin 0x%X\n", glBegin);
  32.  if(GetModuleHandle("opengl32.dll"))
  33.  {
  34.  pOrig_glBegin = (t_glBegin)GetProcAddress(GetModuleHandle("opengl32.dll"), "glBegin");
  35.  pOrig_glBlendFunc = (t_glBlendFunc)GetProcAddress(GetModuleHandle("opengl32.dll"), "glBlendFunc");
  36.  pOrig_glViewport = (t_glViewport)GetProcAddress(GetModuleHandle("opengl32.dll"), "glViewport");
  37.  printf("EXE: glBegin 0x%X\n", pOrig_glBegin);
  38.  printf("EXE: glBlendFunc 0x%X\n", pOrig_glBlendFunc);
  39.  printf("EXE: glViewport 0x%X\n", pOrig_glViewport);
  40.  }
  41.  else
  42.  {
  43.  MessageBox(0,0,0,0);
  44.  ExitProcess(0);
  45.  return 0;
  46.  }
  47.  
  48.  glutInit(&argc, argv);
  49.  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  50.  glutInitWindowSize(450, 450);
  51.  glutCreateWindow("glTest");
  52.  // glutFullScreen();
  53.  init(argv[1]);
  54.  glutDisplayFunc(display);
  55.  glutKeyboardFunc(key);
  56.  glutReshapeFunc(reshape);
  57.  glutIdleFunc(tick);
  58.  glutMainLoop();
  59.  return 0;             /* ANSI C requires main to return int. */
  60. }
  61.  
  62. //
  63.  

Estas funciones son originales del código que conseguí en opengl.org
Los cambios que se ven son que las llamadas a función originales para las 3 funciones elegidas,
fueron cambiadas por los punteros a función que creamos.
Código
  1. void bfunc(void)
  2. {
  3.  static int state;
  4.  if (state ^= 1)
  5.  {
  6.    pOrig_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  7.    glEnable(GL_BLEND);
  8.  } else {
  9.    glDisable(GL_BLEND);
  10.  }
  11. }
  12.  

Código
  1. void bfunc(void)
  2. {
  3.  static int state;
  4.  if (state ^= 1)
  5.  {
  6.    pOrig_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  7.    glEnable(GL_BLEND);
  8.  } else {
  9.    glDisable(GL_BLEND);
  10.  }
  11. }
  12.  

Código
  1. void display(void)
  2. {
  3.  glClear(GL_COLOR_BUFFER_BIT);
  4.  glPushMatrix();
  5.  glTranslatef(transx, transy, 0.f);
  6.  glRotatef(rotx, 0., 1., 0.);
  7.  glRotatef(roty, 1., 0., 0.);
  8.  glScalef(scale, scale, 0.);
  9.  pOrig_glBegin(GL_POLYGON);
  10.  glTexCoord2f(0.0, 0.0);
  11.  glVertex2f(-1.0, -1.0);
  12.  glTexCoord2f(1.0, 0.0);
  13.  glVertex2f(1.0, -1.0);
  14.  glTexCoord2f(1.0, 1.0);
  15.  glVertex2f(1.0, 1.0);
  16.  glTexCoord2f(0.0, 1.0);
  17.  glVertex2f(-1.0, 1.0);
  18.  glEnd();
  19.  glPopMatrix();
  20.  glutSwapBuffers();
  21. }
  22.  


Código
  1. void reshape(int w, int h)
  2. {
  3.  pOrig_glViewport(-50, -50, w+120, h+120);
  4. }
  5.  

La DLL hace un patch a la IAT del EXE, el tema es que esta función la traje de un conocido creador de hacks que se llama h1web.
http://50hz.ws/devel/iathook.c.txt

El tema es que tuve que modificar la función para que funcione correctamente. Los cambios fueron en el 4to parámetro y dentro de la función. El problema era que estas estructuras que recorre, contienen cadenas sin terminación en 0, por lo que STRCMP no encontraba en nombre de GetProcAddress.
Código
  1. BOOL HookIAT(char* szModule, char* szFunc, DWORD dwOwn, DWORD& dwOrg)
  2. {
  3.    DWORD dwBase = (DWORD)GetModuleHandle(NULL);
  4.    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)dwBase;
  5.    PIMAGE_NT_HEADERS pNTHdr = (PIMAGE_NT_HEADERS)(dwBase + pDosHdr->e_lfanew);
  6.    DWORD ImportData = (DWORD)pNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  7.    PIMAGE_IMPORT_DESCRIPTOR pImportD = (PIMAGE_IMPORT_DESCRIPTOR)(dwBase + ImportData);
  8.    while(pImportD->Name != 0)
  9.    {
  10. // CUIDADO! En estas estructuras se encuentran strings no terminadas en 0
  11. // por lo que STRCMP no sirve.
  12. // Un cambio fácil puede ser usar STRSTR que encuentra una cadena dentro de otra.
  13. // if(!strcmp((char*)(dwBase + pImportD->Name), szModule))
  14.        if(!strstr((char*)(dwBase + pImportD->Name), szModule))
  15.            break;
  16.        pImportD++;
  17.    }
  18.  
  19. //printf("pImportD->Name: %s\n",(char*)(dwBase + pImportD->Name));
  20. //system("pause");
  21.    if(pImportD->Name == 0) return FALSE;
  22. //printf("pImportD->Name: 0x%X\n",pImportD->Name);
  23. //system("pause");
  24.  
  25.    PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)(dwBase + pImportD->FirstThunk);
  26.    DWORD OrgFunc = (DWORD)GetProcAddress(GetModuleHandle(szModule), szFunc);
  27.    while(pThunk->u1.Function != 0)
  28.    {
  29.        if(pThunk->u1.Function == (DWORD*)OrgFunc)
  30.        {
  31.            dwOrg = OrgFunc;
  32.            DWORD dwOldProt = 0;
  33.            VirtualProtect((void*)&pThunk->u1.Function, 4, PAGE_EXECUTE_READWRITE, &dwOldProt);
  34.            pThunk->u1.Function = (DWORD*)dwOwn;
  35.            VirtualProtect((void*)&pThunk->u1.Function, 4, dwOldProt, &dwOldProt);
  36.            if(pThunk->u1.Function == (DWORD*)dwOwn)
  37.                return TRUE;
  38.            else
  39.                return FALSE;
  40.        }
  41.        pThunk++;
  42.    }
  43.    return FALSE;
  44. }

DLL: main.cpp
Código
  1.  
  2. //
  3. // By 85
  4. // HookIAT (h1web, Thanks to Ashkbiz Danehkar)
  5. // elhacker.net
  6. // etalking.com.ar
  7. // 2013
  8. //
  9.  
  10. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  11.  
  12. #define WIN32_LEAN_AND_MEAN
  13. #include<windows.h>
  14. #include<stdio.h>
  15. #include<stdlib.h>
  16. #include"opengl.h"
  17.  
  18. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  19.  
  20. FARPROC (WINAPI* pGetProcAddress) ( HMODULE hModule, LPCSTR lpProcName );
  21.  
  22. //
  23. FARPROC WINAPI newGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
  24. {
  25. FARPROC nResult;
  26. nResult=GetProcAddress(hModule, lpProcName);
  27. if (HIWORD(lpProcName))
  28. {
  29. if (!lstrcmp(lpProcName, "GetProcAddress"))
  30. {
  31. return (FARPROC) &newGetProcAddress;
  32. }
  33. else
  34. {
  35. CheckForOpenGlHook(&nResult, lpProcName);
  36.        }
  37. }
  38. return nResult;
  39. }
  40.  
  41. //
  42. BOOL HookIAT(char* szModule, char* szFunc, DWORD dwOwn, DWORD& dwOrg)
  43. {
  44.     // Ya mostrado
  45. }
  46.  
  47. //
  48. bool WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
  49. {
  50. if (fdwReason==DLL_PROCESS_ATTACH)
  51. {
  52. //printf("GetProcAddress 0x%X\n", GetProcAddress);// No refenciar GPA antes!
  53. if(!HookIAT("kernel32.dll","GetProcAddress",(DWORD)newGetProcAddress,
  54. (DWORD&)pGetProcAddress)){
  55.  
  56. MessageBox(0,0,0,0);
  57. return (false);
  58. }
  59.  
  60. printf("\n");
  61. printf("DLL: newGetProcAddress 0x%X\n", newGetProcAddress);
  62. printf("DLL: GetProcAddress 0x%X\n", GetProcAddress);
  63. printf("DLL: pGetProcAddress 0x%X\n", pGetProcAddress);
  64.  
  65. }
  66. return (true);
  67. }
  68.  

Los Hooks o funciones de gancho, como quieran decirles, son estas siguientes. Vemos que dentro de las de Opengl32 se hicieron cambios para modificar el resultado del programa.
El Hook de GetProcAddress se encarga de cambiar la dirección de retorno por una de los Hooks de Opengl32, y de inicializar los punteros a función con las direcciones de las originales.

DLL: opengl32.cpp
Código
  1. //
  2. // By 85
  3. // elhacker.net
  4. // etalking.com.ar
  5. // 2013
  6. //
  7.  
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  9.  
  10. #pragma comment(lib, "opengl32.lib")
  11. #include<windows.h>
  12. #include<stdio.h>
  13. #include "opengl.h"
  14.  
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  16.  
  17. // Opengl32 es APIENTRY
  18. typedef void(__stdcall* t_glBegin)(GLenum);
  19. typedef void(__stdcall* t_glBlendFunc)(GLenum, GLenum);
  20. typedef void(__stdcall* t_glViewport)(GLint,GLint,GLsizei,GLsizei);
  21.  
  22. t_glBegin pOrig_glBegin = NULL;
  23. t_glBlendFunc pOrig_glBlendFunc = NULL;
  24. t_glViewport pOrig_glViewport = NULL;
  25.  
  26. bool once=false;
  27. bool oglSubtractive = false;
  28. bool NewDimension = true;
  29.  
  30. int posx = 200;
  31. int posy = 200;
  32. int neww = 50;
  33. int newh = 50;
  34.  
  35. //
  36. void __stdcall HOOK_glBegin(GLenum mode)
  37. {
  38. if(!once){
  39. once=true;
  40. }
  41.  
  42. if (mode==GL_POLYGON)
  43. {
  44.    glClearColor(1.0, 1.0, 1.0, 1.0);
  45.    glColor3f(0, 0, 0);
  46. }
  47.  
  48. (*pOrig_glBegin)(mode);
  49. }
  50.  
  51. void __stdcall HOOK_glBlendFunc(GLenum sfactor, GLenum dfactor)
  52. {
  53. if(oglSubtractive){
  54. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  55.  
  56. } else {
  57. glBlendFunc(sfactor,dfactor);
  58. }
  59. }
  60.  
  61. void __stdcall HOOK_glViewport( GLint x,GLint y,GLsizei width,GLsizei height )
  62. {
  63. if(NewDimension){
  64.  
  65. (*pOrig_glViewport)(posx,posy,neww,newh);
  66. }
  67. else
  68. {
  69. (*pOrig_glViewport)(x,y,width,height);
  70. }
  71. }
  72.  
  73. void CheckForOpenGlHook(FARPROC* pProc,LPCTSTR lpProcName)
  74. {
  75. if (!strcmp(lpProcName,"glBegin"))
  76. {
  77. pOrig_glBegin = (t_glBegin)*pProc;
  78. *pProc = (FARPROC)&HOOK_glBegin;
  79. }
  80. else if(!strcmp(lpProcName,"glBlendFunc"))
  81. {
  82. pOrig_glBlendFunc = (t_glBlendFunc)*pProc;
  83. *pProc = (FARPROC)&HOOK_glBlendFunc;
  84. }
  85. else if(!strcmp(lpProcName,"glViewport"))
  86. {
  87. pOrig_glViewport = (t_glViewport)*pProc;
  88. *pProc = (FARPROC)&HOOK_glViewport;
  89. }
  90. }
  91.  

Espero que les haya gustado. Es un tutorial básico por lo tanto sólamente usé un parche a la IAT. Se puede experimentar con otro tipo de Hook más avanzado.

El programa ofrece la opción de interceptar Opengl32 o no:


Archivos utilizados:


Resultados:


Si me preguntan por qué hacer que usen GetProcAddress cuando no era necesario, la respuesta es que algunos juegos lo han hecho así, y servía para demostrar la utilidad de interceptar GPA.
Interceptar Opengl32 se podía haber hecho parcheando la IAT en las entradas de Opengl32 también.

Proyecto vc6:
http://www.mediafire.com/?p673twh7in70ys1
22  Programación / Programación C/C++ / Tutorial: Crear un parche 1 (desde otro proceso) en: 6 Marzo 2013, 04:09 am
NIVEL: Beginner
La continuación de este tutorial:
http://foro.elhacker.net/programacion_cc/tutorial_crear_un_parche_1-t384060.0.html

En este caso contamos con 2 ejecutables .EXE ;
dummy.EXE va a ser el proceso víctima y parche1_externo.EXE
va a ser el proceso atacante, por decirlo así..


Cuando se abre el 2do ejecutable mencionado, el proceso atacante queda a la espera de encontrar al proceso víctima.








Dummy.EXE
Código
  1.  
  2. //
  3. // By 85
  4. // elhacker.net
  5. // etalking.com.ar
  6. // 2013
  7. //
  8.  
  9. ///////////////////
  10.  
  11. #include<windows.h>
  12. #include<stdio.h>
  13.  
  14. //////////////////////
  15. //////////////////////
  16.  
  17. DWORD dwPatchPlace = 0x00000000;
  18. BYTE Opcode_JZ = 0x74;
  19.  
  20. ///////////
  21. ////////////////////
  22.  
  23. void Target(){
  24.  
  25. while(1){
  26.  
  27.  
  28. #define MASTERNUM 85
  29. int master=0x99999997;
  30. char* ingreso = new char[256];
  31.  
  32. system("cls");
  33. printf("Ingrese la llave maestra\n");
  34. scanf("%s", ingreso);
  35.  
  36. if(!strcmpi(ingreso, new char[]= "key85\0")){
  37.  
  38. master = 85;
  39. }
  40.  
  41. delete []ingreso;
  42. if(master==MASTERNUM)
  43. {
  44. printf("FELICITACIONES! USTE HA INGRESADO\n");
  45. printf("\n");
  46. system("pause");
  47. break;
  48. }
  49.  
  50. // if(GetAsyncKeyState(VK_END)) break;// En otro hilo
  51. if(!strcmpi(ingreso, new char[]= "exit\0")) break;
  52. }
  53. }
  54.  
  55. //
  56. void Check()//Función que representa un método de seguridad
  57. {
  58. if(*(PBYTE)dwPatchPlace != Opcode_JZ)
  59. {
  60. printf("0x%X\n",*(PBYTE)dwPatchPlace);
  61. printf("Memoria alterada!, se sale del programa..\n");
  62. printf("\n");
  63. system("pause");
  64. ExitProcess(45);
  65. }
  66. }
  67.  
  68. /////////
  69.  
  70. int main(){
  71.  
  72. SetConsoleTitle("Dummy");
  73.  
  74. dwPatchPlace=(DWORD)GetModuleHandle(NULL);//Retorna la BaseAddress
  75.  
  76. //Sumamos el offset obtenido del desensamblado
  77. dwPatchPlace+=0x00001000;
  78. dwPatchPlace+=0x6C;
  79.  
  80. //Logs
  81.  
  82. printf("LOG DE SEGURIDAD PRIMARIO:\n");
  83. printf("0x%X\n",(DWORD)GetModuleHandle(NULL));
  84. printf("0x%X\n",dwPatchPlace);
  85. printf("0x%X\n",*(PBYTE)dwPatchPlace);
  86. printf("\n");
  87. system("pause");
  88.  
  89. //Llamamos a la función
  90. Target();
  91.  
  92. printf("LOG DE SEGURIDAD SECUNDARIO:\n");
  93. printf("0x%X\n",(DWORD)GetModuleHandle(NULL));
  94. printf("0x%X\n",dwPatchPlace);
  95. printf("0x%X\n",*(PBYTE)dwPatchPlace);
  96. printf("\n");
  97. system("pause");
  98.  
  99. //Se deja que las comprobaciones de seguridad sigan su curso
  100. Check();
  101.  
  102. return 0;
  103. }
  104.  

parche1_externo.EXE
Código
  1.  
  2. //
  3. // By 85
  4. // GetModuleBase (googleada en 5 segundos XD)
  5. // elhacker.net
  6. // etalking.com.ar
  7. // 2013
  8. //
  9.  
  10. ///////////////////
  11.  
  12. #include<windows.h>
  13. #include<stdio.h>
  14. #include<tlhelp32.h>
  15.  
  16. //////////////////////
  17.  
  18. HANDLE hProcess;  
  19. HANDLE hModule;
  20. DWORD dwPatchPlace = 0x00000000;
  21. BYTE Opcode_JZ = 0x74;
  22. BYTE Opcode_JNZ = 0x75;
  23. BYTE pReaden;
  24.  
  25. ///////////
  26.  
  27. VOID Patch() {
  28.  
  29. // printf("0x%X\n",pReaden);
  30. // system("pause");
  31.  
  32. if(!hProcess) return;
  33. if(pReaden!=Opcode_JZ) return;
  34.  
  35. DWORD dwOldProtect;
  36.    VirtualProtect( (LPVOID)dwPatchPlace,
  37.                    1,
  38.                    PAGE_EXECUTE_WRITECOPY,
  39.                    &dwOldProtect );
  40.  
  41.    WriteProcessMemory( hProcess,
  42.                        (LPVOID)dwPatchPlace,
  43.                        &Opcode_JNZ,
  44.                        1,
  45.                        NULL );
  46.  
  47.    VirtualProtect( (LPVOID)dwPatchPlace,
  48.                    1,
  49.                    dwOldProtect,
  50.                    &dwOldProtect );
  51. }
  52.  
  53. //
  54. ////////////////////
  55.  
  56. DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
  57. {
  58.   MODULEENTRY32 lpModuleEntry = {0};
  59.   HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
  60.  
  61.   if(!hSnapShot)
  62.      return NULL;
  63.   lpModuleEntry.dwSize = sizeof(lpModuleEntry);
  64.   BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
  65.   while(bModule)
  66.   {
  67.   //printf("%s\n",lpModuleEntry.szModule);
  68.      if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
  69.      {
  70.         CloseHandle( hSnapShot );
  71.         return (DWORD)lpModuleEntry.modBaseAddr;
  72.      }
  73.      bModule = Module32Next( hSnapShot, &lpModuleEntry );
  74.   }
  75.   CloseHandle( hSnapShot );
  76.   return NULL;
  77. }
  78.  
  79. int main(){
  80.  
  81. // We have to replace JZ with JNZ.
  82.  
  83. //TODO: Obtener privilegios
  84. //
  85.  
  86. char l_exe[] = {'d','u','m','m','y','.','e','x','e',0};
  87. char l_window[] = {'D','u','m','m','y',0};
  88. HWND hwnd;          
  89. hwnd = FindWindow(0, l_window);    
  90. if (!hwnd)    
  91. {        
  92. printf("Abre %s ahora.\n", l_exe);        
  93. while (1)      
  94. {            
  95. Sleep(1000);            
  96. hwnd = FindWindow(0, l_window);            
  97. if (hwnd) break;
  98. if (GetAsyncKeyState(VK_END)>0) ExitProcess(45);
  99. }            
  100. }
  101.  
  102. unsigned long pid;    
  103. GetWindowThreadProcessId( hwnd, &pid);    
  104. // hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION,0,pid);
  105. // hProcess=OpenProcess(PROCESS_VM_WRITE|PROCESS_VM_OPERATION,0,pid);
  106. hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,pid);
  107.  
  108. HANDLE baseAddress = (HANDLE)GetModuleBase(l_exe, pid);
  109. if(!baseAddress)
  110. {
  111. printf("No se obtubo la baseAddress!\n");
  112. system("pause");
  113. ExitProcess(45);
  114. }
  115.  
  116. //Lugar del parche
  117. dwPatchPlace=(DWORD)baseAddress;
  118. dwPatchPlace+=0x00001000;
  119. dwPatchPlace+=0x6C;
  120.  
  121. //Logs
  122. printf("hProcess: 0x%X\n",hProcess);
  123. printf("pid: %d\n",pid);
  124. printf("dwPatchPlace: 0x%X\n",dwPatchPlace);
  125. // printf("0x%X\n",*(PBYTE)dwPatchPlace);//No se puede hacer esto para otro proceso
  126. if(ReadProcessMemory(hProcess,(void*)(dwPatchPlace),&pReaden,sizeof(pReaden),0))
  127. {
  128. printf("Lugar antes de parchear: 0x%X\n",pReaden);
  129. }
  130. else
  131. printf("ReadProcessMemory failed: %d\n",GetLastError());
  132.  
  133. system("pause");
  134.  
  135. //Se procede a parchear el proceso objetivo
  136. Patch();
  137.  
  138. if(ReadProcessMemory(hProcess,(void*)(dwPatchPlace),&pReaden,sizeof(pReaden),0))
  139. {
  140. printf("Lugar luego de parchear: 0x%X\n",pReaden);
  141. }
  142. else
  143. printf("ReadProcessMemory failed: %d\n",GetLastError());
  144.  
  145.  
  146. CloseHandle(hProcess);
  147. system("pause");
  148. return 0;
  149. }
  150.  
  151. //
  152.  

La finalidad es la misma que la primer parte del tutorial, es decir parchear un OPCODE en la memoria del proceso víctima. Las novedades son que se hizo desde otro proceso por lo que SI se tuvo que usar ReadProcessMemory y WriteProcessMemory (Sin mencionar las otras API's).

Para detectar si la ventana del proceso víctima se encuentra abierta se ha usado FindWindow.

Para obtener un manejador (handle) del proceso víctima usamos OpenProcess.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx

Algo también que van a querer saber:
Citar
To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege. For more information, see Changing Privileges in a Token.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms717797(v=vs.85).aspx

y conocer los posibles derechos de acceso a un proceso:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx

Al terminar las operaciones se debe cerrar el handle del proceso.

Sobre la forma de buscar los procesos activos, se usó la función googleada 'GetModuleBase' que utiliza TOOLHELP32, para obtener la dirección base:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686832(v=vs.85).aspx

Recuerden que son dos procesos separados con sus espacios de direcciones respectivos, por lo cual se requiere ReadProcessMemory para leer la memoria de otro proceso, y para modificarla, WriteProcessMemory.

O sea que algo como esto:
Código:
printf("0x%X\n",*(PBYTE)dwPatchPlace);//No se puede hacer esto para otro proceso

No sirve porque la dirección guardada en dwPatchPlace es del proceso víctima, no del proceso atacante.
Por eso se pasa como parámetro a ReadProcessMemory.

Si quieren saber como obtener su propia 'dwPatchPlace' de un programa cualquiera, van a tener que desensamblarlo (mejor si no está protegido) o en otro caso depurarlo en funcionamiento con un depurador como el OllyDBG.
Es decir, el tutorial da por sabido que cada uno ya sabe lo que quiere parchear y adonde debe parchear. El tutorial apunta a cómo se parchea.

Disculpen si faltan cosas en este humilde tutorial, pero es para beginners por lo tanto si faltan cosas pueden aportarlas  ;D.

Proyecto vc6: http://www.mediafire.com/?8a65cuufh2dd4um
23  Programación / Programación C/C++ / Flotantes aleatorios en: 6 Marzo 2013, 03:18 am
Hola,
hacía un tiempo había creado una optimización para un código que permitía obtener números flotantes aleatorios, que se usaban en una funcionalidad de un hack para Counter-Strike.
En realidad se necesitan 4 valores aleatorios para usarse en el hack y lo que hice fue optimizar el código original, que daba muchas vueltas antes de hacer la operación real. Supongo que para confundir a los hackers XD

pero fuera de lo que tiene que ver con el Counter-Strike, esto sirve para generar números aleatorios (de punto flotante), por eso el título..

Tengan en cuenta que se puede modificar la función que genera los números aleatorios, para que devuelva un sólo número en lugar de un vector de 4. También pueden hacer las modificaciones que quieran, pero tengan en cuenta que así como está es como sirve para el hack.
Para más información:
http://www.gamedeception.net/threads/26109-85-Customized-Spread-Class

Este es un programa demostrativo que hice para ver los resultados:
Código:

//
// By 85
// Credits: HL1 SDK, Paul Upton, Snipity (Tad)
// elhacker.net
// etalking.com.ar
// David Riedel
// 2013

#pragma warning(disable: 4390)
#include<windows.h>
#include<iostream>
#include<stdio.h>
#include<time.h>

//

class Random{

public:
Random()
{
Init();
}
private:
void Init();
float RandomFloat[4];
unsigned int glSeed;
unsigned int seed_table[ 256 ];
public:
void SetRandomFloatVector(unsigned int seed, int future);
float* getRandomFloatVector() { return RandomFloat; }
};

//

Random random;

//
void Random::Init(){
glSeed = 0;
int i=0;
seed_table[i] = 28985; i++;
seed_table[i] = 27138; i++;
seed_table[i] = 26457; i++;
seed_table[i] = 9451; i++;
seed_table[i] = 17764; i++;
seed_table[i] = 10909; i++;
seed_table[i] = 28790; i++;
seed_table[i] = 8716; i++;
seed_table[i] = 6361; i++;
seed_table[i] = 4853; i++;
seed_table[i] = 17798; i++;
seed_table[i] = 21977; i++;
seed_table[i] = 19643; i++;
seed_table[i] = 20662; i++;
seed_table[i] = 10834; i++;
seed_table[i] = 20103; i++;
seed_table[i] = 27067; i++;
seed_table[i] = 28634; i++;
seed_table[i] = 18623; i++;
seed_table[i] = 25849; i++;
seed_table[i] = 8576; i++;
seed_table[i] = 26234; i++;
seed_table[i] = 23887; i++;
seed_table[i] = 18228; i++;
seed_table[i] = 32587; i++;
seed_table[i] = 4836; i++;
seed_table[i] = 3306; i++;
seed_table[i] = 1811; i++;
seed_table[i] = 3035; i++;
seed_table[i] = 24559; i++;
seed_table[i] = 18399; i++;
seed_table[i] = 315; i++;
seed_table[i] = 26766; i++;
seed_table[i] = 907; i++;
seed_table[i] = 24102; i++;
seed_table[i] = 12370; i++;
seed_table[i] = 9674; i++;
seed_table[i] = 2972; i++;
seed_table[i] = 10472; i++;
seed_table[i] = 16492; i++;
seed_table[i] = 22683; i++;
seed_table[i] = 11529; i++;
seed_table[i] = 27968; i++;
seed_table[i] = 30406; i++;
seed_table[i] = 13213; i++;
seed_table[i] = 2319; i++;
seed_table[i] = 23620; i++;
seed_table[i] = 16823; i++;
seed_table[i] = 10013; i++;
seed_table[i] = 23772; i++;
seed_table[i] = 21567; i++;
seed_table[i] = 1251; i++;
seed_table[i] = 19579; i++;
seed_table[i] = 20313; i++;
seed_table[i] = 18241; i++;
seed_table[i] = 30130; i++;
seed_table[i] = 8402; i++;
seed_table[i] = 20807; i++;
seed_table[i] = 27354; i++;
seed_table[i] = 7169; i++;
seed_table[i] = 21211; i++;
seed_table[i] = 17293; i++;
seed_table[i] = 5410; i++;
seed_table[i] = 19223; i++;
seed_table[i] = 10255; i++;
seed_table[i] = 22480; i++;
seed_table[i] = 27388; i++;
seed_table[i] = 9946; i++;
seed_table[i] = 15628; i++;
seed_table[i] = 24389; i++;
seed_table[i] = 17308; i++;
seed_table[i] = 2370; i++;
seed_table[i] = 9530; i++;
seed_table[i] = 31683; i++;
seed_table[i] = 25927; i++;
seed_table[i] = 23567; i++;
seed_table[i] = 11694; i++;
seed_table[i] = 26397; i++;
seed_table[i] = 32602; i++;
seed_table[i] = 15031; i++;
seed_table[i] = 18255; i++;
seed_table[i] = 17582; i++;
seed_table[i] = 1422; i++;
seed_table[i] = 28835; i++;
seed_table[i] = 23607; i++;
seed_table[i] = 12597; i++;
seed_table[i] = 20602; i++;
seed_table[i] = 10138; i++;
seed_table[i] = 5212; i++;
seed_table[i] = 1252; i++;
seed_table[i] = 10074; i++;
seed_table[i] = 23166; i++;
seed_table[i] = 19823; i++;
seed_table[i] = 31667; i++;
seed_table[i] = 5902; i++;
seed_table[i] = 24630; i++;
seed_table[i] = 18948; i++;
seed_table[i] = 14330; i++;
seed_table[i] = 14950; i++;
seed_table[i] = 8939; i++;
seed_table[i] = 23540; i++;
seed_table[i] = 21311; i++;
seed_table[i] = 22428; i++;
seed_table[i] = 22391; i++;
seed_table[i] = 3583; i++;
seed_table[i] = 29004; i++;
seed_table[i] = 30498; i++;
seed_table[i] = 18714; i++;
seed_table[i] = 4278; i++;
seed_table[i] = 2437; i++;
seed_table[i] = 22430; i++;
seed_table[i] = 3439; i++;
seed_table[i] = 28313; i++;
seed_table[i] = 23161; i++;
seed_table[i] = 25396; i++;
seed_table[i] = 13471; i++;
seed_table[i] = 19324; i++;
seed_table[i] = 15287; i++;
seed_table[i] = 2563; i++;
seed_table[i] = 18901; i++;
seed_table[i] = 13103; i++;
seed_table[i] = 16867; i++;
seed_table[i] = 9714; i++;
seed_table[i] = 14322; i++;
seed_table[i] = 15197; i++;
seed_table[i] = 26889; i++;
seed_table[i] = 19372; i++;
seed_table[i] = 26241; i++;
seed_table[i] = 31925; i++;
seed_table[i] = 14640; i++;
seed_table[i] = 11497; i++;
seed_table[i] = 8941; i++;
seed_table[i] = 10056; i++;
seed_table[i] = 6451; i++;
seed_table[i] = 28656; i++;
seed_table[i] = 10737; i++;
seed_table[i] = 13874; i++;
seed_table[i] = 17356; i++;
seed_table[i] = 8281; i++;
seed_table[i] = 25937; i++;
seed_table[i] = 1661; i++;
seed_table[i] = 4850; i++;
seed_table[i] = 7448; i++;
seed_table[i] = 12744; i++;
seed_table[i] = 21826; i++;
seed_table[i] = 5477; i++;
seed_table[i] = 10167; i++;
seed_table[i] = 16705; i++;
seed_table[i] = 26897; i++;
seed_table[i] = 8839; i++;
seed_table[i] = 30947; i++;
seed_table[i] = 27978; i++;
seed_table[i] = 27283; i++;
seed_table[i] = 24685; i++;
seed_table[i] = 32298; i++;
seed_table[i] = 3525; i++;
seed_table[i] = 12398; i++;
seed_table[i] = 28726; i++;
seed_table[i] = 9475; i++;
seed_table[i] = 10208; i++;
seed_table[i] = 617; i++;
seed_table[i] = 13467; i++;
seed_table[i] = 22287; i++;
seed_table[i] = 2376; i++;
seed_table[i] = 6097; i++;
seed_table[i] = 26312; i++;
seed_table[i] = 2974; i++;
seed_table[i] = 9114; i++;
seed_table[i] = 21787; i++;
seed_table[i] = 28010; i++;
seed_table[i] = 4725; i++;
seed_table[i] = 15387; i++;
seed_table[i] = 3274; i++;
seed_table[i] = 10762; i++;
seed_table[i] = 31695; i++;
seed_table[i] = 17320; i++;
seed_table[i] = 18324; i++;
seed_table[i] = 12441; i++;
seed_table[i] = 16801; i++;
seed_table[i] = 27376; i++;
seed_table[i] = 22464; i++;
seed_table[i] = 7500; i++;
seed_table[i] = 5666; i++;
seed_table[i] = 18144; i++;
seed_table[i] = 15314; i++;
seed_table[i] = 31914; i++;
seed_table[i] = 31627; i++;
seed_table[i] = 6495; i++;
seed_table[i] = 5226; i++;
seed_table[i] = 31203; i++;
seed_table[i] = 2331; i++;
seed_table[i] = 4668; i++;
seed_table[i] = 12650; i++;
seed_table[i] = 18275; i++;
seed_table[i] = 351; i++;
seed_table[i] = 7268; i++;
seed_table[i] = 31319; i++;
seed_table[i] = 30119; i++;
seed_table[i] = 7600; i++;
seed_table[i] = 2905; i++;
seed_table[i] = 13826; i++;
seed_table[i] = 11343; i++;
seed_table[i] = 13053; i++;
seed_table[i] = 15583; i++;
seed_table[i] = 30055; i++;
seed_table[i] = 31093; i++;
seed_table[i] = 5067; i++;
seed_table[i] = 761; i++;
seed_table[i] = 9685; i++;
seed_table[i] = 11070; i++;
seed_table[i] = 21369; i++;
seed_table[i] = 27155; i++;
seed_table[i] = 3663; i++;
seed_table[i] = 26542; i++;
seed_table[i] = 20169; i++;
seed_table[i] = 12161; i++;
seed_table[i] = 15411; i++;
seed_table[i] = 30401; i++;
seed_table[i] = 7580; i++;
seed_table[i] = 31784; i++;
seed_table[i] = 8985; i++;
seed_table[i] = 29367; i++;
seed_table[i] = 20989; i++;
seed_table[i] = 14203; i++;
seed_table[i] = 29694; i++;
seed_table[i] = 21167; i++;
seed_table[i] = 10337; i++;
seed_table[i] = 1706; i++;
seed_table[i] = 28578; i++;
seed_table[i] = 887; i++;
seed_table[i] = 3373; i++;
seed_table[i] = 19477; i++;
seed_table[i] = 14382; i++;
seed_table[i] = 675; i++;
seed_table[i] = 7033; i++;
seed_table[i] = 15111; i++;
seed_table[i] = 26138; i++;
seed_table[i] = 12252; i++;
seed_table[i] = 30996; i++;
seed_table[i] = 21409; i++;
seed_table[i] = 25678; i++;
seed_table[i] = 18555; i++;
seed_table[i] = 13256; i++;
seed_table[i] = 23316; i++;
seed_table[i] = 22407; i++;
seed_table[i] = 16727; i++;
seed_table[i] = 991; i++;
seed_table[i] = 9236; i++;
seed_table[i] = 5373; i++;
seed_table[i] = 29402; i++;
seed_table[i] = 6117; i++;
seed_table[i] = 15241; i++;
seed_table[i] = 27715; i++;
seed_table[i] = 19291; i++;
seed_table[i] = 19888; i++;
seed_table[i] = 19847;
}

//
// Misma funcionalidad que random.cpp y nospread.cpp (Snipity Hook)
void Random::SetRandomFloatVector(unsigned int seed, int future){// By 85
for(int i=0; i<4; i++){
glSeed = seed_table[(int)(seed+future+i)&0xff];
for(int j=0; j<3;j++){
glSeed *= 69069;
glSeed += seed_table[glSeed&0xff];
(++glSeed & 0x0fffffff);
}
RandomFloat[i]=(-0.5+(float)(((glSeed&0x0fffffff)&65535)/65536.0f));
}
}

//
int main(){

unsigned int seed;
int future;
seed = time(NULL);
future=1;
int i =0;

while(1)
{
seed = time(NULL);//No es la seed original (Original es me.spread.random_seed)
       random.SetRandomFloatVector(seed, future);
printf("RandomFloat[0] %f\n",random.getRandomFloatVector()[0]);
printf("RandomFloat[1] %f\n",random.getRandomFloatVector()[1]);
printf("RandomFloat[2] %f\n",random.getRandomFloatVector()[2]);
printf("RandomFloat[3] %f\n",random.getRandomFloatVector()[3]);
printf("\n");

std::cout << "Press the ENTER key\n";
if (std::cin.get() == '\n');

if(i++==10) break;
}

system("pause > nul");
return 0;
}

//

Proyecto vc6: http://www.mediafire.com/?a93dsydc3gvrrdj

24  Programación / Programación C/C++ / Parchear la EAT para interceptar GPA en: 2 Marzo 2013, 10:06 am
NIVEL: Beginner
TEST: win XP SP3

Esta es la continuación de esta especie de tutorial que había
comenzado en este hilo:

http://foro.elhacker.net/programacion_cc/parchear_la_iat_para_interceptar_gpa-t384232.0.html


En este caso, vamos a utilizar el desensamblador que veníamos usando
para obtener ciertos datos acerca de una librería llamada kernel32.dll
para los que no la conocen, es una librería (DLL) del sistema Windows
y la pueden encontrar en la carpeta system32.
Más información:
http://en.wikipedia.org/wiki/Microsoft_Windows_library_files

Usamos el desensamblador (O un explorador PE) para observar los detalles del archivo. Y también cierta información que vamos a utilizar.















Luego el código del programa..
En este programa contamos con dos rutinas que realizan el mismo
objetivo: Parchear la EAT de kernel32.dll

La diferencia es que la primera hace las operaciones automáticamente
valiéndose de cierta información obtenida del siguiente tutorial:
http://www.mediafire.com/?6nzmp28x2pb9b4n

y de esto:
http://www.cyvera.com/how-injected-code-finds-exported-functions/

Realiza algunas operaciones con ensamblador en línea y luego parchea la EAT.

La segunda rutina cumple con el objetivo pero sin usar ensamblador
en línea.

Con respecto al por qué de usar ASM, es para mostrar algo diferente
del anterior tutorial en el que se hacía todo automáticamente y con
C/C++.
http://foro.elhacker.net/programacion_cc/parcheo_de_eat_y_de_iat_automatico-t384486.0.html

NOTA: El objetivo es como se puede usar una herramienta como puede
ser un explorador de PE, o un desensamblador cualquiera, para obtener
estos datos.

Inclusive este tipo de cosas se puede hacer sin necesidad de código, es decir simplemente usando este tipo de herramientas pero para parchear los archivos en disco. Pero la idea era codificar algo XD

El código del programa:
Código
  1.  
  2. //
  3. // By 85
  4. // elhacker.net
  5. // etalking.com.ar
  6. // boyscout_arg@hotmail.com
  7. // 2013
  8. //
  9.  
  10. #include<windows.h>
  11. #include<stdio.h>
  12.  
  13. //
  14. FARPROC (WINAPI* pGetProcAddress) ( HMODULE hModule, LPCSTR lpProcName );
  15.  
  16. typedef FARPROC (WINAPI* GetProcAddress_t) ( HMODULE hModule, LPCSTR lpProcName );
  17.  
  18. //
  19. FARPROC WINAPI newGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
  20. {
  21. FARPROC nResult;
  22. nResult=pGetProcAddress(hModule, lpProcName);
  23. if (HIWORD(lpProcName))
  24. {
  25. if (!lstrcmp(lpProcName, "GetProcAddress"))
  26. {
  27. return (FARPROC) &newGetProcAddress;
  28. }
  29. }
  30. return nResult;
  31. }
  32.  
  33. //
  34. DWORD PatchEAT( DWORD pOrgFunction, DWORD pNewFunction )
  35. {
  36. DWORD dwOldProtect;
  37. DWORD dwOldProtect2;
  38. DWORD pOldFunction = ((DWORD*)pOrgFunction)[0];
  39.  
  40. VirtualProtect( reinterpret_cast< void * >( pOrgFunction ), sizeof( DWORD ), PAGE_EXECUTE_READWRITE, &dwOldProtect );
  41. ((DWORD*)pOrgFunction)[0] = pNewFunction;
  42. VirtualProtect( reinterpret_cast< void * >( pOrgFunction ), sizeof( DWORD ), dwOldProtect, &dwOldProtect2 );
  43. return pOldFunction;
  44. }
  45.  
  46. //
  47. void PatchEatConInlineASM(){
  48.  
  49. char* gpastr = "GetProcAddress";
  50. DWORD k32base = (DWORD)GetModuleHandle("kernel32.dll");
  51.  
  52. // Logs
  53.    DWORD peheader=0;
  54. DWORD rva_exports_dir=0;
  55. DWORD rva_exports_funcs=0;
  56. DWORD rva_exports_fnames=0;
  57. DWORD va_exports_fnames=0;
  58. DWORD va_eat=0;
  59. int savedeax;
  60. DWORD rEDX;
  61.  
  62. __asm{
  63. mov ebx, k32base                      //EBX = kernel32.dll's base address
  64. mov edx,dword ptr ds:[ebx+3Ch]        //PE header
  65. mov peheader, edx
  66. mov edx,dword ptr ds:[edx+ebx+78h]    //EDX = kernel32.dll's export directory (RVA)
  67. mov rva_exports_dir, edx
  68. mov eax,dword ptr ds:[edx+ebx+1Ch]    //Address of exported funcs (EAX = EAT (RVA))
  69. mov rva_exports_funcs, eax
  70. mov edx,dword ptr ds:[edx+ebx+20h]    //EDX = Address of function names (RVA)
  71. mov rva_exports_fnames, edx
  72. add edx,ebx                           //EDX = Address of function names (VA)
  73. mov va_exports_fnames, edx
  74. add eax,ebx                           //EAX = EAT (VA)
  75. mov va_eat, eax
  76. }
  77.  
  78. __asm{
  79.  
  80. get_exports:
  81. xor ecx, ecx
  82. mov esi,gpastr              //Address of string "GetProcAddress" (not null-terminated)
  83. mov edi,dword ptr ds:[edx]  //EDI = *(EDX = VA of function names)
  84. add edi,ebx                 //Address of string (Exported function name) (k32+offs en edi)
  85. mov cl,0Eh                  //14 chars
  86. repe cmpsb                  //recibe dos direcciones de 2 strings (ESI,EDI)
  87. je short found_set_context  //Jump if this is our function
  88. add edx,4                   //Next function name
  89. add eax,4                   //Next function address
  90. jmp short get_exports
  91. found_set_context:
  92. mov savedeax, eax
  93. mov edx,dword ptr ds:[eax]
  94. add edx,ebx  
  95. mov rEDX, edx
  96. }
  97.  
  98.  
  99. printf("k32 0x%X\n",k32base);
  100. printf("peheader 0x%X\n",peheader);
  101. printf("rva_exports_dir 0x%X\n",rva_exports_dir);
  102. printf("rva_exports_funcs 0x%X\n",rva_exports_funcs);
  103. printf("rva_exports_fnames 0x%X\n",rva_exports_fnames);
  104. printf("va_exports_fnames 0x%X\n",va_exports_fnames);
  105. printf("va_eat 0x%X\n",va_eat);
  106. printf("primer entrada de va_eat 0x%X\n",*(DWORD*)va_eat);//da un rva
  107. printf("savedeax 0x%X\n",savedeax);// eat entry para gpa
  108. printf("savedeax 0x%X\n",*(DWORD*)savedeax);// el rva en el eat entry correspondiente a gpa
  109. printf("GetProcAddress 0x%X\n",GetProcAddress);
  110. printf("rEDX 0x%X\n",rEDX);
  111. system("pause");
  112.  
  113. /////////////////////////////////////////////////
  114.  
  115. // Calcular el rva con mi gpa
  116. DWORD rvaMiGPA = (((DWORD)newGetProcAddress)-DWORD(k32base));
  117.  
  118. // Inicializar puntero de retorno a la original
  119. pGetProcAddress = (GetProcAddress_t)rEDX;
  120.  
  121. // Parche
  122. PatchEAT( savedeax, rvaMiGPA );// savedeax = eat entry para gpa
  123.  
  124. printf("newGetProcAddress 0x%X\n",newGetProcAddress);
  125. // printf("GetProcAddress 0x%X\n",GetProcAddress);
  126. system("pause");
  127. }
  128.  
  129. //
  130. void PatchEatSinInlineASM(){
  131.  
  132. DWORD k32base = (DWORD)GetModuleHandle("kernel32.dll");
  133. DWORD exports = k32base+0x262C;
  134. DWORD* dwEAT = (DWORD*)(exports+0x28);//953 entradas
  135. printf("EAT 0x%X\n",dwEAT);
  136.  
  137. //for(int i=0;i<409-1;i++) dwEAT+=0x1;
  138. //printf("GPA EAT 0x%X\n",dwEAT);
  139. //printf("*GPA EAT 0x%X\n",*(dwEAT));
  140.  
  141. DWORD dwEATgpa = (DWORD)(dwEAT+0x198);
  142. printf("GPA EAT 0x%X\n",(dwEAT+0x198));//0x199 = 409
  143. printf("*GPA EAT 0x%X\n",*(dwEAT+0x198));
  144.  
  145. DWORD rvaGPA = dwEAT[409-1];//409 = gpa index
  146. DWORD dwGPA = k32base+rvaGPA;
  147.  
  148. printf("rvaGPA 0x%X\n",rvaGPA);
  149. printf("dwGPA 0x%X\n",dwGPA);
  150. // printf("GetProcAddress 0x%X\n",GetProcAddress);
  151. //system("pause");
  152.  
  153. /////////////////////////////////////////////////
  154.  
  155. // Calcular el rva de mi gpa
  156. DWORD rvaMiGPA = (((DWORD)newGetProcAddress)-DWORD(k32base));
  157.  
  158. printf("dwEATgpa 0x%X\n",dwEATgpa);
  159. printf("rvaMiGPA 0x%X\n",rvaMiGPA);
  160.  
  161. // Inicializar puntero de retorno a la original
  162. pGetProcAddress = (GetProcAddress_t)dwGPA;
  163.  
  164. // Parche
  165. PatchEAT( dwEATgpa, rvaMiGPA );
  166.  
  167. printf("newGetProcAddress 0x%X\n",newGetProcAddress);
  168. // printf("GetProcAddress 0x%X\n",GetProcAddress);
  169. system("pause");
  170. }
  171.  
  172. //
  173. int main(){
  174.  
  175. // 1
  176. // PatchEatConInlineASM();
  177.  
  178. // 2
  179. PatchEatSinInlineASM();
  180.  
  181. /////////////////////////////////////////////////
  182. // Test
  183.  
  184. DWORD test = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
  185. printf("test 0x%X\n",test);
  186. printf("pGetProcAddress 0x%X\n",pGetProcAddress);// retorno a la original
  187.  
  188. system("pause");
  189. return 0;
  190. }
  191.  
  192. //
  193.  

PROYECTO VC6
http://www.mediafire.com/?t87q7m7b7give3b

hasta luego
25  Programación / Programación C/C++ / 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
26  Programación / Programación C/C++ / Parchear la IAT para interceptar GPA en: 27 Febrero 2013, 04:56 am
Hola, quería mostrar algo básico que puede aportar algunos conceptos. Más que nada, gente que está en sus comienzos con la programación y puede interesarse en algunos detalles técnicos.

NIVEL: Beginner
No consideren esto de nivel avanzado.

Lo primero:
IAT = IMPORT ADDRESS TABLE
http://sandsprite.com/CodeStuff/Understanding_imports.html
http://www.karmany.net/index.php/ingenieria-inversa/19-ingenieria-inversa-novatos/146-pe-header-que-es-la-iat-import-address-table
http://cboard.cprogramming.com/cplusplus-programming/99240-import-address-table-iat.html

La iat es un lugar que puede accederse fácilmente con un desensamblador y se pueden observar todos los símbolos que el ejecutable importa de ciertos módulos. Hay una forma de hacer que el ejecutable no contenga imports, pero fuera de esa técnica los ejecutables la utilizan.
Generalmente se dice que los EXE usan la IAT y las DLL las EAT,
véase EAT = EXPORT ADDRESS TABLA , es para exportar símbolos.

Más información
http://www.rohitab.com/discuss/topic/33541-assembling-an-executable-with-no-imports/
http://www.etalking.com.ar/showthread.php?400-llamar-funciones-winapi32-sin-imports


Volviendo al tema, veamos lo que uno puede hacer fácilmente, con un desensamblador:









Obteniendo la dirección específica en la IAT se puede proceder a crear el parche con el cual se logra interceptar GetProcAddress.
Se trata sólo de cambiar el valor de un puntero, poniéndole la dirección de nuestra función "de gancho" o hook, para que sea llamada en lugar de la original.

Código:

//
// By 85
// PatchIAT LTFX
// elhacker.net
// etalking.com.ar
// 2013
//

#include<windows.h>
#include<stdio.h>

FARPROC (WINAPI* pGetProcAddress) ( HMODULE hModule, LPCSTR lpProcName );

typedef FARPROC (WINAPI* GetProcAddress_t) ( HMODULE hModule, LPCSTR lpProcName );

FARPROC WINAPI newGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
FARPROC nResult;
nResult=pGetProcAddress(hModule, lpProcName);
if (HIWORD(lpProcName))
{
if (!lstrcmp(lpProcName, "GetProcAddress"))
{
return (FARPROC) &newGetProcAddress;
}
}
return nResult;
}

DWORD PatchIAT( DWORD pOrgFunction, DWORD pNewFunction )
{
DWORD dwOldProtect;
DWORD dwOldProtect2;
DWORD pOldFunction = ((DWORD*)pOrgFunction)[0];

VirtualProtect( reinterpret_cast< void * >( pOrgFunction ), sizeof( DWORD ), PAGE_EXECUTE_READWRITE, &dwOldProtect );
((DWORD*)pOrgFunction)[0] = pNewFunction;
VirtualProtect( reinterpret_cast< void * >( pOrgFunction ), sizeof( DWORD ), dwOldProtect, &dwOldProtect2 );
return pOldFunction;
}

int main(){

//400000+2004= GPA IAT ENTRY (En este programa x64core!, no lo modifiques!)
DWORD dwGPA = (DWORD)(GetModuleHandle(NULL));
dwGPA+=0x2004;

// x64core lo quiere en ASM inline..
__asm {
mov ebx, dwGPA
mov edx, [ebx]
mov pGetProcAddress, edx
}

// pGetProcAddress = *(GetProcAddress_t*)dwGPA;// Ajam..

printf("pGetProcAddress 0x%X\n\n",pGetProcAddress);
printf("GetProcAddress antes 0x%X\n\n",*(DWORD*)dwGPA);
// printf("GetProcAddress antes 0x%X\n\n",GetProcAddress);//No referenciar GPA antes del parche!

// Parchear IAT
PatchIAT( dwGPA, (DWORD)&newGetProcAddress );

// Sin PatchIAT:
//Desproteger
//DWORD* pGPA=(DWORD*)0x00402004;//400000+2004= GPA IAT ENTRY
//*pGPA=(DWORD)&newGetProcAddress;
//Proteger

printf("dwGPA 0x%X\n",dwGPA);
printf("*dwGPA 0x%X\n",*(DWORD*)dwGPA);
printf("GetProcAddress ahora 0x%X\n",GetProcAddress);
printf("newGetProcAddress 0x%X\n",newGetProcAddress);
system("pause");

DWORD test = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
printf("test 0x%X\n",test);
printf("GetProcAddress ahora 0x%X\n",GetProcAddress);
system("pause");
return 0;
}

//

Dejo el proyectito para descargar
http://www.mediafire.com/?2sowg12a6vora4n

Hasta Luego
27  Programación / Programación C/C++ / Tutorial: Crear un parche 1 en: 25 Febrero 2013, 09:12 am
Estaba mirando un tema acerca de como se pasaba por alto la detección de un anticheat y se me ocurrió la idea de mostrar como se puede hacer un parche básico dentro de un mismo proceso. Es decir tenemos un ejecutable, lo ejecutamos y parcheamos nuestra propia memoria. Esto se puede hacer de varias formas, una de ellas es inyectando una DLL , pero esto es algo más fácil :p

Cómo es una demostración el propio programa se parchea así mismo, por lo que necesitamos saber en que lugar vamos a querer modificar las cosas.
Para eso en el programa puse un bloque condicional que es el que me interesa parchear para poder accederlo aunque no se cumpla la condición.
Por Ejemplo:
Código:
if( 0 == 1){ /* no se cumple */ }
Eso no se cumple, pero parcheándolo se logra acceder de todas formas..

Con un desensamblador, abro el ejecutable (el archivo EXE) y procedo a mirar el código ensamblador.


Identifico el OPCODE que me interesa cambiar, en este caso es JZ (0x74), y procedo a obtener la posición en donde se encuentra (dirección de memoria).

Es 0x40106C

En realidad lo que nos interesa es saber el desplazamiento en bytes que hay desde la dirección base del ejecutable hasta el punto en el que queremos parchear.
Se puede tomar en cuenta la sección de código también pero no es la base del ejecutable, recordar al momento de hacer la cuenta..


Bueno el offset (desplazamiento) es 0x6C y 0x1000 de la sección de código.

Bueno sabiendo estas cosas, ya vamos al código..
Con respecto al código, como decía antes, la idea viene de algo que estaba mirando sobre llamadas seguras a funciones para evitar detecciones de un anticheat por ejemplo,,
Por eso fui a crear una función (Check()) que trata de ser en forma figurativa la detección de modificaciones en la memoria.
Aunque en realidad una función de este tipo no tiene mucho sentido en el mismo hilo de ejecución, se debería hacer desde otro..

Y otro concepto que se puede apreciar en todo esto, es la importancia de restaurar la memoria luego de modificarla y lograr lo deseado.
Por eso , en este programa luego de realizar el parche y de llamar a la función de prueba (Target()) , se procede a restaurar la memoria a como estaba antes, para que las detecciones no se disparen.

Véase el bloque condicional donde se desea poder ingresar
Código:
...
if(master==MASTERNUM)//Aquí es donde queremos entrar XD
{ ...

Código
  1.  
  2. //
  3. // By 85
  4. // Credits: Organner
  5. // elhacker.net
  6. // etalking.com.ar
  7. // 2013
  8. //
  9.  
  10. ///////////////////
  11.  
  12. #include<windows.h>
  13. #include<stdio.h>
  14.  
  15. //////////////////////
  16.  
  17. DWORD dwPatchPlace = 0x00000000;
  18. BYTE Opcode_JZ = 0x74;
  19. BYTE Opcode_JNZ = 0x75;
  20.  
  21. ///////////
  22.  
  23. inline void Patch(){//Función de parcheadora
  24.  
  25. if(*(PBYTE)dwPatchPlace!=Opcode_JZ) return;
  26.  
  27. DWORD dwOldProtect;
  28.    VirtualProtect( (LPVOID)dwPatchPlace,
  29.                    1,
  30.                    PAGE_EXECUTE_WRITECOPY,
  31.                    &dwOldProtect );
  32.  
  33. WriteProcessMemory( GetCurrentProcess(),
  34.                        (LPVOID)dwPatchPlace,
  35.                        &Opcode_JNZ,
  36.                        1,
  37.                        NULL );
  38.  
  39. VirtualProtect( (LPVOID)dwPatchPlace,
  40.                    1,
  41.                    dwOldProtect,
  42.                    &dwOldProtect );
  43. }
  44.  
  45. //
  46. inline void UnPatch(){//Función restauradora
  47.  
  48. if(*(PBYTE)dwPatchPlace!=Opcode_JNZ) return;
  49.  
  50. DWORD dwOldProtect;
  51.    VirtualProtect( (LPVOID)dwPatchPlace,
  52.                    1,
  53.                    PAGE_EXECUTE_WRITECOPY,
  54.                    &dwOldProtect );
  55.  
  56. WriteProcessMemory( GetCurrentProcess(),
  57.                        (LPVOID)dwPatchPlace,
  58.                        &Opcode_JZ,
  59.                        1,
  60.                        NULL );
  61.  
  62. VirtualProtect( (LPVOID)dwPatchPlace,
  63.                    1,
  64.                    dwOldProtect,
  65.                    &dwOldProtect );
  66. }
  67.  
  68. ////////////////////
  69.  
  70. void Target(){//Función objetivo para ser alterada
  71.  
  72. while(1){
  73.  
  74. #define MASTERNUM 85
  75. int master=0x99999997;
  76. char* ingreso = new char[256];
  77.  
  78. system("cls");
  79. printf("Ingrese la llave maestra\n");
  80. scanf("%s", ingreso);
  81.  
  82. if(!strcmpi(ingreso, new char[]= "key85\0")){
  83.  
  84. master = 85;
  85. }
  86.  
  87. delete []ingreso;
  88. if(master==MASTERNUM)//Aquí es donde queremos entrar XD
  89. {
  90. printf("FELICITACIONES! USTED HA INGRESADO\n");
  91. printf("\n");
  92. system("pause");
  93. break;
  94. }
  95.  
  96. // if(GetAsyncKeyState(VK_END)) break;// En otro hilo
  97. if(!strcmpi(ingreso, new char[]= "exit\0")) break;
  98. }
  99. }
  100.  
  101. //
  102. void Check()//Función que representa un método de seguridad
  103. {
  104. if(*(PBYTE)dwPatchPlace != Opcode_JZ)
  105. {
  106. printf("0x%X\n",*(PBYTE)dwPatchPlace);
  107. printf("Memoria alterada!, se sale del programa..\n");
  108. printf("\n");
  109. system("pause");
  110. ExitProcess(45);
  111. }
  112. }
  113.  
  114. /////////
  115.  
  116. int main(){
  117.  
  118. // We have to replace JZ with JNZ.
  119.  
  120. dwPatchPlace=(DWORD)GetModuleHandle(NULL);//Retorna la BaseAddress
  121.  
  122. //Sumamos el offset obtenido del desensamblado
  123. dwPatchPlace+=0x00001000;
  124. dwPatchPlace+=0x6C;
  125.  
  126. //Logs
  127. printf("0x%X\n",(DWORD)GetModuleHandle(NULL));
  128. printf("0x%X\n",dwPatchPlace);
  129. printf("0x%X\n",*(PBYTE)dwPatchPlace);
  130. printf("\n");
  131. system("pause");
  132.  
  133. //Parcheamos la memoria antes de llamar a la función
  134. Patch();
  135.  
  136. //Llamamos a la función objetivo
  137. Target();
  138.  
  139. //Volvemos a dejar la memoria como estaba antes
  140. // UnPatch();
  141.  
  142. //Se deja que las comprobaciones de seguridad sigan su curso normalmente
  143. Check();
  144.  
  145. return 0;
  146. }
  147.  

Unas imágenes, aunque voy a dejar el proyecto para descargar.


La llamada a UnPatch() está comentada, por eso la detección se dispara..


Un comentario acerca del uso de WriteProcessMemory, no es necesario,,
ya que con simplemente hacer esto:
Código:
*(PBYTE)dwPatchPlace= Opcode_JNZ;
es suficiente, ya que es un mismo proceso.
lo que pasa que ambas funciones fueron sacadas de un post de un tal Organner, que algunos deben saber quien es, sólo les cambié una cosa y listo, aunque tampoco son algo especial como para que deban tener un autor XD

Proyecto MSVC6
http://www.mediafire.com/?j7s6a85bp4k5p3t

Este tutorial está orientado a gente principiante en la programación, no sea considerado un tutorial avanzado  ;D

Hasta Luego
28  Programación / Programación C/C++ / MSVCRT hook en: 24 Febrero 2013, 18:50 pm
Un ejemplo interesante en donde se intercepta a modo de prueba la función STRLWR , no voy a tomar crédito del hook ya que se trata de un simple parche que lo he googleado en 5 segundos XD, lo que si voy a mostrar un par de fotos al respecto..

Como se compiló el ejecutable, para que sea dependiente de la DLL msvcrt


Como se buscó el export en la DLL, se puede observar su índice y su símbolo.


El resto del código no es nada especial, dejo el proyecto en vc6
http://www.mediafire.com/?s9vic23mvrjxrwg

Código:
//
// By 85
// elhacker.net
// InterceptAPI: (googleado en 5 segundos XD)
// 2013
//


#pragma comment (lib,"Shlwapi.lib")
#include<windows.h>
#include <Shlwapi.h>
#include<stdio.h>

///////////////////////////////////////////////////////////

char* mystrlwr(char* a){

static bool onlyonce=false;
if(!onlyonce){
onlyonce=true;
printf("\nSTRLWR INTERCEPTADA!\n");
// MessageBox(0,0,0,0);
}
return a;
}

//
BOOL InterceptAPI(HMODULE hLocalModule,const char* c_szDllName,const char* c_szApiName, DWORD dwReplaced)
{
    DWORD dwOldProtect;
    DWORD dwAddressToIntercept=(DWORD)GetProcAddress(GetModuleHandle((char*)c_szDllName),(char*)c_szApiName);
printf("add: %x\n", dwAddressToIntercept);
printf("dll: %s\n", c_szDllName);
printf("api: %s\n", c_szApiName);
// system("pause");
if(!dwAddressToIntercept) return false;
    BYTE *pbTargetCode = (BYTE *) dwAddressToIntercept;
    BYTE *pbReplaced = (BYTE *) dwReplaced;
    VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_WRITECOPY, &dwOldProtect);
    *pbTargetCode++ = 0xE9;        // jump rel32
    *((signed int *)(pbTargetCode)) = pbReplaced - (pbTargetCode +4);
    VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_EXECUTE, &dwOldProtect);
    FlushInstructionCache(GetCurrentProcess(), NULL, NULL);
    return TRUE;
}

//
void Dummy(){

strlwr(new char[] = "85 de elhacker.net :D\0");
}

//
int main(){

Sleep(500);
char l_s11[] = {'m','s','v','c','p','6','0','.','d','l','l',0};
char l_s12[] = {'m','s','v','c','p','7','1','.','d','l','l',0};
char l_s13[] = {'m','s','v','c','p','1','0','0','.','d','l','l',0};
char l_s[] = {'m','s','v','c','r','t','.','d','l','l',0};
char l_api[] = {'_','s','t','r','l','w','r',0};
char l_exe[] = {'m','s','v','c','r','t','_','h','o','o','k','.','e','x','e',0};
char FileName[256];
if(!GetModuleHandle(l_s)) ExitProcess(0);
GetModuleFileName(GetModuleHandle(NULL), FileName, sizeof(FileName));
PathStripPath(FileName);
if (strcmp(FileName, l_exe) == 0){
InterceptAPI(GetModuleHandle(NULL), l_s, l_api, (DWORD)mystrlwr);
                /* else: no se ha interceptado ! */
}
else
{ /* no se ha interceptado ! */ return 0;}
Dummy();
printf("\n");
system("pause");
return 0;
}
29  Programación / Ingeniería Inversa / crackeáte esta cuenta en: 24 Febrero 2013, 01:15 am
Bueno este es un crackme , supongo que para muchos puede resultar de nivel principiante. En realidad yo no estoy familiarizado con el cracking, pero encontré un código con una rutina interesante y me pareció que podía servir para un crackme. Si y sólo si están interesados en resolver un crackme más en sus vidas, háganlo , no es mi intención quitarles su tiempo XD. Disculpen si falta algo XD

Nivel:
Principiante, conocimiento de hooking/patching, desensamblado, depurado, etc

Objetivo:
Que salga un cartel contando que el resultado fue exitoso. Se requiere mostrar los datos de usuario que fueron encontrados y explicar como se resolvió. Los datos son un nombre de usuario y la contraseña. Pueden exponer un código si lo desean.

Elementos:
XP SP3 x86, MSVCPP6

Premio: Ninguno. Un código con la rutina utilizada.

Necesitan algo más ? avisen.
http://www.mediafire.com/?bb4xz7ta4qrfr6e

30  Programación / Programación C/C++ / ghostwriting? cadenas que no son detectadas en: 24 Febrero 2013, 01:02 am
Estaba mirando cuando uno desensambla un programa en c++, no protegido obviamente.... no hablo de un editor hexadecimal ni de ollyDBG, un desensamblado normal que muestre el código  ensamblador.
Algunas strings son detectadas y otras no, en realidad no se si esto se llama ghostwriting porque parece que ghostwriting es otra cosa aparte.

Suponiendo el siguiente código que muestra algunas de las formas más conocidas de declarar cadenas:
Código:

//
// By 85
// elhacker.net
// 2013
//

#include<windows.h>
#include<stdio.h>

void Test(){
char test1[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0};
char test11[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0};
char test111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0};
char test1111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0};
char test11111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0};
char testA[256];
strcat(testA,test1);
strcat(testA," 85\0");
printf(test1);
printf("\n\n");
char test2[] = "ochentaycinco1\0";
char test22[] = "ochentaycinco2\0";
char test222[] = "ochentaycinco3\0";
char test2222[] = "ochentaycinco4\0";
char test22222[] = "ochentaycinco5\0";
const char* testX = "ASD\0";
char testB[256];
strcat(testB,test2);
strcat(testB," 85\0");
printf(test2);
printf("\n\n");
printf(testX);
printf("\n\n");
}

int main()
{
Test();

char test11111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0};
char test22222[] = "ochentaycinco11\0";
const char* testX = "WWW\0";
printf("TEST1\n");
printf(testX);
printf("\n");
printf(new char[] = "wwwwwww\n");
printf(new char[] = "xxxxxxx\n");
printf(new char[] = "AAAAAAA\n");
system("pause");
return 0;
}


podemos ver las cadenas que son detectadas y las que no:




Si alguno quiere agregar algo con referencia al tema XD, en realidad yo si tuviera que recurrir a ocultar cadenas utilizaría algún tipo de encriptamiento interno, como XORSTR, pero esto se usa también



Páginas: 1 2 [3] 4
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines