Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: dRak0 en 8 Agosto 2014, 13:06 pm



Título: [Consulta] campo del struct MODULEENTRY32
Publicado por: dRak0 en 8 Agosto 2014, 13:06 pm
Tenia algo de tiempo y me puse a repasar algunas cosas

Aca el codigo:

Código
  1. HANDLE snapshot,snapshotModule=NULL;
  2.  
  3. PROCESSENTRY32 processEntry;
  4. MODULEENTRY32 moduleEntry;
  5. if((snapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0))==NULL){
  6. printf("\n%s","FAIL!!!!SNAPSHOTCREATE");
  7. return 0;
  8.  
  9. }
  10.  
  11. processEntry.dwSize=sizeof(PROCESSENTRY32);
  12. moduleEntry.dwSize=sizeof(MODULEENTRY32);
  13.  
  14. while(Process32Next(snapshot,&processEntry)==TRUE)
  15. {
  16. printf("\nPID:%d\nExe:%s\n",processEntry.th32ProcessID,processEntry.szExeFile);
  17. if(snapshotModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processEntry.th32ProcessID))
  18. {
  19. while(Module32Next(snapshotModule,&moduleEntry)==TRUE)
  20. printf("%s %s %d\n",moduleEntry.szModule,moduleEntry.szExePath,moduleEntry.th32ProcessID);
  21. }
  22. }
  23.  
  24. return 0;
  25.  
  26.  


->gcc.exe archivo.c -o archivo . OK
->archivo.exe | more

Ok. Fijense que me devuelve siempre el mismo PID en los modulos... Ese es el problema y no entiendo porque.

Saludos.


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: Eternal Idol en 8 Agosto 2014, 22:47 pm
De acuerdo a la descripcion y el codigo funciona correctamente (no intente generarlo); estas llamando a CreateToolhelp32Snapshot con TH32CS_SNAPMODULE, asi que todos los modulos enumerados tendran como PID el que le pasas como segundo argumento (processEntry.th32ProcessID).

TH32CS_SNAPMODULE
Includes all modules of the process specified in th32ProcessID in the snapshot. To enumerate the modules, see Module32First. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds.


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: dRak0 en 9 Agosto 2014, 16:25 pm
Que tal , esperaba tu respuesta jaja. Fijate de compilarlo y correrlo. Hace todo bien hasta busca los modulos en los diferentes procesos como quiero. El tema es que no se porque cuando lo imprimo me imprime siempre el mismo proceso.

Ejemplo burdo:

PID:3911
Exe:apache.exe

kernel32.dll pathdekernel32 912(Aqui esta el problema)
user32.dll pathuser32 912

PID:3222
Exe:justina.exe

kernel32.dll pathkernel32 912
user32.dll pathuser32 912
DLL'S DIFERENTES AL ANTERIOR PROCESO

asi con todos los procesos.

Muy raro no? No es realmente un problema , pero no realiza lo correcto y nose porque.

Saludos!


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: Eternal Idol en 9 Agosto 2014, 16:44 pm
Poniendo antes del while:
Código
  1. ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));

No parece que la API rellene ese campo, en principio no lo necesitas y tal vez lo hace cuando enumeres los modulos de todos los procesos y no de uno en particular.



Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: dRak0 en 9 Agosto 2014, 16:57 pm
Si pongo eso directamente ni me busca las dlls.

Modifico:No me buscaba las dlls porque tenia que inicializar el dwSize. Ahora me las busca , pero me muestra que pertenece al proceso 0 (Supongo debido al ZeroMemory) antes me mostraba q pertenician al 912.


Código
  1. while(Process32Next(snapshot,&processEntry)==TRUE)
  2. {
  3. printf("\nPID:%d\nExe:%s\n",processEntry.th32ProcessID,processEntry.szExeFile);
  4.  
  5.  
  6. if(snapshotModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processEntry.th32ProcessID))
  7. {
  8. ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
  9. moduleEntry.dwSize=sizeof(MODULEENTRY32);
  10. while(Module32Next(snapshotModule,&moduleEntry)==TRUE)
  11. printf("%s %s %d\n",moduleEntry.szModule,moduleEntry.szExePath,moduleEntry.th32ProcessID);
  12.  
  13. }
  14. }
  15.  

Para solucionarlo podria asignar el valor de la estructura PROCESSENTRY32 al MODULEENTRY32 . O sea si:

PROCESSENTRY32 proEntry;
MODULEENTRY32 modEntry;

modEntry.th32ProcessID=proEntry.th32ProcessID;

Pero quedaria muy horrible y ademas no responderia el porque me muestra siempre un valor.


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: Eternal Idol en 9 Agosto 2014, 17:16 pm
Si claro, antes del while, pero no antes de asignar el campo dwSize. Ya te dije la razon: la funcion de la API no escribe nada en ese campo; por lo menos es asi cuando usas TH32CS_SNAPMODULE. Antes tenias un valor indefinido, ahora esta inicializado a 0 y la API NO lo cambia nunca.


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: dRak0 en 9 Agosto 2014, 17:33 pm
Jaja y para que existe?He ahi la cuestion jaja.Entonces no seria tan horrible asignarle el de la estructura PROCESSENTRY32.

