[Consulta] campo del struct MODULEENTRY32

Iniciado por dRak0, 8 Agosto 2014, 13:06 PM

0 Miembros y 6 Visitantes están viendo este tema.

dRak0

Tenia algo de tiempo y me puse a repasar algunas cosas

Aca el codigo:


HANDLE snapshot,snapshotModule=NULL;

PROCESSENTRY32 processEntry;
MODULEENTRY32 moduleEntry;
if((snapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0))==NULL){
printf("\n%s","FAIL!!!!SNAPSHOTCREATE");
return 0;

}

processEntry.dwSize=sizeof(PROCESSENTRY32);
moduleEntry.dwSize=sizeof(MODULEENTRY32);

while(Process32Next(snapshot,&processEntry)==TRUE)
{
printf("\nPID:%d\nExe:%s\n",processEntry.th32ProcessID,processEntry.szExeFile);
if(snapshotModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processEntry.th32ProcessID))
{
while(Module32Next(snapshotModule,&moduleEntry)==TRUE)
printf("%s %s %d\n",moduleEntry.szModule,moduleEntry.szExePath,moduleEntry.th32ProcessID);
}
}

return 0;




->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.

Eternal Idol

#1
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.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dRak0

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!

Eternal Idol

Poniendo antes del while:
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.

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dRak0

#4
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.



while(Process32Next(snapshot,&processEntry)==TRUE)
{
printf("\nPID:%d\nExe:%s\n",processEntry.th32ProcessID,processEntry.szExeFile);


if(snapshotModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processEntry.th32ProcessID))
{
ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
moduleEntry.dwSize=sizeof(MODULEENTRY32);
while(Module32Next(snapshotModule,&moduleEntry)==TRUE)
printf("%s %s %d\n",moduleEntry.szModule,moduleEntry.szExePath,moduleEntry.th32ProcessID);

}
}


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.

Eternal Idol

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.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dRak0

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.

Eternal Idol

#7
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.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dRak0

#8

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

struct PARAMETROS{
DWORD MessageBoxInj;
char text[4];
char caption[4];
int buttons;
};

typedef struct PARAMETROS PARAMETROS;
int obtenerPID(char*);
int privilegios();
typedef int (WINAPI* MessageBoxParam)(HWND,LPCSTR,LPCSTR,UINT);
DWORD FuncionInyectar(PARAMETROS* myparam);
DWORD Useless();


/****************************COMIENZO MAIN!*******************************/

int main(int argc,char **argv)
{
HANDLE procesoHandle,hilo=NULL;
PARAMETROS data;
char *mytext="Hola";
char *mycaption="Hola";
HMODULE user32=NULL;
DWORD size_FuncionInyectar;
LPVOID MyFuncAddress,parametrosAddress=NULL;
int privilegio;


//Obtengo PID
int pid=obtenerPID("sublime_textSinASLR.exe");
printf("PID:%d\n",pid);

//Privilegios
privilegio=privilegios();
printf("Privilegios%d\n",privilegio);

//Obtengo handle del proceso Remoto
if((procesoHandle=OpenProcess(PROCESS_ALL_ACCESS,0,pid))==NULL)
{
printf("%s\n","Error al abrir proceso remoto");
return 0;
}

//Inicializo estructura
user32=LoadLibrary("User32.dll");
data.MessageBoxInj=(DWORD)GetProcAddress(user32,"MessageBoxA");
strcpy(data.text,"Hola");
strcpy(data.caption,"Hola");
data.buttons=MB_OKCANCEL|MB_ICONQUESTION;

//Tamano de la funcion en bytes

size_FuncionInyectar=(PBYTE)Useless - (PBYTE)FuncionInyectar;

//Reservo espacio en proceso remoto para la funcion

MyFuncAddress=VirtualAllocEx(procesoHandle,NULL,size_FuncionInyectar,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(MyFuncAddress==NULL)
{
printf("%s\n","Error al reservar memoria para la funcion en el proceso remoto");
return 0;
}

printf("Direccion Funcion:%p \n %d Bytes reservados \n",MyFuncAddress,sizeof(PARAMETROS));


//Reservo espacio en proceso remoto para los parametros de la funcion

parametrosAddress=VirtualAllocEx(procesoHandle,NULL,sizeof(PARAMETROS),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
if(parametrosAddress==NULL)
{
printf("%s\n","Error al reservar memoria para los parametros de la funcion en el proceso remoto");
return 0;
}
printf("Direccion Parametros:%p \n %d Bytes reservados \n",parametrosAddress,sizeof(PARAMETROS));

//Escribo en los espacios reservados
//1.Funcion
if(WriteProcessMemory(procesoHandle,MyFuncAddress,(void*)FuncionInyectar,size_FuncionInyectar,NULL)!=0)
{
printf("%s\n","Error al escribir la funcion en el proceso remoto");
printf("%d\n",GetLastError());
return 0;
}
//2.Parametros
if(WriteProcessMemory(procesoHandle,parametrosAddress,&data,sizeof(PARAMETROS),NULL)!=0)
{
printf("%s\n","Error al escribir los parametros en el proceso remoto");
return 0;
}

//OK!Perfecto!Reservamos y Escribimos en el proceso remoto!Ahora a ejecutar un hilo!

if((hilo=CreateRemoteThread(procesoHandle,NULL,0,(LPTHREAD_START_ROUTINE)MyFuncAddress,parametrosAddress,0,NULL))==NULL)
{
printf("%s\n","Error al crear hilo remoto!");
return 0;
}
printf("%s\n","Se inyecto el codigo");

return 0;
}

/****************************Funciones*************************/
int obtenerPID(char *nombreArchivo)
{
HANDLE snapshotProcesos=NULL;
PROCESSENTRY32 estructuraProceso;

estructuraProceso.dwSize=sizeof(PROCESSENTRY32);
if(snapshotProcesos=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0))
{
do
{
if(Process32Next(snapshotProcesos,&estructuraProceso))
{}
else
{
CloseHandle(snapshotProcesos);
return -1;
}
}
while(strcmp(estructuraProceso.szExeFile,nombreArchivo)!=0);
CloseHandle(snapshotProcesos);
return (int)estructuraProceso.th32ProcessID;
}
}

DWORD FuncionInyectar(PARAMETROS* myparam)
{
MessageBoxParam MsgBox = (MessageBoxParam)myparam->MessageBoxInj;

int result = MsgBox(0,myparam->text,myparam->caption,myparam->buttons);

switch(result)
{
case IDOK:
break;
case IDCANCEL:
break;
}
return 0;

}

DWORD Useless()
{
return 0;
}

int privilegios(){
HANDLE Token;
TOKEN_PRIVILEGES tp;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token))
{
   LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
   tp.PrivilegeCount = 1;
   tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
   if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL)==0){
   return 1;
   }else{
   return 0;
  }
}    
return 1;
}



Eternal Idol

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.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón