首页
社区
课程
招聘
[原创]对64位下*P的学习(不用过PG)
2015-3-29 16:48 52866

[原创]对64位下*P的学习(不用过PG)

2015-3-29 16:48
52866
前不久研究了一些32位下各种保护,收获颇多,但是在32位下由于内存限制所以,卡卡的感觉让人很不爽,于是研究了一下64为下的保护。

     测试游戏:JFZR  环境:win7 x64

     一:首先是双击调试,我之前发过一篇帖子,总结过双击调试的一些关键变量之类的东西,64位和32位基本想通,详细的可以看我之前的帖子,地址:http://bbs.pediy.com/showthread.php?t=196149
PS:过双击调试的时候要打一下PG的补丁,以为要替换那几个全局变量,还有就是Inline Hook IoAllocateMdl这个函数。这里再贴一下代理函数:
PMDL newIoAllocateMdl(
        __in_opt PVOID  VirtualAddress,
        __in ULONG  Length,
        __in BOOLEAN  SecondaryBuffer,
        __in BOOLEAN  ChargeQuota,
        __inout_opt PIRP  Irp  OPTIONAL)
{

        if (VirtualAddress == KdEnteredDebugger)
        {
                //DbgPrint("[KdEnteredDebugger] address: %p\n", KdEnteredDebugger);
                VirtualAddress = (PUCHAR)KdEnteredDebugger + 0x30;  
        }

        return oldIoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp);
}


    二:双击调试过了之后,开始对关键点下访问断点(全局调试对象权限,DebugPort),发现*P并没有对DebugPort做清零,而是只对全局调试对象权限做了清零处理,难道没有了DebugPort清零?于是自己写了个程序对程序模拟的试了一下DebugPort清零(在未打PG补丁的情况下),结果就是触发PG蓝屏。也就是说64位下如果对DebugPort清零就会触发PG。
        但是对全局对象权限的清零并不会触发PG。处理方法就是简单粗暴地用DPC定时器把权限给写回去:
// 用于全局调试对象权限的计时器   500ms写一次
VOID TimerRoutine(
  _In_      struct _KDPC *Dpc,
  _In_opt_  PVOID DeferredContext,
  _In_opt_  PVOID SystemArgument1,
  _In_opt_  PVOID SystemArgument2
  )
{
  UNREFERENCED_PARAMETER(Dpc);
  UNREFERENCED_PARAMETER(DeferredContext);
  UNREFERENCED_PARAMETER(SystemArgument1);
  UNREFERENCED_PARAMETER(SystemArgument2);

  LARGE_INTEGER lTime = { 0 };
  ULONG ulMicroSecond = 0;

  //将定时器的时间设置为500ms
  ulMicroSecond = 500000;
  //将32位整数转化成64位整数
  lTime = RtlConvertLongToLargeInteger(-10 * ulMicroSecond);

  DbgPrint("dpc Timer...\n");
  KIRQL irql;
  irql = WPOFF();
  *(PULONG_PTR)ul_ValidAccessMask_Addr = 0x1f000f;
  WPON(irql);

  KeSetTimer(&Timer, lTime, &myDpc);
}


      写回权限之后,然后用XT把一些回调结束掉,就发现可以使用OD附加了,但是又遇到情况了,OD附加后,F9运行,游戏却莫名的退出了。在32位调试*p的时候也遇到过这种情况,当时是*p对线程计数做了手脚,于是我列了一下线程,发现并没有异常,于是打开XT检测了一下R3的HOOK,
当我尝试恢复KiUserExceptionDispatcher这个Hook的时候,游戏居然也跟着退出了,习惯性的拿起WinDbg对这个函数下了访问断点,结果如下图:



大体的跟了一下,可以确定这个19号线程是一个检测线程,我先是对此线程挂起,然后发现KiUserExceptionDispatcher这个函数可以正常恢复了,

后来我更暴力的把这个线程直接干掉了,也是没有问题的,发现*P对此线程也没有做保护等处理。

处理完这个线程之后居然可以OD附加调试,硬断,F2都是正常的。附图:



后续:
发现X64位下的*p强度好低,也可能是我调试的游戏强度略低,最后附上源码,并且感谢TA大牛提供的64位教程资料。

