-
-
[求助]关于ssdt hook一段代码的疑惑
-
发表于: 2011-7-10 12:12 3862
-
void ReSSDT( IN HANDLE hDriver)
{
HMODULE hKernel;
DWORD dwKSDT; // rva of KeServiceDescriptorTable
DWORD dwKiServiceTable; // rva of KiServiceTable
PMODULES pModules=(PMODULES)&pModules;
DWORD dwNeededSize,rc;
DWORD dwKernelBase,dwServices=0;
PCHAR pKernelName;
PDWORD pService;
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
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;
}
printf("&KiServiceTable==%08X\n\nDumping 'old' ServiceTable:\n\n",dwKiServiceTable+dwKernelBase);
// let's dump KiServiceTable contents
// MAY FAIL!!!
// should get right ServiceLimit here, but this is trivial in the kernel mode
GetHeaders((PCHAR)hKernel,&pfh,&poh,&psh); //获取文件头信息
for (pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable); //基址+偏移
*pService-poh->ImageBase<poh->SizeOfImage;
pService++,dwServices++)
{
ULONG ulAddr=*pService-poh->ImageBase+dwKernelBase; //kernel库文件中服务绝对地址-文件的基址+kernel库文件的基址=相当于kernel文件基址的绝对地址
SetProc( hDriver,dwServices, &ulAddr ); //通过驱动命令修改函数地址
//printf("%08X\n",ulAddr);
}
printf("\n\nPossibly KiServiceLimit==%08X\n",dwServices);
FreeLibrary(hKernel);
}
DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT) //模块句柄,SSTD表偏移地址
{
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);
//获取模块dll的文件头信息,返回数据目录的绝对地址到psh,poh为文件头绝对地址,pfh为pe标志绝对地址
// 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));
这里pfe已经指向IMAGE_BASE_RELOCATION结构之后的另一个区段了?
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;
}
由于刚接触ssdt hook,看得有点晕。还请各位大虾不吝赐教!谢谢
{
HMODULE hKernel;
DWORD dwKSDT; // rva of KeServiceDescriptorTable
DWORD dwKiServiceTable; // rva of KiServiceTable
PMODULES pModules=(PMODULES)&pModules;
DWORD dwNeededSize,rc;
DWORD dwKernelBase,dwServices=0;
PCHAR pKernelName;
PDWORD pService;
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
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;
}
printf("&KiServiceTable==%08X\n\nDumping 'old' ServiceTable:\n\n",dwKiServiceTable+dwKernelBase);
// let's dump KiServiceTable contents
// MAY FAIL!!!
// should get right ServiceLimit here, but this is trivial in the kernel mode
GetHeaders((PCHAR)hKernel,&pfh,&poh,&psh); //获取文件头信息
for (pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable); //基址+偏移
*pService-poh->ImageBase<poh->SizeOfImage;
pService++,dwServices++)
{
ULONG ulAddr=*pService-poh->ImageBase+dwKernelBase; //kernel库文件中服务绝对地址-文件的基址+kernel库文件的基址=相当于kernel文件基址的绝对地址
SetProc( hDriver,dwServices, &ulAddr ); //通过驱动命令修改函数地址
//printf("%08X\n",ulAddr);
}
printf("\n\nPossibly KiServiceLimit==%08X\n",dwServices);
FreeLibrary(hKernel);
}
DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT) //模块句柄,SSTD表偏移地址
{
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);
//获取模块dll的文件头信息,返回数据目录的绝对地址到psh,poh为文件头绝对地址,pfh为pe标志绝对地址
// 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));
这里pfe已经指向IMAGE_BASE_RELOCATION结构之后的另一个区段了?
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;
}
由于刚接触ssdt hook,看得有点晕。还请各位大虾不吝赐教!谢谢
赞赏
他的文章
- [求助]这种是VMP壳吗 4002
- [求助]这种驱动保护怎么弄? 5128
- [求助]请教下TesSafe.sys 5421
- [求助]微过滤中FltCreateFile失败是为何? 7745
- [求助]寒江minifilter编译不过去求助 7654
赞赏
雪币:
留言: