Я анализирую различные модули, загруженные процессом. К сожалению, я не могу создать kernel32.dll
снимок памяти, хотя функция работает правильно с другими модулями (например, ntddl.dll
). Проблема в следующем коде:
/* Copy code from memory */
if (VirtualProtect((BYTE*)virtualAddress, sizeOfCode, PAGE_EXECUTE_READWRITE, &flags) == 0) {
std::cout << "VirtualProtect failed!" << std::endl;
std::cout << "Virtual address: " << virtualAddress << std::endl;
std::cout << "Size of code: " << sizeOfCode << std::endl;
std::cout << "Error code: " << GetLastError() << std::endl;
}
Результат вызова этого кода для kernel32.dll
является:
Virtual address: 747d0000
Size of code: 6a000
Error code: 0x1e7
Описание ошибки говорит о том, что:
ERROR_INVALID_ADDRESS
487 (0x1E7)
Attempt to access invalid address.
Я проверил карту памяти процесса и адрес kernel32.dll правильный. В чем причина?
Довольно сложно проверить, что вы правильно указали адрес, он необычно низкий. Я просто написал другую программу, чтобы проверить это. Он перечисляет регионы в kernel32.dll и вызывает VirtualProtect () для них:
#include <Windows.h>
#include <assert.h>
#include <iostream>int main()
{
HMODULE hmod = GetModuleHandle(L"kernel32.dll");
MEMORY_BASIC_INFORMATION info;
// Start at PE32 header
SIZE_T len = VirtualQuery(hmod, &info, sizeof(info));
assert(len > 0);
BYTE* dllBase = (BYTE*)info.AllocationBase;
BYTE* address = dllBase;
for (;;) {
len = VirtualQuery(address, &info, sizeof(info));
assert(len > 0);
if (info.AllocationBase != dllBase) break;
std::cout << "Address: " << std::hex << info.BaseAddress;
std::cout << " (" << std::hex << info.RegionSize << ") ";
std::cout << " protect = " << std::hex << info.Protect;
DWORD oldprotect;
if (info.Protect == 0) std::cout << ", VirtualProtect skipped" << std::endl;
else {
BOOL ok = VirtualProtect(info.BaseAddress, info.RegionSize, PAGE_EXECUTE_READWRITE, &oldprotect);
std::cout << ", VirtualProtect = " << (ok ? "okay" : "Failed!") << std::endl;
}
address = (BYTE*)info.BaseAddress + info.RegionSize;
}
return 0;
}
Вывод этой программы на мою машину под управлением Windows 8.1 x64:
Address: 77470000 (1000) protect = 2, VirtualProtect = okay
Address: 77471000 (f000) protect = 0, VirtualProtect skipped
Address: 77480000 (62000) protect = 20, VirtualProtect = okay
Address: 774E2000 (e000) protect = 0, VirtualProtect skipped
Address: 774F0000 (7e000) protect = 2, VirtualProtect = okay
Address: 7756E000 (2000) protect = 0, VirtualProtect skipped
Address: 77570000 (1000) protect = 4, VirtualProtect = okay
Address: 77571000 (f000) protect = 0, VirtualProtect skipped
Address: 77580000 (1000) protect = 2, VirtualProtect = okay
Address: 77581000 (f000) protect = 0, VirtualProtect skipped
Address: 77590000 (1a000) protect = 2, VirtualProtect = okay
Address: 775AA000 (6000) protect = 0, VirtualProtect skipped
Запуск его в 64-битном режиме:
Address: 00007FFC4F870000 (1000) protect = 2, VirtualProtect = okay
Address: 00007FFC4F871000 (112000) protect = 20, VirtualProtect = okay
Address: 00007FFC4F983000 (1000) protect = 4, VirtualProtect = okay
Address: 00007FFC4F984000 (1000) protect = 8, VirtualProtect = okay
Address: 00007FFC4F985000 (24000) protect = 2, VirtualProtect = okay
Очевидно, у вас другая версия Windows, поэтому обязательно запустите эту программу на своем компьютере, чтобы получить сопоставимые результаты.
Вывод, который я делаю, состоит в том, что нет фундаментальной причины для отказа такого рода кода. И если это происходит на вашей машине, то это, вероятно, будет экологическим. С очень очевидным кандидатом на роль вашего анти-вредоносного программного обеспечения, которое, конечно, имеет большое значение для предотвращения попадания кода в kernel32.dll. Я использую минимальную защиту на моей машине.
Других решений пока нет …