过 DNF TP 驱动保护(二)
2012-06-12 09:04
405 查看
文章目录:
01.博文简介:
02.环境及工具准备:
03.分析TP所做的保护:
04.干掉NtOpenProcess中的DeepInLineHook:
05.干掉NtOpenThread中的DeepInLineHook:
06.干掉NtReadVirtualMemory中的InLineHook:
07.干掉NtWriteVirtualMemory中的InLineHook:
08.干掉KiAttachProcess的InLineHook:
09.干掉NtGetContextThread中的InLineHook:
10.干掉NtSetContextThread中的InLineHook:
11.干掉DbgkpQueueMessage中的InLineHook:
12.干掉DbgkpSetProcessDebugObject中的InLineHook:
13.干掉Debug清零:
共四篇,本篇为第二篇。
06.干掉NtReadVirtualMemory中的InLineHook:
前面已经干掉了TP对NtOpenProcess以及TP对NtOpenThread所做的Hook,
这样的话,我们已经可以使用OD或者CE看到DNF的游戏进程了,
弄过一些游戏方面内容的朋友应该都是知道CE的,这东东是开源的,不过是基于Delphi的,
工具做得很不错,可以通过CE来修改一些游戏进程的内存数据,比如可以修改一些简单的游戏的血值啊之类的,
但是,此时我们可以用CE来扫描一下DNF游戏进程的内存,你会发现根本扫描不到任何数据,
其实原因也很简单,TP对NtReadVirtualMemory进行了浅层的InLineHook,
从而可以达到防止其他进程读取DNF游戏进程内存的目的,
而CE的话,在Ring3下是通过ReadProcessMemory来读取游戏内存的,
而ReadProcessMemory进入Ring0后又是调用的NtReadVirtualMemory,
由于NtReadVirtualMemory被TP干掉了,所以自然用CE是扫描不出任何东西的,
要干掉TP对NtReadVirtualMemory所作的浅层InLineHook其实是比较简单的,
因为TP并没有对NtReadVirtualMemory做检测,所以可以直接用SSDT来对抗掉浅层的InLineHook就OK。
至于原理的话,很简单,直接用SSDTHook替换掉系统服务NtReadVirtualMemory,
然后在SSDTHookNtReadVirtualMemory这个我们自己写的系统服务中判断,
如果是DNF进程的话,直接调用原来的SSDT系统服务就好,如果不是DNF进程的话,
我就跳过TP对NtReadVirtualMemory所做的InLineHook,也就是跳过前面7个字节就OK了。
对于这种干掉InLineHook的原理,堕落天才的文章讲的最清楚了,我这里就不再班门弄斧了。
(继续为堕落天才打广告)
对于用SSDTHook干掉浅层的InLineHook可以参考看雪上堕落天才的文章:
文章名称:《SSDTHook的妙用-对抗Ring0InLineHook》
文章地址:http://bbs.pediy.com/showthread.php?t=40832
有的童鞋可能会问,咱是如何知道NtReadVirtualMemory被TP干掉了呢?
很简单,还是采用前面的做法,用KernelDetective就可以看到了,具体可以看下面的截图:
至于如何安装SSDTHook或者SSDTHook是啥玩意来着的话,大家有兴趣的可以参考我的下面博文系列:
《进程隐藏与进程保护(SSDTHook实现)》系列,共三篇。
/article/4910401.html
/article/4910402.html
/article/4910403.html
下面先贴出安装SSDT钩子的代码,该代码用来干掉TP对NtReadVirtualMemory的InLineHook:
[code]/*安装钩子从而过掉TP保护所Hook的NtReadVirtualMemory-让TP失效
[/code]
下面再给出SSDTHook的中继API的实现代码:
[code]/*自定义的NtReadVirtualMemory,用来实现SSDTHookKernelAPI
[/code]
好,到这里就已经干掉了TP对NtReadVirtualMemory所做的InLineHook了,
对此最直白的效果就是用CE打开DNF游戏进程进行内存扫描,你会发现,OnYear,可以正常扫描到DNF内存了。
07.干掉NtWriteVirtualMemory中的InLineHook:
上面又干掉了TP对NtReadVirtualMemory的InLineHook了,从而实现了CE读取DNF进程的内存。
但是你可以试着用CE修改DNF进程的内存,你很快就会发现,虽然可以扫描内存,但是并不可以读取内存,
而后你也肯定能够想到,既然有防止读取内存,那肯定也有防止写入内存,
而后你又自然会找到NtWriteVirtualMemory上来,等你找到NtWriteVirtualMemory后,
你又基本能够确定,搞定这个API和搞定NtReadVirtualMemory应该是差不多的,
因为这两个API就是一对啊,一个读,一个写,所以TP肯定也是采用相同的做法来处理这两个API,
当然,你上面的猜想都是正确的,所以咱还是用SSDT来干掉TP对NtWriteVirtualMemory所做的InLine。
代码和上面的NtReadVirtualMemory差不多,这里也还是贴出来一下吧,俺先放两幅截图,然后再贴代码出来:
下面先贴出安装SSDT钩子的代码,该代码用来干掉TP对NtWriteVirtualMemory的InLineHook:
[code]/*安装钩子从而过掉TP保护所Hook的NtWriteVirtualMemory-让TP失效
[/code]
下面再给出SSDTHook的中继API的实现代码:
[code]/*自定义的NtWriteVirtualMemory,用来实现SSDTHookKernelAPI
[/code]
好,到这里就已经拿下了TP对NtWriteVirtualMemory所做的InLineHook了,
对此最直白的效果大家也都可以想象得到了,那就是直接用CE打开DNF游戏进程进行内存修改,
你会发现,此时可以正常修改掉DNF游戏的内存了。
08.干掉KiAttachProcess中的InLineHook:
前面已经干掉NtOpenProcess和NtOpenThread了,按道理来说,咱可以开始用OD来调试DNF游戏进程了,
不过你可以用OD尝试附加一下DNF的游戏进程,而后你会发现根本附加不上去,这又是为何呢?
首先需要明白Ring3在何种操作下,会导致内核调用KiAttachProcess,
从字面意思上看,就是附加进程,在Ring3下的附加进程操作一般会出现在调试进程的时候,
比如用OD附加进程来进行调试,或者用VisualStudio附加进程进行调试,
其实咱猜的没错,就是当附加进程的时候会导致内核调用KiAttachProcess,
TP对这个未导出的API进行了InLineHook,从而使得DNF游戏进程不能被附加,
这样的话,咱的OD或者VisualStudio都是不能够附加上DNF的游戏进程来进行调试了。
正如前面分析的NtReadVirtualMemory和NtWriteVirtualMemory这两个API一样,
TP对KiAttachProcess也是做的浅层的InLineHook,也就是只是Hook了函数头7个字节,
且TP对KiAttachProcess的InLineHook也没有检测,所以干掉这个API还是比较简单的,
不过我们不可以像干掉NtRead/WriteVirtualMemory一样用SSDTHook来对抗掉,
因为KiAttachProcess并没有在SSDT表中,不过我们可以直接恢复TP对KiAttachProcess的Hook即可。
前面也提到了KiAttachProcess是一个未导出的内核API,
所以我们不能使用MmGetSystemRoutineAddress来获得它的地址,
不过好在KeAttachProcess这是一个导出的内核API,
(一般Kixxx都是未导出的API,而Kexxx则是导出的API)
在KeAttachProcess的内部实质上是调用的KiAttachProcess来完成功能的,
所以咱可以通过KeAttachProcess来定位到KiAttachProcess的地址,
并且让人欣喜的是在KeAttachProcess中的第一个call就是callKiAttachProcess,
所以搜索特征码也更加简单了,直接搜索第一个e8就OK。
如果用WinDbg的话,你可以输几个命令就可以把KeAttachProcess的地址打印出来,但是现在咱走点弯路,
在驱动里面用KdPrint打印出KeAttachProcess的地址,然后我们再分析。
好,这里得到了KeAttachProcess的地址了,
那么咱就可以在KernelDetective中来看看KeAttachProcess的反汇编代码了,
具体的就看图说话,俺也就不多说了,因为截图里面都明明白白摆着在哪里,
下面给出获取KiAttachProcess地址的代码:
[code]/*获取函数KiAttachProcess的地址
[/code]
得到了KiAttachProcess的地址,那么下面就要来干掉KiAttachProcess了,
为了简单实现,我一开始干掉KiAttachProcess的做法是采用的硬编码,
在得到KiAttachProcess地址后,可以用Xuetr来反汇编这个地址,
从而看到KiAttachProcess的反汇编指令,所以我的做法就是,
直接将Xuetr中KiAttachProcess的头7个字节以硬编码的形式保存在数组中,
然后等TP启动后,我用保存下来的这7个字节直接去恢复KiAttachProcess就OK,
这种方式在我的虚拟机XP里面是OK的,因为我就是从这台XP上获取的7个字节的硬编码,
但是在别的XP系统上就不OK了,原因是KiAttachProcess头7个字节并不是所有的XP都相同的,
直接拿不一致的硬编码去恢复肯定是会BSOD的,不过后来我用了一种简单的办法就干掉这个问题了,
办法很简单,在TP启动之前,我动态去读取KiAttachProcess的头7个字节,并且保存在数组中,
等TP启动后,我就用数组中的这7个字节去恢复TP对KiAttachProcess所做的InLineHook。
实现的具体代码很简单,下面也贴出来:
先在TP启动之前保存KiAttachProcess的头7个字节:
[code]
[/code]
TP启动之后恢复被TP修改掉的KiAttachProcess的头7个字节:
[code]/*恢复KiAttachProcess头9个字节从而恢复KiAttachProcess-让TP失效
[/code]
到这里,我们又把KiAttachProcess给搞定了,所以此时咱可以用OD来附加DNF游戏进程试试看了,
此时你会发现咱可以将OD附加上去了,不过可惜的是,就算附加上去了,离使用OD来调试DNF还远着呢,
因为TP对DNF游戏进程还有其他的保护措施,它在内核里面Hook的API可不止这么点哦。
总结:
《过DNFTP驱动保护》的第二篇到这里就结束了,经过上面的处理,
我们已经过掉了TP所做InLineHook的5个API了,
首先是NtOpenProcess和NtOpenThread的深层InLineHook,
然后是SSDT系统服务函数NtReadVirtualMemory和NtWriteVirtualMemory的浅层次InLineHook,
最后我们也干掉了TP对未导出内核函数KiAttachProcess所做的浅层次InLineHook。
虽然也干掉了不少TP在内核中Hook的API了,但是这离过DNFTP驱动保护还比较远的,
详情还得留到下回分解了。
现已支持过掉最新版本的TP保护(2013年04月23日),
如有需要者(有偿提供),请联系QQ:1751048662
版权所有,[b]欢迎转载,但转载请注明:转载自[/b][b]Zachary.XiaoZhen-梦想的天空 [/b]
01.博文简介:
02.环境及工具准备:
03.分析TP所做的保护:
04.干掉NtOpenProcess中的DeepInLineHook:
05.干掉NtOpenThread中的DeepInLineHook:
06.干掉NtReadVirtualMemory中的InLineHook:
07.干掉NtWriteVirtualMemory中的InLineHook:
08.干掉KiAttachProcess的InLineHook:
09.干掉NtGetContextThread中的InLineHook:
10.干掉NtSetContextThread中的InLineHook:
11.干掉DbgkpQueueMessage中的InLineHook:
12.干掉DbgkpSetProcessDebugObject中的InLineHook:
13.干掉Debug清零:
共四篇,本篇为第二篇。
06.干掉NtReadVirtualMemory中的InLineHook:
前面已经干掉了TP对NtOpenProcess以及TP对NtOpenThread所做的Hook,
这样的话,我们已经可以使用OD或者CE看到DNF的游戏进程了,
弄过一些游戏方面内容的朋友应该都是知道CE的,这东东是开源的,不过是基于Delphi的,
工具做得很不错,可以通过CE来修改一些游戏进程的内存数据,比如可以修改一些简单的游戏的血值啊之类的,
但是,此时我们可以用CE来扫描一下DNF游戏进程的内存,你会发现根本扫描不到任何数据,
其实原因也很简单,TP对NtReadVirtualMemory进行了浅层的InLineHook,
从而可以达到防止其他进程读取DNF游戏进程内存的目的,
而CE的话,在Ring3下是通过ReadProcessMemory来读取游戏内存的,
而ReadProcessMemory进入Ring0后又是调用的NtReadVirtualMemory,
由于NtReadVirtualMemory被TP干掉了,所以自然用CE是扫描不出任何东西的,
要干掉TP对NtReadVirtualMemory所作的浅层InLineHook其实是比较简单的,
因为TP并没有对NtReadVirtualMemory做检测,所以可以直接用SSDT来对抗掉浅层的InLineHook就OK。
至于原理的话,很简单,直接用SSDTHook替换掉系统服务NtReadVirtualMemory,
然后在SSDTHookNtReadVirtualMemory这个我们自己写的系统服务中判断,
如果是DNF进程的话,直接调用原来的SSDT系统服务就好,如果不是DNF进程的话,
我就跳过TP对NtReadVirtualMemory所做的InLineHook,也就是跳过前面7个字节就OK了。
对于这种干掉InLineHook的原理,堕落天才的文章讲的最清楚了,我这里就不再班门弄斧了。
(继续为堕落天才打广告)
对于用SSDTHook干掉浅层的InLineHook可以参考看雪上堕落天才的文章:
文章名称:《SSDTHook的妙用-对抗Ring0InLineHook》
文章地址:
有的童鞋可能会问,咱是如何知道NtReadVirtualMemory被TP干掉了呢?
很简单,还是采用前面的做法,用KernelDetective就可以看到了,具体可以看下面的截图:
至于如何安装SSDTHook或者SSDTHook是啥玩意来着的话,大家有兴趣的可以参考我的下面博文系列:
《进程隐藏与进程保护(SSDTHook实现)》系列,共三篇。
下面先贴出安装SSDT钩子的代码,该代码用来干掉TP对NtReadVirtualMemory的InLineHook:
/************************************************************************/
[code]/*安装钩子从而过掉TP保护所Hook的NtReadVirtualMemory-让TP失效
/*保存NtReadVirtualMemory第4,5,6,7个字节(其实就是一个ULONG跳转地址)
/*因为这几个字节在不同的XP上会改变,所以在SSDTHook之前保存下来
/*从而避免在此处进行硬编码
/************************************************************************/
VOIDInstallPassTPNtReadVirtualMemory()
{
if(g_SSDTHookNtReadVirtualMemory>0)
{
/*获得NtReadVirtualMemory的地址*/
ULONGuNtReadVirtualMemoryAddr=oldSysServiceAddr[g_SSDTHookNtReadVirtualMemory];
/*如果是DNF进程,则跳到NtReadVirtualMemory执行,即不处理,从而让DNFInLineHook生效*/
uTPHookedNtReadVirtualMemoryJmpAddr=uNtReadVirtualMemoryAddr;
/*如果不是DNF进程,则跳过TP的InLineHook,从而使TP失效*/
uMyHookedNtReadVirtualMemoryJmpAddr=uNtReadVirtualMemoryAddr+7;
/*保存下未Hook之前的NtReadVirtualMemory的第4,5,6,7个字节*/
uNtReadVirtualMemoryAddr_3=*((ULONG*)(uNtReadVirtualMemoryAddr+3));
InstallSysServiceHookByIndex(g_SSDTHookNtReadVirtualMemory,SSDTHookNtReadVirtualMemory);
KdPrint(("PassTP-NtReadVirtualMemoryInstalled."));
}
}
[/code]
下面再给出SSDTHook的中继API的实现代码:
/************************************************************************/
[code]/*自定义的NtReadVirtualMemory,用来实现SSDTHookKernelAPI
/************************************************************************/
NTSYSHOOKAPIVOIDSSDTHookNtReadVirtualMemory()
{
/*开始过滤*/
if(ValidateCurrentProcessIsDNF()==TRUE)
{
__asm
{
/*如果是DNF进程调用的话,则调用已经被TPHook的NtReadVirtualMemory*/
jmpuTPHookedNtReadVirtualMemoryJmpAddr
}
}
__asm
{
/*已经做了针对硬编码的处理*/
/*如果不是DNF进程调用的话,则跳过TPHook的NtReadVirtualMemory*/
push0x1C
pushuNtReadVirtualMemoryAddr_3
jmpuMyHookedNtReadVirtualMemoryJmpAddr
}
}
[/code]
好,到这里就已经干掉了TP对NtReadVirtualMemory所做的InLineHook了,
对此最直白的效果就是用CE打开DNF游戏进程进行内存扫描,你会发现,OnYear,可以正常扫描到DNF内存了。
07.干掉NtWriteVirtualMemory中的InLineHook:
上面又干掉了TP对NtReadVirtualMemory的InLineHook了,从而实现了CE读取DNF进程的内存。
但是你可以试着用CE修改DNF进程的内存,你很快就会发现,虽然可以扫描内存,但是并不可以读取内存,
而后你也肯定能够想到,既然有防止读取内存,那肯定也有防止写入内存,
而后你又自然会找到NtWriteVirtualMemory上来,等你找到NtWriteVirtualMemory后,
你又基本能够确定,搞定这个API和搞定NtReadVirtualMemory应该是差不多的,
因为这两个API就是一对啊,一个读,一个写,所以TP肯定也是采用相同的做法来处理这两个API,
当然,你上面的猜想都是正确的,所以咱还是用SSDT来干掉TP对NtWriteVirtualMemory所做的InLine。
代码和上面的NtReadVirtualMemory差不多,这里也还是贴出来一下吧,俺先放两幅截图,然后再贴代码出来:
下面先贴出安装SSDT钩子的代码,该代码用来干掉TP对NtWriteVirtualMemory的InLineHook:
/************************************************************************/
[code]/*安装钩子从而过掉TP保护所Hook的NtWriteVirtualMemory-让TP失效
/*保存NtWriteVirtualMemory第4,5,6,7个字节(其实就是一个ULONG跳转地址)
/*因为这几个字节在不同的XP上会改变,所以在SSDTHook之前保存下来
/*从而避免在此处进行硬编码
/************************************************************************/
VOIDInstallPassTPNtWriteVirtualMemory()
{
if(g_SSDTHookNtWriteVirtualMemory>0)
{
/*获得NtWriteVirtualMemory的地址*/
ULONGuNtWriteVirtualMemoryAddr=oldSysServiceAddr[g_SSDTHookNtWriteVirtualMemory];
/*如果是DNF进程,则跳到NtWriteVirtualMemory执行,即不处理,从而让DNFInLineHook生效*/
uTPHookedNtWriteVirtualMemoryJmpAddr=uNtWriteVirtualMemoryAddr;
/*如果不是DNF进程,则跳过TP的InLineHook,从而使TP失效*/
uMyHookedNtWriteVirtualMemoryJmpAddr=uNtWriteVirtualMemoryAddr+7;
/*保存下未Hook之前的NtReadVirtualMemory的第4,5,6,7个字节*/
uNtWriteVirtualMemoryAddr_3=*((ULONG*)(uNtWriteVirtualMemoryAddr+3));
InstallSysServiceHookByIndex(g_SSDTHookNtWriteVirtualMemory,SSDTHookNtWriteVirtualMemory);
KdPrint(("PassTP-NtWriteVirtualMemoryInstalled."));
}
}
[/code]
下面再给出SSDTHook的中继API的实现代码:
/************************************************************************/
[code]/*自定义的NtWriteVirtualMemory,用来实现SSDTHookKernelAPI
/************************************************************************/
NTSYSHOOKAPIVOIDSSDTHookNtWriteVirtualMemory()
{
/*开始过滤*/
if(ValidateCurrentProcessIsDNF()==TRUE)
{
__asm
{
/*如果是DNF进程调用的话,则调用已经被TPHook的NtWriteVirtualMemory*/
jmpuTPHookedNtWriteVirtualMemoryJmpAddr
}
}
__asm
{
/*已经做了针对硬编码的处理*/
/*如果不是DNF进程调用的话,则跳过TPHook的NtWriteVirtualMemory*/
push0x1C
pushuNtWriteVirtualMemoryAddr_3
jmpuMyHookedNtWriteVirtualMemoryJmpAddr
}
}
[/code]
好,到这里就已经拿下了TP对NtWriteVirtualMemory所做的InLineHook了,
对此最直白的效果大家也都可以想象得到了,那就是直接用CE打开DNF游戏进程进行内存修改,
你会发现,此时可以正常修改掉DNF游戏的内存了。
08.干掉KiAttachProcess中的InLineHook:
前面已经干掉NtOpenProcess和NtOpenThread了,按道理来说,咱可以开始用OD来调试DNF游戏进程了,
不过你可以用OD尝试附加一下DNF的游戏进程,而后你会发现根本附加不上去,这又是为何呢?
首先需要明白Ring3在何种操作下,会导致内核调用KiAttachProcess,
从字面意思上看,就是附加进程,在Ring3下的附加进程操作一般会出现在调试进程的时候,
比如用OD附加进程来进行调试,或者用VisualStudio附加进程进行调试,
其实咱猜的没错,就是当附加进程的时候会导致内核调用KiAttachProcess,
TP对这个未导出的API进行了InLineHook,从而使得DNF游戏进程不能被附加,
这样的话,咱的OD或者VisualStudio都是不能够附加上DNF的游戏进程来进行调试了。
正如前面分析的NtReadVirtualMemory和NtWriteVirtualMemory这两个API一样,
TP对KiAttachProcess也是做的浅层的InLineHook,也就是只是Hook了函数头7个字节,
且TP对KiAttachProcess的InLineHook也没有检测,所以干掉这个API还是比较简单的,
不过我们不可以像干掉NtRead/WriteVirtualMemory一样用SSDTHook来对抗掉,
因为KiAttachProcess并没有在SSDT表中,不过我们可以直接恢复TP对KiAttachProcess的Hook即可。
前面也提到了KiAttachProcess是一个未导出的内核API,
所以我们不能使用MmGetSystemRoutineAddress来获得它的地址,
不过好在KeAttachProcess这是一个导出的内核API,
(一般Kixxx都是未导出的API,而Kexxx则是导出的API)
在KeAttachProcess的内部实质上是调用的KiAttachProcess来完成功能的,
所以咱可以通过KeAttachProcess来定位到KiAttachProcess的地址,
并且让人欣喜的是在KeAttachProcess中的第一个call就是callKiAttachProcess,
所以搜索特征码也更加简单了,直接搜索第一个e8就OK。
如果用WinDbg的话,你可以输几个命令就可以把KeAttachProcess的地址打印出来,但是现在咱走点弯路,
在驱动里面用KdPrint打印出KeAttachProcess的地址,然后我们再分析。
KdPrint(("KeAttachProcess:%x.",MmGetSystemFunAddress(L"KeAttachProcess")));
好,这里得到了KeAttachProcess的地址了,
那么咱就可以在KernelDetective中来看看KeAttachProcess的反汇编代码了,
具体的就看图说话,俺也就不多说了,因为截图里面都明明白白摆着在哪里,
下面给出获取KiAttachProcess地址的代码:
/************************************************************************/
[code]/*获取函数KiAttachProcess的地址
/*KiAttachProcess在KeAttachProcess中的第一个Call(e8指令)位置
/************************************************************************/
ULONGGetKiAttachProcessAddr()
{
ULONGuCallAddr=0;
ULONGuKeAttachProcessAddr=0;
ULONGuKiAttachProcessAddr=0;
CHARszCode[1]=
{
(char)0xe8
};
/*获取KeAttachProcess的地址*/
uKeAttachProcessAddr=MmGetSystemFunAddress(L"KeAttachProcess");
/*搜索特征码e8*/
uCallAddr=SearchFeature(uKeAttachProcessAddr,szCode,1);
if(uCallAddr==0)
{
uKiAttachProcessAddr=0;
}
else
{
/*获取KiAttachProcess的地址*/
uKiAttachProcessAddr=*((ULONG*)uCallAddr)+uCallAddr+4;
}
returnuKiAttachProcessAddr;
}
[/code]
得到了KiAttachProcess的地址,那么下面就要来干掉KiAttachProcess了,
为了简单实现,我一开始干掉KiAttachProcess的做法是采用的硬编码,
在得到KiAttachProcess地址后,可以用Xuetr来反汇编这个地址,
从而看到KiAttachProcess的反汇编指令,所以我的做法就是,
直接将Xuetr中KiAttachProcess的头7个字节以硬编码的形式保存在数组中,
然后等TP启动后,我用保存下来的这7个字节直接去恢复KiAttachProcess就OK,
这种方式在我的虚拟机XP里面是OK的,因为我就是从这台XP上获取的7个字节的硬编码,
但是在别的XP系统上就不OK了,原因是KiAttachProcess头7个字节并不是所有的XP都相同的,
直接拿不一致的硬编码去恢复肯定是会BSOD的,不过后来我用了一种简单的办法就干掉这个问题了,
办法很简单,在TP启动之前,我动态去读取KiAttachProcess的头7个字节,并且保存在数组中,
等TP启动后,我就用数组中的这7个字节去恢复TP对KiAttachProcess所做的InLineHook。
实现的具体代码很简单,下面也贴出来:
先在TP启动之前保存KiAttachProcess的头7个字节:
PUCHARpKiAttachProcessAddr=NULL;
[code]
pKiAttachProcessAddr=(PUCHAR)GetKiAttachProcessAddr();
KdPrint(("KiAttachProcess:%x.",uKiAttachProcessAddr));
/*保存KiAttachProcess被DNFHook之前的头API_HOOK_HEADER_LEN个字节*/
for(uIndex=0;uIndex<API_HOOK_HEADER_LEN;uIndex++)
{
szKiAttachProcessOriginCode[uIndex]=pKiAttachProcessAddr[uIndex];
}
[/code]
TP启动之后恢复被TP修改掉的KiAttachProcess的头7个字节:
/************************************************************************/
[code]/*恢复KiAttachProcess头9个字节从而恢复KiAttachProcess-让TP失效
/*这里使用了硬编码,去掉硬编码的思路如下:
/*在TP未启动之前,先保存下KiAttachProcess的头9个字节
/*然后在TP启动之后,恢复这9个字节就OK
/************************************************************************/
VOIDRecoveryTPHookedKiAttachProcess()
{
ULONGuIndex=0;
ULONGuOldAttr=0;
KIRQLkOldIRQL=PASSIVE_LEVEL;
PUCHARpKiAttachProcessAddr=NULL;
/*获取到KiAttachProcess的地址*/
pKiAttachProcessAddr=(PUCHAR)GetKiAttachProcessAddr();
EnableWriteProtect(&uOldAttr);
kOldIRQL=KeRaiseIrqlToDpcLevel();
/*恢复KiAttachProcess的头API_HOOK_HEADER_LEN个字节*/
for(uIndex=0;uIndex<API_HOOK_HEADER_LEN;uIndex++)
{
pKiAttachProcessAddr[uIndex]=szKiAttachProcessOriginCode[uIndex];
}
KeLowerIrql(kOldIRQL);
DisableWriteProtect(uOldAttr);
KdPrint(("PassTP-KiAttachProcessInstalled."));
}
[/code]
到这里,我们又把KiAttachProcess给搞定了,所以此时咱可以用OD来附加DNF游戏进程试试看了,
此时你会发现咱可以将OD附加上去了,不过可惜的是,就算附加上去了,离使用OD来调试DNF还远着呢,
因为TP对DNF游戏进程还有其他的保护措施,它在内核里面Hook的API可不止这么点哦。
总结:
《过DNFTP驱动保护》的第二篇到这里就结束了,经过上面的处理,
我们已经过掉了TP所做InLineHook的5个API了,
首先是NtOpenProcess和NtOpenThread的深层InLineHook,
然后是SSDT系统服务函数NtReadVirtualMemory和NtWriteVirtualMemory的浅层次InLineHook,
最后我们也干掉了TP对未导出内核函数KiAttachProcess所做的浅层次InLineHook。
虽然也干掉了不少TP在内核中Hook的API了,但是这离过DNFTP驱动保护还比较远的,
详情还得留到下回分解了。
现已支持过掉最新版本的TP保护(2013年04月23日),
如有需要者(有偿提供),请联系QQ:1751048662
版权所有,[b]欢迎转载,但转载请注明:转载自[/b]
相关文章推荐
- [转载] 过 DNF TP 驱动保护
- 过 DNF TP 驱动保护(一)
- 过 DNF TP 驱动保护(一)
- 过 DNF TP 驱动保护(二)
- 过 DNF TP 驱动保护(二)
- 过DNF TP驱动保护(二)(转载)
- 过 DNF TP 驱动保护(一)
- 过 DNF TP 驱动保护(一)
- 过 DNF TP 驱动保护(二)
- 过 DNF TP 驱动保护(二)
- 过 DNF TP 驱动保护(一)
- 过 DNF TP 驱动保护(二)
- 过 DNF TP 驱动保护(一)
- 过 DNF TP 驱动保护(一)
- 过 DNF TP 驱动保护(二)
- 过TP保护之发现DNF进程(上)
- 过TP保护与解除游戏驱动保护
- 搞定QQ游戏系列(寻仙,DNF等等)驱动保护TesSafe.sys
- 过TP保护与解除游戏驱动保护
- 过TP保护与解除游戏驱动保护(可以借鉴)