首页
社区
课程
招聘
[求助]一个关于清空PE文件头的问题,请各位大侠指点一下。
发表于: 2011-5-9 21:57 4987

[求助]一个关于清空PE文件头的问题,请各位大侠指点一下。

2011-5-9 21:57
4987
我在学习_achillis的隐藏模块驱动代码时,其中清除PE文件头的函数中MmGetSystemAddressForMdl老是失败,返回错误代码为:0xC0000005。这个问题我搞了二天也没搞定,请大侠帮忙解答一下,万分感谢。函数如下:
VOID ZeroPEHeader(ULONG ImageBase)
{
        PIMAGE_DOS_HEADER pDosHeader;
        char *pNtHeader;
        PIMAGE_OPTIONAL_HEADER pOptinalHeader;
        ULONG HeaderSize=0;
        PMDL pHeaderMdl;
        PVOID NewBuffer;
        __try
        {
                pDosHeader=(PIMAGE_DOS_HEADER)ImageBase;
                pNtHeader=(char*)ImageBase+pDosHeader->e_lfanew;
                pOptinalHeader=(PIMAGE_OPTIONAL_HEADER)(pNtHeader+4+sizeof(IMAGE_FILE_HEADER));
                HeaderSize=pOptinalHeader->SizeOfHeaders;
                dprintf("Image Header Size=0x%X\n",HeaderSize);
                pHeaderMdl=IoAllocateMdl((PVOID)ImageBase,HeaderSize,FALSE,FALSE,NULL);
                dprintf("pHeaderMdl=0x%08X\n",pHeaderMdl);
                NewBuffer=MmGetSystemAddressForMdl(pHeaderMdl);
                dprintf("NewBuffer=0x%08X\n",NewBuffer);
                RtlZeroMemory(NewBuffer,HeaderSize);
                MmUnmapLockedPages(NewBuffer,pHeaderMdl);
                IoFreeMdl(pHeaderMdl);
                //若要针对所有进程,可使用以下方法,此时COW将会失效
                /*
                WPOFF();
                RtlZeroMemory((char*)ImageBase,HeaderSize);
                WPON();
                */
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                DbgPrint("Error occured while zero pe header.\n");
                return ;
        }
       
       
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 167
活跃值: (288)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
补充一下,我是在ring0下抹ring3的dll.
2011-5-10 00:57
0
雪    币: 167
活跃值: (288)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
自己先顶起来。
2011-5-10 09:39
0
雪    币: 517
活跃值: (84)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
4
使用MDL比较安全。
另外,如果你的代码不是由目标进程驱动,那么环境不对,你在操作前需要先Attach目标进程,这样,所谓的ImageBase才能被正确映射。
操作MDL如下所示:
inline	bool	Crackit(void* mem,unsigned char* crackcode,size_t len)
	{
#ifdef	_RING0
	PMDL pMDL = MmCreateMdl(NULL,mem,len);
	if (pMDL == NULL)	return	false;
	MmBuildMdlForNonPagedPool(pMDL);
	pMDL->MdlFlags = pMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA | MDL_WRITE_OPERATION;
	void* Mem = MmMapLockedPages(pMDL,KernelMode);
	if (Mem == NULL)	return	false;
	bool rets = true;
	__try
		{
		RtlCopyMemory(Mem,crackcode,len);
		}
	__except(EXCEPTION_EXECUTE_HANDLER)
		{
		rets = false;
		}
	MmUnmapLockedPages(Mem,pMDL);
	IoFreeMdl(pMDL);
#else
	bool	rets = true;
	if(!WriteProcessMemory((HANDLE)-1,(LPVOID)mem,(LPCVOID)crackcode,len,0))	return	false;
#endif
	return rets;
	}
2011-5-10 09:46
0
雪    币: 167
活跃值: (288)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
非常感谢您的回答,这个问题我刚解决,正准备把解决办法贴出来时,你竟然给发出来了(说实话,原以为没人会帮忙了)。在此,再次对你的帮助表示衷心的感谢。
解决办法跟你的代码原理一样,我是参考了内核读写只读内存方法总结[Delphi描述] (http://apps.hi.baidu.com/share/detail/168311)中的第二种方法,我贴出有问题的代码是该文中说到的第三种方法,可实际这种方法不行。
既然您给出答案了,我也就不再贴了,不过,我在想要不要在写之前加个自旋琐呢?为了稳当起见,还是加一下比较好,不知各位资深前辈的意见如何???
2011-5-10 11:05
0
游客
登录 | 注册 方可回帖
返回
//