Bueno , gracias.

Ya que tenes bastante experiencia con la API de windows , te hago otra consulta.

Al ejecutar un WriteProcessMemory() me tira un error. Como me dijistes en otro post ,"si tenes un error usa GetLastError()" .Me tira error 5. Busque y significa "Permiso denegado". Pero el problema es que tengo todos los permisos. Ejecuto como administrador y ademas le ajusto los privilegios del TOKEN. Nose que pasa.

El espacio que reserve tiene sus permisos correctamente.


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: Eternal Idol en 9 Agosto 2014, 17:44 pm
No lo se, puede ser algo historico ... estas funciones vienen de 16 bits y es posible que las estructuras tengan campos heredados obsoletos como:

Note  The module identifier, which is specified in the th32ModuleID member of MODULEENTRY32, only has meaning in 16-bit Windows.

Si, 5 es ACCESS_DENIED, sin el codigo no se puede mas que adivinar.


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: dRak0 en 9 Agosto 2014, 18:12 pm
Código
  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <tlhelp32.h>
  4.  
  5. struct PARAMETROS{
  6. DWORD MessageBoxInj;
  7. char text[4];
  8. char caption[4];
  9. int buttons;
  10. };
  11.  
  12. typedef struct PARAMETROS PARAMETROS;
  13. int obtenerPID(char*);
  14. int privilegios();
  15. typedef int (WINAPI* MessageBoxParam)(HWND,LPCSTR,LPCSTR,UINT);
  16. DWORD FuncionInyectar(PARAMETROS* myparam);
  17. DWORD Useless();
  18.  
  19.  
  20. /****************************COMIENZO MAIN!*******************************/
  21.  
  22. int main(int argc,char **argv)
  23. {
  24. HANDLE procesoHandle,hilo=NULL;
  25. PARAMETROS data;
  26. char *mytext="Hola";
  27. char *mycaption="Hola";
  28. HMODULE user32=NULL;
  29. DWORD size_FuncionInyectar;
  30. LPVOID MyFuncAddress,parametrosAddress=NULL;
  31. int privilegio;
  32.  
  33.  
  34. //Obtengo PID
  35. int pid=obtenerPID("sublime_textSinASLR.exe");
  36. printf("PID:%d\n",pid);
  37.  
  38. //Privilegios
  39. privilegio=privilegios();
  40. printf("Privilegios%d\n",privilegio);
  41.  
  42. //Obtengo handle del proceso Remoto
  43. if((procesoHandle=OpenProcess(PROCESS_ALL_ACCESS,0,pid))==NULL)
  44. {
  45. printf("%s\n","Error al abrir proceso remoto");
  46. return 0;
  47. }
  48.  
  49. //Inicializo estructura
  50. user32=LoadLibrary("User32.dll");
  51. data.MessageBoxInj=(DWORD)GetProcAddress(user32,"MessageBoxA");
  52. strcpy(data.text,"Hola");
  53. strcpy(data.caption,"Hola");
  54. data.buttons=MB_OKCANCEL|MB_ICONQUESTION;
  55.  
  56. //Tamano de la funcion en bytes
  57.  
  58. size_FuncionInyectar=(PBYTE)Useless - (PBYTE)FuncionInyectar;
  59.  
  60. //Reservo espacio en proceso remoto para la funcion
  61.  
  62. MyFuncAddress=VirtualAllocEx(procesoHandle,NULL,size_FuncionInyectar,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  63. if(MyFuncAddress==NULL)
  64. {
  65. printf("%s\n","Error al reservar memoria para la funcion en el proceso remoto");
  66. return 0;
  67. }
  68.  
  69. printf("Direccion Funcion:%p \n %d Bytes reservados \n",MyFuncAddress,sizeof(PARAMETROS));
  70.  
  71.  
  72. //Reservo espacio en proceso remoto para los parametros de la funcion
  73.  
  74. parametrosAddress=VirtualAllocEx(procesoHandle,NULL,sizeof(PARAMETROS),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
  75. if(parametrosAddress==NULL)
  76. {
  77. printf("%s\n","Error al reservar memoria para los parametros de la funcion en el proceso remoto");
  78. return 0;
  79. }
  80. printf("Direccion Parametros:%p \n %d Bytes reservados \n",parametrosAddress,sizeof(PARAMETROS));
  81.  
  82. //Escribo en los espacios reservados
  83. //1.Funcion
  84. if(WriteProcessMemory(procesoHandle,MyFuncAddress,(void*)FuncionInyectar,size_FuncionInyectar,NULL)!=0)
  85. {
  86. printf("%s\n","Error al escribir la funcion en el proceso remoto");
  87. printf("%d\n",GetLastError());
  88. return 0;
  89. }
  90. //2.Parametros
  91. if(WriteProcessMemory(procesoHandle,parametrosAddress,&data,sizeof(PARAMETROS),NULL)!=0)
  92. {
  93. printf("%s\n","Error al escribir los parametros en el proceso remoto");
  94. return 0;
  95. }
  96.  
  97. //OK!Perfecto!Reservamos y Escribimos en el proceso remoto!Ahora a ejecutar un hilo!
  98.  
  99. if((hilo=CreateRemoteThread(procesoHandle,NULL,0,(LPTHREAD_START_ROUTINE)MyFuncAddress,parametrosAddress,0,NULL))==NULL)
  100. {
  101. printf("%s\n","Error al crear hilo remoto!");
  102. return 0;
  103. }
  104. printf("%s\n","Se inyecto el codigo");
  105.  
  106. return 0;
  107. }
  108.  
  109. /****************************Funciones*************************/
  110. int obtenerPID(char *nombreArchivo)
  111. {
  112. HANDLE snapshotProcesos=NULL;
  113. PROCESSENTRY32 estructuraProceso;
  114.  
  115. estructuraProceso.dwSize=sizeof(PROCESSENTRY32);
  116. if(snapshotProcesos=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0))
  117. {
  118. do
  119. {
  120. if(Process32Next(snapshotProcesos,&estructuraProceso))
  121. {}
  122. else
  123. {
  124. CloseHandle(snapshotProcesos);
  125. return -1;
  126. }
  127. }
  128. while(strcmp(estructuraProceso.szExeFile,nombreArchivo)!=0);
  129. CloseHandle(snapshotProcesos);
  130. return (int)estructuraProceso.th32ProcessID;
  131. }
  132. }
  133.  
  134. DWORD FuncionInyectar(PARAMETROS* myparam)
  135. {
  136. MessageBoxParam MsgBox = (MessageBoxParam)myparam->MessageBoxInj;
  137.  
  138. int result = MsgBox(0,myparam->text,myparam->caption,myparam->buttons);
  139.  
  140. switch(result)
  141. {
  142. case IDOK:
  143. break;
  144. case IDCANCEL:
  145. break;
  146. }
  147. return 0;
  148.  
  149. }
  150.  
  151. DWORD Useless()
  152. {
  153. return 0;
  154. }
  155.  
  156. int privilegios(){
  157. HANDLE Token;
  158. TOKEN_PRIVILEGES tp;
  159. if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token))
  160. {
  161.    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
  162.    tp.PrivilegeCount = 1;
  163.    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  164.    if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL)==0){
  165.    return 1;
  166.    }else{
  167.    return 0;
  168.   }
  169. }    
  170. return 1;
  171. }
  172.  
  173.  
  174.  


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: Eternal Idol en 9 Agosto 2014, 19:32 pm
if(WriteProcessMemory(procesoHandle,MyFuncAddress,(void*)FuncionInyectar,size_FuncionInyectar,NULL)!=0)

