FARPROC NtQuerySystemInformationAddr=GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation"); // get system modules - ntoskrnl is always first there, rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,4,&dwNeededSize); if (rc==STATUS_INFO_LENGTH_MISMATCH) { pModules=(MODULES *)GlobalAlloc(GPTR,dwNeededSize); rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,dwNeededSize,NULL); } else { strange: printf("strange NtQuerySystemInformation()!\n"); return; } if (!NT_SUCCESS(rc)) goto strange; //不成功则退出
// imagebase dwKernelBase=(DWORD)pModules->smi.Base; // filename - it may be renamed in the boot.ini pKernelName=pModules->smi.ModuleNameOffset+pModules->smi.ImageName; // map ntoskrnl - hopefully it has relocs hKernel=LoadLibraryEx(pKernelName,0,DONT_RESOLVE_DLL_REFERENCES); //加载模块 if (!hKernel) { printf("Failed to load! LastError=%i\n",GetLastError()); return; }
GlobalFree(pModules); //释放空间
// our own export walker is useless here - we have GetProcAddress :) if (!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable"))) { //试图获取模块中的ssdt表基址,这里已经获取了地址 printf("Can't find KeServiceDescriptorTable\n"); return; }
// get KeServiceDescriptorTable rva dwKSDT-=(DWORD)hKernel; // find KiServiceTable if (!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT))) { //在模块中寻找ssdt表偏移地址为啥这里又去寻找ssdt表的地址了? printf("Can't find KiServiceTable...\n"); return; }
// 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;
for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) { if (pfe->type==IMAGE_REL_BASED_HIGHLOW) { 这里怎么能取本区段IMAGE_BASE_RELOCATION结构内的typeoffset里的类型?,下一个区段的?又不像 dwFixups++; dwPointerRva=pbr->VirtualAddress+pfe->offset; // DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed 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; 这里返回的偏移地址和之前GetProcAddress获取的区别是什么 return dwKiServiceTable; } }
} else if (pfe->type!=IMAGE_REL_BASED_ABSOLUTE) // should never get here printf("\trelo type %d found at .%X\n",pfe->type,pbr->VirtualAddress+pfe->offset); } *(PDWORD)&pbr+=pbr->SizeOfBlock; } }
if (!dwFixups) // should never happen - nt, 2k, xp kernels have relocation data printf("No fixups!\n"); return 0; }