Z teoretycznego punktu widzenia gdy otworzymy proces z flagami PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE | PROCESS_VM_READ lub PROCESS_ALL_ACCESS mozliwe bedzie modygikowanie pamieci wirtualnej procesu a tym samym modyfikowanie stron bibliotek systemowych zmapowanych na obszar procesu! Naturalnie w pierw wypadalo by zmienic prawa do strony ktora chcemy zmodyfikowac. Windows stosuje pewna sztuczke ktora chroni biblioteki przed modyfikacja ich przez dowolny proces. Dlatego jesli bedziemy chcieli zmodyfikowac strone wowczas uzyska ona atrybut PAGE_WRITECOPY - czyli zmodyfikujemy wylacznie zkopiowana strone w obrebie procesu modyfikujacego strone. Dzieki VirtualProtect mozemy jednak zmienic wpierw atrybut strony na PAGE_READWRITE i dzieki temu zmodyfikowana strona faktycznie zostanie zmieniona! Wlasciwosc ta wykorzystuja rozne narzedzia oraz szkodniki do filtrowania roznych funkcji. Skoro tzw. inline hooking jest najskuteczniejszy i ma zasieg globalny zasieg postanowilem wykorzystac go do monitorowania funkcji OpenProcess. Dzieki temu moglbym blokowac niechciane procesy! Wszystko pieknie tylko z praktycznego punktu widzenia za kazdym razem kiedy probuje ustawic prawo do zapisu dla strony uzyskuje w rezultacie PAGE_WRITECOPY albo PAGE_EXECUTE_WRITECOPY. Do tematu zamieszczam program testowy ktory pokazuje prawo do strony przed proba modyfikacji i po.
#include<stdio.h>
#include<windows.h>
int main(int argc, char *argv[])
{
PVOID MessageBoxExW;
DWORD Status;
HANDLE ProcessHandle;
DWORD ProcessId;
ULONG OldProtect;
MEMORY_BASIC_INFORMATION mbi;
MessageBoxExW = (PVOID)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxExW");
printf(" MessageBoxExW: 0x%.8X\n", MessageBoxExW);
__asm
{
mov eax, fs:0x18
mov eax, [eax+0x20]
mov dword ptr ProcessId, eax
}
printf(" ProcessId: %.8d\n", ProcessId);
ProcessHandle = OpenProcess(
PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
ProcessId);
printf(" ProcessHandle: 0x%.8X\n\n", ProcessHandle);
Status = VirtualQueryEx(
ProcessHandle,
(PVOID)MessageBoxExW,
&mbi,
sizeof(MEMORY_BASIC_INFORMATION));
printf(" VirtualQueryEx Status: 0x%.8X\n", Status);
printf(" Protect 1: 0x%.2X\n", mbi.Protect);
Status = VirtualProtectEx(
ProcessHandle,
(PDWORD)mbi.BaseAddress,
mbi.RegionSize,
PAGE_READWRITE,
&OldProtect);
printf(" VirtualProtectEx Status: 0x%.8X\n\n", Status);
Status = VirtualQueryEx(
ProcessHandle,
(PVOID)MessageBoxExW,
&mbi,
sizeof(MEMORY_BASIC_INFORMATION));
printf(" VirtualQueryEx Status: 0x%.8X\n", Status);
printf(" Protect 2: 0x%.2X\n", mbi.Protect);
Status = VirtualProtectEx(
ProcessHandle,
(PVOID)MessageBoxExW,
sizeof(DWORD),
OldProtect,
&OldProtect);
printf(" VirtualProtectEx Status: 0x%.8X\n", Status);
system("PAUSE");
return 0;
}
Oraz gotowy program: Binarka