|
|
#include "precomp.h"
#include <tlhelp32.h>
#ifndef MYASSERT
#define MYASSERT(x)
#endif
typedef HANDLE (WINAPI * CREATETOOLHELP32SNAPSHOT)(DWORD Flags, DWORD ProcessId); typedef BOOL (WINAPI * MODULE32FIRST)(HANDLE Snapshot, LPMODULEENTRY32 lpme); typedef BOOL (WINAPI * MODULE32NEXT)(HANDLE Snapshot, LPMODULEENTRY32 lpme);
BOOL pIsLegalPage ( IN DWORD Protect ) { //
// Page must be actually in memory to protect it, and it
// cannot be any type of write-copy.
//
if ((Protect & PAGE_GUARD) || (Protect == PAGE_NOACCESS) || (Protect == PAGE_WRITECOPY) || (Protect == PAGE_EXECUTE_WRITECOPY) ) { return FALSE; }
return TRUE; }
BOOL pIsKnownSection ( IN const IMAGE_SECTION_HEADER *Section, IN const IMAGE_NT_HEADERS *NtHeaders ) { //
// Return TRUE if section is code or code data
//
if (Section->Characteristics & (IMAGE_SCN_MEM_EXECUTE| IMAGE_SCN_MEM_DISCARDABLE| IMAGE_SCN_MEM_WRITE| IMAGE_SCN_MEM_READ) ) { return TRUE; }
//
// Return TRUE if section is resources
//
if (NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress == Section->VirtualAddress ) { return TRUE; }
//
// Unknown section
//
return FALSE; }
VOID pPutRegionInSwapFile ( IN PVOID Address, IN DWORD Size ) { MEMORY_BASIC_INFORMATION mbi; DWORD PageSize; PVOID EndPtr; PVOID RegionEnd; DWORD d; DWORD OldPermissions; volatile DWORD *v; SYSTEM_INFO si;
//
// Get system virtual page size
//
GetSystemInfo(&si); PageSize = si.dwPageSize;
//
// Compute the pointer to the end of the region
//
EndPtr = (PBYTE) Address + Size;
//
// For each page in the region, mark it as e/r/w, modify it, and restore the permissions
//
while (Address < EndPtr) {
d = (DWORD)VirtualQuery (Address, &mbi, sizeof(mbi));
if (d == sizeof(mbi)) {
//
// We assume the module wasn't loaded with one of the following
// conditions (which break as a result of VirtualProtect)
//
RegionEnd = (PBYTE) mbi.BaseAddress + mbi.RegionSize;
if (RegionEnd > EndPtr) { RegionEnd = EndPtr; }
if (mbi.State == MEM_COMMIT && pIsLegalPage (mbi.Protect)) {
//
// Switch to e/r/w
//
if (VirtualProtect ( mbi.BaseAddress, (PBYTE) RegionEnd - (PBYTE) mbi.BaseAddress, PAGE_EXECUTE_READWRITE, &OldPermissions )) {
//
// Touch every page in the region.
//
for (Address = mbi.BaseAddress; Address < RegionEnd ; Address = (PBYTE) Address + PageSize) { v = Address; *v = *v; }
//
// Switch back
//
VirtualProtect ( mbi.BaseAddress, (PBYTE) RegionEnd - (PBYTE) mbi.BaseAddress, OldPermissions, &d ); } }
Address = RegionEnd;
} else { MYASSERT (FALSE); break; } } }
VOID pProtectModule ( HANDLE Module ) { TCHAR Path[MAX_PATH]; BOOL IsNetDrive; const IMAGE_DOS_HEADER *DosHeader; const IMAGE_NT_HEADERS *NtHeaders; const IMAGE_SECTION_HEADER *SectHeader; UINT u;
IsNetDrive = FALSE;
//
// Get module info
//
if( MyGetModuleFileName (Module, Path, MAX_PATH)){
//
// Determine if the module is running on the net
//
if (Path[0] == TEXT('\\')) { IsNetDrive = TRUE; } else if (GetDriveType (Path) == DRIVE_REMOTE) { IsNetDrive = TRUE; }
}
if (!IsNetDrive) { return; }
//
// Enumerate all sections in the PE header
//
DosHeader = (const IMAGE_DOS_HEADER *) Module; NtHeaders = (const IMAGE_NT_HEADERS *) ((PBYTE) Module + DosHeader->e_lfanew);
for (u = 0 ; u < NtHeaders->FileHeader.NumberOfSections ; u++) { SectHeader = IMAGE_FIRST_SECTION (NtHeaders) + u;
if (pIsKnownSection (SectHeader, NtHeaders)) { pPutRegionInSwapFile ( (PBYTE) Module + SectHeader->VirtualAddress, SectHeader->Misc.VirtualSize ); } } }
VOID ProtectAllModules ( VOID ) { HANDLE Library; HANDLE Snapshot; MODULEENTRY32 me32; CREATETOOLHELP32SNAPSHOT fnCreateToolhelp32Snapshot; MODULE32FIRST fnModule32First; MODULE32NEXT fnModule32Next;
//
// Load toohelp dynamically (for NT 4, NT 3.51 compatibility)
//
Library = LoadLibrary (TEXT("toolhelp.dll")); if (!Library) { return; }
(FARPROC) fnCreateToolhelp32Snapshot = GetProcAddress (Library, "CreateToolhelp32Snapshot"); (FARPROC) fnModule32First = GetProcAddress (Library, "Module32First"); (FARPROC) fnModule32Next = GetProcAddress (Library, "Module32Next");
if (!fnCreateToolhelp32Snapshot || !fnModule32First || !fnModule32Next) { FreeLibrary (Library); return; }
//
// Protect each loaded module
//
Snapshot = fnCreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); MYASSERT (Snapshot != INVALID_HANDLE_VALUE);
if (Snapshot == INVALID_HANDLE_VALUE) { return; }
me32.dwSize = sizeof (me32); if (fnModule32First (Snapshot, &me32)) { do { pProtectModule (me32.hModule); } while (fnModule32Next (Snapshot, &me32)); }
//
// Done
//
CloseHandle (Snapshot);
FreeLibrary (Library); }
|