Опираясь на это,хочу получить список dll, которые использует каждый процесс. Я использую stl list, где каждая нода имеет вот такие поля:
struct info
{
wchar_t name_PID[100]; // the name of process
//maybe DWORD not unsigned
unsigned num_PID; // the id of the proc
char* path;// the way like C://
char par_name[100]; // the name of parent
unsigned num_par_PID;// the id of the parent
char ownerName[256]="\0"; // host/adm/elv
char* SID;
unsigned x_bit;
//bool DEP;
char DEP[4];
//bool ASLR;
char ASLR[4];
};
На момент выполнения этой функции(которая ищет dll у процесса), все представленные поля заполнены. Вот так выглядит вариант из документации Microsoft:
int main( void )
{
DWORD aProcesses[1024];
DWORD cbNeeded;
DWORD cProcesses;
unsigned int i;
// Get the list of process identifiers.
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return 1;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the names of the modules for each process.
for ( i = 0; i < cProcesses; i++ )
{
PrintModules( aProcesses[i] );
}
return 0;
}
По аналогии и я пишу свою функцию:
void about_dll(list <info>& gqlist)
{
list <info> ::iterator lit;
DWORD* mass;
DWORD cbNeeded, cProcesses;
mass = (DWORD*)malloc(1*sizeof(DWORD));
int i = 0;
for (lit = gqlist.begin(); lit != gqlist.end(); ++lit)
{
mass[i] = lit->num_PID;
mass = (DWORD*)realloc(mass, sizeof(DWORD)*(i + 2));
i++;
}
int k = 0;
EnumProcesses(mass, sizeof(mass)*i, &cbNeeded);
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
for (i = 0; i < cProcesses; i++)
{
//PrintModules(aProcesses[i]);
about_dll2(mass[i]);
}
}
Я пробегаю по каждому элементу списка, чтобы записать в новый массив mass
(который динамический) номер процесса. Это нужно для функции EnumProcesses
, которая после исполнения изменит содержимое cbNeeded
. Его я использую, для цикла (ровно как и в примере).
В документации вызывают из цикла функцию(в их примере из сайта):
int PrintModules( DWORD processID )
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Get a handle to the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return 1;
// Get a list of all the modules in this process.
if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.
if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
{
// Print the module name and handle value.
_tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
}
}
}
// Release the handle to the process.
CloseHandle( hProcess );
return 0;
}
Теперь и я вызываю about_dll2 каждый раз из цикла.
void about_dll2(DWORD processID)
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, processID);
// Get a list of all the modules in this process.
if (NULL == hProcess)
return;
//GetModuleHandleExA(NULL, "chrome.exe", hMods);
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.
if (GetModuleFileNameEx(hProcess, hMods[i], szModName,sizeof(szModName) / sizeof(TCHAR)))
{
// Print the module name and handle value.
_tprintf(TEXT("\t%s (0x%08X)\n"), szModName, hMods[i]);
}
}
}
}
Но возникает несколько трудностей:
if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
никогда не выполняется.Последнее и есть причина моего вопроса - почему эта функция в if возвращает 0?
Я подумал, что дело может быть в неинициализированном hMods
. Поэтому захотел инициализировать её(неудачно). Мне показалось, что GetModuleHandleExA
должен иницилизировать этот hMods
, но вышло так , что приходится самому называть эту dll, а я наоборот хочу узнать dll.
Таким образом, более общий вопрос задать так: Как узнать, какие dll использует процесс? А поконкретнее - описал выше. Может я вообще не в ту сторону иду с описанной выше идеей?
Вопрос решился использованием Module32First и Module32Next. Всё оказалось очень тривиально, даже мануал нашел тут. В общем решение у меня выглядит так:
void about_dll(list <info>& gqlist)
{
list <info> ::iterator it;
HANDLE hSnap;
for (it = gqlist.begin(); it != gqlist.end(); ++it)
{
int i = 0;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, it->num_par_PID);
if (hSnap == NULL)
{
continue;
}
else
{
memset(it->DLL[i], 0, 30);
MODULEENTRY32 mod;
if (Module32First(hSnap, &mod))
{
//m_List1.AddString(mod.szExePath);
char k1[30]="\0";
sprintf(k1, "%s", mod.szModule);
if (!strstr(k1, "exe"))
{
sprintf(it->DLL[i], "%s", mod.szModule);
i++;
memset(it->DLL[i], 0, 30);
}
while (Module32Next(hSnap, &mod))
{
//m_List1.AddString(mod.szExePath);
if (strstr(mod.szModule, "exe"))
continue;
sprintf(it->DLL[i], "%s", mod.szModule);
i++;
memset(it->DLL[i], 0, 30);
}
}
CloseHandle(hSnap);
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Почему 2 std::istream_iterator считаются одинаковыми, даже если они указывают на разные элементы одного потока? С чем связано такое определение?
есть такой вопрос, хочу сделать UPDATE запрос к базе данных, для этого нужно подготовить запрос, но помимо подстановки данных, я хочу подставить...
есть указатель на массив объектов s и указатель на s