Когда мой код вызывает GetAllModulesInfoOfPID(второй блок), который внутренне вызывает CreateToolhelp32Snapshot (первый блок) для получения информации о модуле процесс, идентифицируемый его PID, CreateToolhelp32Snapshot возвращает INVALID_HANDLE_VALUE с кодом ошибки 0x5 (Доступ запрещен). Однако если я закомментирую вызов GetRDataSectionBaseAddress (последний блок), последующая функция GetAllModulesInfoOfPID (которая использует CreateToolhelp32Snapshot) выполнится без ошибок.
Код: Выделить всё
char** GetAllModulesInfoOfPID(DWORD PID, int* numModules) {
//CreateToolHelp32Snapshot is powerfull
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PID);
if (hSnapshot == INVALID_HANDLE_VALUE) {
switch (GetLastError()){
case 5:
warn("PID: %-6d, Denied Access", PID);
break;
case 299:
warn("PID: %-6d, Error Memory Management", PID);
break;
default:
warn("PID: %-6d, [CreateToolhelp32Snapshot] failed to get handle, Error: %lx", GetLastError());
break;
}
*numModules = 0;
return nullptr;
}
//...
Код: Выделить всё
if (processList) {
info("Writing in list_MODULES_imports:");
for (int i = 0; i < numProcesses; i++) {
int numModules = 0;
char** moduleNames = GetAllModulesInfoOfPID(processList[i].pid, &numModules);
if (moduleNames) {
// If you call get_all_modules_info_of_PID and GetRDataSectionBaseAddress it'll denies access magically
for (int j = 0; j < numModules; ++j) {
fprintf(outputFile, "%s (%d), %s\n", moduleNames[0], processList[i].pid, moduleNames[j]);
//get_exported_functions(processList[i].pid, processList[i].processName);
}
free_module_names(moduleNames, numModules);
} else {
//pass
}
}
} else { return false; }
Код: Выделить всё
LPVOID GetRDataSectionBaseAddress(DWORD PID, const char* moduleName) {
info("[GetRDataSectionBaseAddress] call");
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
if (hProcess == NULL) {
warn("[OpenProcess] failed to get handle to %d. Error: %lx", PID, GetLastError());
return nullptr;
}
HMODULE hModules[1024];
DWORD cbNeeded;
if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) {
warn("[EnumProcessModules] failed to list modules. Error: %lx", GetLastError());
CloseHandle(hProcess);
return NULL;
}
HMODULE hModule = NULL;
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
char szModuleName[MAX_PATH];
if (GetModuleBaseNameA(hProcess, hModules[i], szModuleName, sizeof(szModuleName))) {
if (_stricmp(szModuleName, moduleName) == 0) {
hModule = hModules[i];
break;
}
}
}
if (hModule == NULL) {
warn("[GetModuleBaseNameA] failed to get name of module. Error: %lx", GetLastError());
CloseHandle(hProcess);
return NULL;
}
MODULEINFO moduleInfo;
if (!GetModuleInformation(hProcess, hModule, &moduleInfo, sizeof(moduleInfo))) {
warn("[GetModuleInformation] failed to get info about module. Error: %lx", GetLastError());
CloseHandle(hProcess);
return NULL;
}
BYTE* moduleBase = reinterpret_cast(moduleInfo.lpBaseOfDll);
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast
(moduleBase);
PIMAGE_NT_HEADERS ntHeaders = reinterpret_cast(moduleBase + dosHeader->e_lfanew);
PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeaders);
for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
if (strncmp(reinterpret_cast(sectionHeader->Name), ".rdata", IMAGE_SIZEOF_SHORT_NAME) == 0) {
LPVOID rdataBaseAddress = moduleBase + sectionHeader->VirtualAddress;
CloseHandle(hProcess);
okay("Got base address of .rdata");
return rdataBaseAddress;
}
sectionHeader++;
}
warn("Failed to get .rdata base address");
CloseHandle(hProcess);
return NULL;
}
Код: Выделить всё
if (processList) {
info("Writing in list_importExport_table:");
for (int i = 0; i < numProcesses; i++) {
if (contains_exe(processList[i].processName)){
//system("pause");
info("Base Address of .rdata of PID %d: %p", processList[i].pid, GetRDataSectionBaseAddress(processList[i].pid, processList[i].processName));
} else {
warn("Something went wrong with %s (%d)", processList[i].processName, processList[i].pid);
}
}
} else { return false; }
fclose(outputFile);
okay("Operation Success!");
return true;
Я экспериментировал с различными разрешениями для OpenProcess (например, PROCESS_ALL_ACCESS, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ), но проблема сохраняется.
Такое поведение происходит постоянно, и другой аналогичный код, использующий NtOpenProcess, не сталкивается с проблемами доступа.
Я убедился, что все дескрипторы закрыты правильно и нет утечек ресурсов.
Что может быть причиной сбоя CreateToolhelp32Snapshot с сообщением «Доступ запрещен» только при вызове GetRDataSectionBaseAddress? Как я могу решить или дополнительно диагностировать эту проблему?
Я ожидаю, что CreateToolhelp32Snapshot успешно получит информацию о модуле процесса, даже если GetRDataSectionBaseAddress вызывается до GetAllModulesInfoOfPID .
Подробнее здесь: https://stackoverflow.com/questions/787 ... windows-11