调试一段驱动程序,遍历ntoskrnl.exe的IAT表,在虚拟机里执行蓝屏,在实体机上却能正常的执行,真是非常的奇怪,谁能看看是怎么回事?
代码如下:
//安装IAT hook钩子
void CKernelModelIATHook::InstallIATHook(PBYTE pModBase, PBYTE pOldFuncName, PVOID pNewFuncAddr, PBYTE pDllName)
{
do
{
//DOS header头
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pModBase;
if (IMAGE_DOS_SIGNATURE != pDosHeader->e_magic)
{
break;
}
//NT header头
PIMAGE_NT_HEADERS32 pNtHeader = (PIMAGE_NT_HEADERS32)(pModBase + pDosHeader->e_lfanew);
if (IMAGE_NT_SIGNATURE != pNtHeader->Signature)
{
break;
}
PIMAGE_OPTIONAL_HEADER32 pOph = &pNtHeader->OptionalHeader;
//调试的时候发现下面这句代码在虚拟机上获取到的PIMAGE_IMPORT_DESCRIPTOR 内存不可访问
//奇怪的是在实体机上是正常的。在调试的过程中发现,无论哪个模块这行代码都是失败的,windbg
//dd出来的数据都是不对的。虚拟机环境是WIN7 32位、也尝试了WIN XP SP3出现的问题与win7 32是一样的
//求大师解答,不胜感激!!!!
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pModBase + pOph->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
//导入表有效
while (pImport->Name)
{
//判断是否遍历了指定的模块
BOOL bIsFind = FALSE;
//找出指定的模块
if (0 == strcmp((char *)(pModBase + pImport->Name), (char *)pDllName))
{
bIsFind = TRUE;
PIMAGE_THUNK_DATA pThunkData = (PIMAGE_THUNK_DATA)(pModBase + pImport->FirstThunk);
while (pThunkData->u1.Ordinal)
{
//函数名字相同就找到要hook的函数了
PIMAGE_IMPORT_BY_NAME pImportFuncName = (PIMAGE_IMPORT_BY_NAME)(pModBase + pThunkData->u1.AddressOfData);
if (0 == strcmp((char *)pOldFuncName, (char *)pImportFuncName->Name))
{
//DbgBreakPoint();
//保存hook掉的函数信息
dwHookedModuleBase = (DWORD)pModBase;
pHookedFuncName = (PBYTE)ExAllocatePool(NonPagedPool, (strlen((char *)pImportFuncName->Name) + 1));
if (NULL == pHookedFuncName)
{
break;
}
RtlZeroMemory(pHookedFuncName, (strlen((char *)pImportFuncName->Name) + 1));
RtlCopyMemory(pHookedFuncName, pOldFuncName, (strlen((char *)pImportFuncName->Name) + 1));
dwHookedFuncAddr = pThunkData->u1.Function;
//写入新的函数地址
WPOFF();
pThunkData->u1.Function = (DWORD)pNewFuncAddr;
WPON();
break;
}
//继续下一个函数块,知道结束
pThunkData++;
}
}
if (bIsFind)
{
break;
}
pImport++;
}
} while(0);
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!