新手发帖无任何技术含量,望大牛轻喷~
声明:本文只供计数交流,代码切勿用于非法途径
Test.rar

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 4
打赏
分享
最新回复 (98)
雪    币: 2867
活跃值: (1091)
能力值: ( LV12,RANK:215 )
在线值:
发帖
回帖
粉丝
scxc 3 2015-3-29 16:56
2
0
学习了,mark一下,火钳刘明
雪    币: 376
活跃值: (87)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
蛋蛋好疼 2015-3-29 16:59
3
0
大牛技术资料可否分享下
雪    币: 8
活跃值: (120)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
duanqiang 2015-3-29 17:43
4
0
膜拜看雪的大神;菜鸟路过
雪    币: 294
活跃值: (119)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
zfdyq 1 2015-3-29 17:58
5
0
我看的TA那套教程
雪    币: 78
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
whypro 2015-3-29 18:21
6
0
学习了,mark一下.
雪    币: 84
活跃值: (92)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
rozbo 2015-3-29 18:28
7
0
这个必须mark
雪    币: 155
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yxwdjsw 2015-3-29 18:59
8
0
学习了,谢谢分享
雪    币: 144
活跃值: (335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
人在塔在 2015-3-29 19:05
9
0
mark谢谢分享
雪    币: 5459
活跃值: (1390)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
浙江螃蟹 2015-3-29 19:09
10
0
这个要学习的。。
雪    币: 11
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
aLevel 2015-3-29 19:24
11
0
楼主好人,不过如果能把调试的步骤说得详细点就更好了。比如怎么知道(计算)出那个线程ID的
雪    币: 60
活跃值: (424)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
褐眼男子 1 2015-3-29 19:35
12
0
学习了感谢
雪    币: 35
活跃值: (567)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guotouck 2015-3-29 19:36
13
0
求给传送门  
十分感觉
雪    币: 376
活跃值: (87)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
蛋蛋好疼 2015-3-29 19:39
14
0
是 Tesla.Angela 吗
雪    币: 11
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
aLevel 2015-3-29 19:45
15
0
PsSetCreateProcessNotifyRoutine((PCREATE_PROCESS_NOTIFY_ROUTINE)NotifyAddr, TRUE);
这个是FALSE吧?
雪    币: 294
活跃值: (119)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
zfdyq 1 2015-3-29 20:01
16
0
[QUOTE=aLevel;1362081]PsSetCreateProcessNotifyRoutine((PCREATE_PROCESS_NOTIFY_ROUTINE)NotifyAddr, TRUE);
这个是FALSE吧?[/QUOTE]
true是remove 可以仔细看一下api
雪    币: 294
活跃值: (119)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
zfdyq 1 2015-3-29 20:04
17
0
那个线程你下kiuserexcrptiondispatcher访问断点可以找到,帖子上也说了:)
雪    币: 163
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sinmon 2015-3-29 20:39
18
0
Mark
雪    币: 318
活跃值: (41)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
网监张局 1 2015-3-29 21:32
19
0
X64 天生就是过保护的
那些猥琐的inlineHook , IDT hook 都是禁止的
多好的64位
雪    币: 294
活跃值: (119)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
zfdyq 1 2015-3-29 21:37
20
0
是啊,X64确实造福大众
雪    币: 178
活跃值: (125)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
子琳 2015-3-29 21:39
21
0
枫哥精华帖,必须顶!向枫哥学习!
雪    币: 294
活跃值: (119)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
zfdyq 1 2015-3-29 22:14
22
0
http://bbs.pediy.com/showthread.php?t=187348&highlight=64
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pedipaj 2015-3-29 23:05
23
0
mark
好贴
雪    币: 9941
活跃值: (2138)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
VCKFC 2015-3-29 23:08
24
0
VOID InitKillThread()
{
        //get pspterminatethreadbypointer
        ULONG32 callcode = 0;
        ULONG64 AddressOfPspTTBP = 0, AddressOfPsTST = 0, i = 0;
        PETHREAD Thread = NULL;
        PEPROCESS tProcess = NULL;
        NTSTATUS status = 0;
        if (PspTerminateThreadByPointer == NULL)
        {
                AddressOfPsTST = (ULONG64)GetFunctionAddr(L"PsTerminateSystemThread");
                if (AddressOfPsTST == 0)
                        return STATUS_UNSUCCESSFUL;
                for (i = 1; i < 0xff; i++)
                {
                        if (MmIsAddressValid((PVOID)(AddressOfPsTST + i)) != FALSE)
                        {
                                if (*(BYTE *)(AddressOfPsTST + i) == 0x01 && *(BYTE *)(AddressOfPsTST + i + 1) == 0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
                                {
                                        RtlMoveMemory(&callcode, (PVOID)(AddressOfPsTST + i + 2), 4);
                                        AddressOfPspTTBP = (ULONG64)callcode + 5 + AddressOfPsTST + i + 1;
                                }
                        }
                }
                PspTerminateThreadByPointer = (PSPTERMINATETHREADBYPOINTER)AddressOfPspTTBP;
                DbgPrint("PspTerminateThreadByPointer:%p\n", PspTerminateThreadByPointer);
        }
}

这能编译?什么编译器啊?
我读书少,不要骗我 !
雪    币: 294
活跃值: (119)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
zfdyq 1 2015-3-29 23:10
25
0
VS2013+WDK8.1~
游客
登录 | 注册 方可回帖
返回