Esta mal la condicion, cuando retorna 0 es que fallo.

PD. Ya vi el mensaje (aunque use notepad.exe), cambiando las dos comprobaciones de WriteProcessMemory.


Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: dRak0 en 9 Agosto 2014, 20:09 pm
Que error mas tonto jeje.  :P

Te funciono el CreateRemoteThread()?Me tira error 5 , osea AccesoDenegado. Puede ser que sea por que lo estoy corriendo en WIN7 x64 .Lei que algunos tienen el mismo problema , pero en win8 corre bien.

Edito:
En win7 x64 me tira acceso denegado.
En win xp sp3 x86 funciona bien.
En win xp sp 2 x86 funciona bien.
En win xp x86 funciona bien.

Gracias!

PD:Conoces algun buen libro orientado a la API de windows? De teoria de windows toy leyendo Windows Internals 6.Aunque tiene practica , no es sobre la api de windows.

PD2:Perdon por las molestias , soy mas de unix , unix like. Poseo poco conocimiento en windows , pero estoy tratando de aprender.



Título: Re: [Consulta] campo del struct MODULEENTRY32
Publicado por: Eternal Idol en 9 Agosto 2014, 21:05 pm
Que error mas tonto jeje.  :P

Te funciono el CreateRemoteThread()?Me tira error 5 , osea AccesoDenegado. Puede ser que sea por que lo estoy corriendo en WIN7 x64 .Lei que algunos tienen el mismo problema , pero en win8 corre bien.

Edito:
En win7 x64 me tira acceso denegado.
En win xp sp3 x86 funciona bien.
En win xp sp 2 x86 funciona bien.
En win xp x86 funciona bien.

Gracias!

PD:Conoces algun buen libro orientado a la API de windows? De teoria de windows toy leyendo Windows Internals 6.Aunque tiene practica , no es sobre la api de windows.

PD2:Perdon por las molestias , soy mas de unix , unix like. Poseo poco conocimiento en windows , pero estoy tratando de aprender.



Si, aunque yo lo probe con el notepad, tal vez sea cosa de diferentes sesiones (el proceso puede ser un servicio) ... o tal vez estas tratando de trabajar con un proceso de 64 bits y tu programa es de 32 bits ... si es asi proba generando un ejecutable de 64 bits.

Solo conozco el "Windows via C/C++" de Jeffrey Richter.