Странная ошибка, или где-то затупил или что. Есть простой код Код (C++): LPVOID lpFunc = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateFileW"); DWORD dwProtect = PAGE_READWRITE; VirtualProtect(lpFunc, 5, dwProtect, &dwProtect); который ес-но работает норм. Но - если поменять на NTDLL.NtCreateFile, файл падает в access_violation именно на вызове VirtualProtect. Причем, такое только в ЕХЕ, скомпилированном студией, на масме все гуд. WriteProcessMemory помогает, но все же, интересно что это за мистика. В аттаче оба ехе файла, код такой Код (C): #include <windows.h> int e_p() { LPVOID lpFunc = GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtCreateFile"); DWORD dwProtect = PAGE_READWRITE; VirtualProtect(lpFunc, 5, dwProtect, &dwProtect); // WriteProcessMemory(GetCurrentProcess(), lpFunc, "abc", 3, &dwProtect); ExitProcess(1); } Как собирать - без разницы, хоть с командной строки хоть со студии, один черт падает. --- Сообщение объединено, 27 дек 2021 --- Думаю ошибка в том, что VirtualProtect не 5 байтов, которые мне надо, меняет права, а на целую страницу. И какие-то натив апи функции из-за этого не работают. Однако странно, что в масм все норм, NTDLL же в обоих процессах одинаков.
Вероятно при обработке каких-нибудь структур цэ-ехешника при завершении процесса таки вызывается NtCreateFile, которому ты PAGE_READWRITE (вместо PAGE_EXECUTE_READWRITE) запретил исполняться.
f13nd, оно крешится именно на вызове VirtualProtect. Потом я возвращаю oldProtect, но до того не доходит.
Ну вот этот кажется вполне логичным вариантом. Так ты посмотри, попадает ли адрес, на котором случается аксес вайолейшн, в твою страницу.
Я заменяю на ntdll.dll/NtCreateFile и VirtualProtect возвращает 1 и ERROR_SUCCESS. Зато какой-то анус в ExitProcess происходит.
M0rg0t, изменяются атрибуты всей страницы в этом и проблема. Ты меняешь атрибуты и при возврате из функции NtProtectVirtualMemory (если это WOW64) или сервиса если это syscall/sysenter начинают исполняться инструкции на RW странице. В этом и ошибка. --- Сообщение объединено, 27 дек 2021 --- Добавлю что оба exe с ошибкой валяться, второй валится в недрах ExitProcess по той же причине.
Спасибо всем за ответы. Все решается флагом PAGE_EXECUTE_READWRITE либо WriteProcessMemory (хотя эта функция вроде как тоже юзает VirtualProtect внутри ?).
Так а зачем тебе WriteProcessMemory вообще, ты же память собственного процесса пишешь, не? Мог бы и memcpy сделать, или просто байты по указателю проставить.
Rel, там страница read_only, точнее EXECUTE_READ, потому и юзал VirtualProtect. А WriteProcessMemory может писать по таким страницам , т.к. внутри себя вызывает VirtualProtect.
NtProtectVirtualMemory, но она юзает с умом, передает флаг PAGE_EXECUTE_READWRITE. Также вызывает NtFlushInstructionCache.