VirtualProtect и kernel32.dll — попытка доступа к неверному адресу

Я анализирую различные модули, загруженные процессом. К сожалению, я не могу создать 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 правильный. В чем причина?

9

Решение

Довольно сложно проверить, что вы правильно указали адрес, он необычно низкий. Я просто написал другую программу, чтобы проверить это. Он перечисляет регионы в 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. Я использую минимальную защиту на моей машине.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]