2008/07/28 15:44
Base Relocation Demystified(기준재배치의 신비를 벗겨버리자)
typedef struct _IMAGE_FIXUP_ENTRY {
WORD offset:12;
WORD type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
DWORD
FindKiServiceTable(HMODULE hModule, DWORD dwKeSDTOffset)
{
PIMAGE_NT_HEADERS NtHeaders = NULL;
PIMAGE_BASE_RELOCATION ImageBaseReloc = NULL;
PIMAGE_FIXUP_ENTRY ImageFixup = NULL;
DWORD RelocTableSize = 0;
DWORD i;
DWORD dwVirtualAddress;
DWORD dwRva;
DWORD dwKiServiceTable = 0;
NtHeaders = RtlImageNtHeader( hModule );
ImageBaseReloc = (PIMAGE_BASE_RELOCATION)RtlImageDirectoryEntryToData( (PVOID)hModule,
TRUE,
IMAGE_DIRECTORY_ENTRY_BASERELOC,
&RelocTableSize );
if ( NULL == ImageBaseReloc ) {
return 0;
}
do {
ImageFixup = (PIMAGE_FIXUP_ENTRY)((DWORD)ImageBaseReloc + sizeof(IMAGE_BASE_RELOCATION));
for ( i = 0;
i < ( ImageBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) ) >> 1;
i++, ImageFixup++ ) {
if ( ImageFixup->type == IMAGE_REL_BASED_HIGHLOW ) {
dwVirtualAddress = ImageBaseReloc->VirtualAddress + ImageFixup->offset;
dwRva = *(PDWORD)((DWORD)hModule+dwVirtualAddress) - (DWORD)NtHeaders->OptionalHeader.ImageBase;
if ( dwRva == dwKeSDTOffset ) {
if (*(PWORD)((DWORD)hModule + dwVirtualAddress-2) == 0x05c7) {
dwKiServiceTable = *(PDWORD)((DWORD)hModule +
dwVirtualAddress+4) - NtHeaders->OptionalHeader.ImageBase;
return dwKiServiceTable;
}
}
}
}
*(PDWORD)&ImageBaseReloc += ImageBaseReloc->SizeOfBlock;
} while ( ImageBaseReloc->VirtualAddress );
return 0;
}

