-
-
[求助]关于ntoskrnl.exe的重定位
-
发表于: 2008-10-8 01:43 4424
-
这个查找SSDT函数大家都熟悉吧,以前也用过,但没有细看,这几天看了看《加密解密3》的重定位那一节,有一处有点疑问,见代码
DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT)
{
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
PIMAGE_BASE_RELOCATION pbr;
PIMAGE_FIXUP_ENTRY pfe;
DWORD dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable;
BOOL bFirstChunk;
GetHeaders((PCHAR)hModule,&pfh,&poh,&psh);
// loop thru relocs to speed up the search
if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) &&
(!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED))) {
pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule);
bFirstChunk=TRUE;
// 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0
while (bFirstChunk || pbr->VirtualAddress) {
bFirstChunk=FALSE;
pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));
for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) {
if (pfe->type==IMAGE_REL_BASED_HIGHLOW) {
dwFixups++;
//这里得到重定位项的地址RVA
dwPointerRva=pbr->VirtualAddress+pfe->offset;
// DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed
//为什么*(PDWORD)((DWORD)hModule+dwPointerRva)是没有修正的值,不是应该重定位了吗?比如我自己加载的hModule地址是b50000,这里跟进去看*(PDWORD)((DWORD)hModule+dwPointerRva)是4XXXXX,显然比真实的装载地址b50000小,也就是还没有重定位
dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;
// does this reloc point to KeServiceDescriptorTable.Base?
if (dwPointsToRva==dwKSDT) {
//后面就好理解了
// check for mov [mem32],imm32. we are trying to find
// "mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable"
// from the KiInitSystem.
if (*(PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7) {
// should check for a reloc presence on KiServiceTable here
// but forget it
dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase;
return dwKiServiceTable;
}
}
}
// should never get here
}
*(PDWORD)&pbr+=pbr->SizeOfBlock;
}
}
return 0;
}
还有用Lordpe查看ntoskrnl.exe发现它的代码段起始地址是580,没有4K对齐,不解。。。。。
DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT)
{
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
PIMAGE_BASE_RELOCATION pbr;
PIMAGE_FIXUP_ENTRY pfe;
DWORD dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable;
BOOL bFirstChunk;
GetHeaders((PCHAR)hModule,&pfh,&poh,&psh);
// loop thru relocs to speed up the search
if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) &&
(!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED))) {
pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule);
bFirstChunk=TRUE;
// 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0
while (bFirstChunk || pbr->VirtualAddress) {
bFirstChunk=FALSE;
pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));
for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) {
if (pfe->type==IMAGE_REL_BASED_HIGHLOW) {
dwFixups++;
//这里得到重定位项的地址RVA
dwPointerRva=pbr->VirtualAddress+pfe->offset;
// DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed
//为什么*(PDWORD)((DWORD)hModule+dwPointerRva)是没有修正的值,不是应该重定位了吗?比如我自己加载的hModule地址是b50000,这里跟进去看*(PDWORD)((DWORD)hModule+dwPointerRva)是4XXXXX,显然比真实的装载地址b50000小,也就是还没有重定位
dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;
// does this reloc point to KeServiceDescriptorTable.Base?
if (dwPointsToRva==dwKSDT) {
//后面就好理解了
// check for mov [mem32],imm32. we are trying to find
// "mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable"
// from the KiInitSystem.
if (*(PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7) {
// should check for a reloc presence on KiServiceTable here
// but forget it
dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase;
return dwKiServiceTable;
}
}
}
// should never get here
}
*(PDWORD)&pbr+=pbr->SizeOfBlock;
}
}
return 0;
}
还有用Lordpe查看ntoskrnl.exe发现它的代码段起始地址是580,没有4K对齐,不解。。。。。
赞赏
看原图
赞赏
雪币:
留言: