首页
社区
课程
招聘
[旧帖] [求助]TP的四个HOOK都过了 OD提示无法附加游戏 0.00雪花
发表于: 2012-4-2 04:12 3916

[旧帖] [求助]TP的四个HOOK都过了 OD提示无法附加游戏 0.00雪花

2012-4-2 04:12
3916
在3月20号的时候还能 正常附加 游戏更新后 提示无法附加游戏  是不是游戏有新的HOOK?   希望各位大大能说下新加了什么HOOK 我找了几天都找不到 最后才无奈来发帖求助
下面是我的源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
/////定义全局变量///////
BYTE *NtOpenProcessAddress=NULL;
BYTE *ObOpenObjectByPointerAddress=NULL;
BYTE *returnAddress=NULL;
BYTE *NtOpenProcess_TP_HOOK=NULL;
 
 
ANSI_STRING p_str1,p_str2; //保存进程名称
#define DNF_EXE "DNF.exe" //要检索的进程名
PEPROCESS processEPROCESS = NULL; //保存访问者的EPROCESS
 
// 自定义的NtOpenProcess函数 ZwOpenProcess
#pragma PAGECODE
extern "C" NTSTATUS __declspec(naked) __stdcall MyNtOpenProcess(
    OUT     PHANDLE ProcessHandle,
    IN     ACCESS_MASK DesiredAccess,
    IN     POBJECT_ATTRIBUTES ObjectAttributes,
    IN     PCLIENT_ID ClientId )
{
     
    processEPROCESS=IoGetCurrentProcess();
    RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
    //将我们要比对的进程名放入str2
    RtlInitAnsiString(&p_str2,DNF_EXE);
   if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
   {
       __asm
       {
           push dword ptr [ebp-38h]
           push dword ptr [ebp-24h]
           call NtOpenProcess_TP_HOOK
               mov edx,returnAddress
 
               jmp edx
 
 
       }
 
 
   }
   
 
    if (RtlCompareString(&p_str1,&p_str2,TRUE) != 0)
    {
        _asm
        {
            push dword ptr [ebp-38h]
            push dword ptr [ebp-24h]
            call ObOpenObjectByPointerAddress
                mov edx,returnAddress
 
                jmp edx
 
 
        }
 
    }
    __asm
    {
        retn
    }
}
 
//HOOK 函数构建
#pragma PAGECODE
VOID Hook()
{
 
    BYTE *p = NULL; //临时
     
    KdPrint(("驱动成功被加载中.............................\n"));
    //获取NtOpenProcess的地址
    NtOpenProcessAddress = (BYTE*)MyGetFunAddress(L"NtOpenProcess");
    //获取ObOpenObjectByPointer的地址
    ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");
    
 
 
 
//将p指向NtOpenProcess函数开始处
p = NtOpenProcessAddress;
//用一个无限循环来判断给定的特征码来确定被HOOK位置
while (1)
{
    if ((*(p-7) == 0x50) &&
        (*(p-0xE) == 0x56) &&
        (*(p+0xd) == 0x50) &&
        (*(p+0x16) == 0x3b) &&
        (*(p+0x17) == 0xce) &&
        (*p == 0xE8) &&
        (*(p+5) == 0x8b) &&
        (*(p+6) == 0xf8))
    {
        KdPrint(("%0X \n",(ULONG)p));
        break;
    }
    //推动指针向前走
    p++;
}
 
///把RETURN的地址放进变量里
returnAddress=p+5;
NtOpenProcess_TP_HOOK=(BYTE*)(p+5+*(ULONG*)(p+1));
 
KdPrint((" p的地址=%x\n",p));
 
KdPrint(("MYHOOK的地址也就是 p-6的地址=%x\n",p-6));
 
 
 
 
__asm //去掉页面保护
    {
        cli
            mov eax,cr0
            and eax,not 10000h //and eax,0FFFEFFFFh
            mov cr0,eax
 
    }
 
    
    ULONG jmpaddr=(ULONG)MyNtOpenProcess-(ULONG)(p-6)-5;
 
    BYTE *pjian6=p-6;
     
    // in line hook
  __asm
  {
      mov ebx,pjian6
      mov byte ptr ds:[ebx],0xe9
      mov eax,jmpaddr
      mov DWORD ptr ds:[ebx+1],eax
      mov byte ptr ds:[ebx+6],0x90
  }
 
    __asm
    { //nt 3
        mov     eax, cr0
        or     eax, 10000h
        mov     cr0, eax
        sti
    }  
    return;
}
 
 
 
 
 
 
 
 
 
 
 
 
///////变量定义////////
BYTE *NtOpenThreadAddress=NULL;
BYTE *NtOpenThreadreturn=NULL;
BYTE *NtOpenThread_TP_HOOK=NULL;
 
 
//////////////////////////MyNtOpenThread  ////////////////////////////////////////////////
#pragma PAGECODE
extern "C" static  NTSTATUS __declspec(naked) __stdcall MyNtOpenThread()
{
 
 
 
 
    //获得调用者的EPROCESS
    processEPROCESS = IoGetCurrentProcess();
    //将调用者的进程名保存到str1中
    RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
 
    //将我们要比对的进程名放入str2
    RtlInitAnsiString(&p_str2,DNF_EXE);
 
    if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
    {
        KdPrint(("DNF访问了NtOpenThreadHook"));
 
        __asm
        {
            push dword ptr [ebp-34h]
            push dword ptr [ebp-20h]
            call NtOpenThread_TP_HOOK
                mov edx,NtOpenThreadreturn
                jmp edx
 
 
        }
    }
    if (RtlCompareString(&p_str1,&p_str2,TRUE) != 0)
    {
        KdPrint(("NtOpenThreadreturn==%x",NtOpenThreadreturn));
        KdPrint(("NtOpenThreadAddress==%x",NtOpenThreadAddress));
        __asm
        {
            push dword ptr [ebp-34h]
            push dword ptr [ebp-20h]
            call NtOpenThreadAddress
                mov edx,NtOpenThreadreturn
                jmp edx
                 
                 
 
 
        }
         
    }
    __asm
    {
        retn
    }
 
     
 
}
 
 
 
 
//////NtOpenThread的 Hook
 
 
VOID NtOpenThreadHook()
{
 
    BYTE *p = NULL; //临时
 
    KdPrint(("NtOpenThreadHook被加载中.............................\n"));
    ////获取NtOpenThreadAddress地址
    NtOpenThreadAddress=(BYTE*)MyGetFunAddress(L"NtOpenThread");
 
    //获取ObOpenObjectByPointer的地址
    ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");
 
 
 
 
 
    //将p指向NtOpenThreadAddress函数开始处
    p = NtOpenThreadAddress;
    //用一个无限循环来判断给定的特征码来确定被HOOK位置
    while (1)
    {
        if ((*(p-1) == 0xE0) &&
            (*(p-2) == 0x75) &&
            (*(p-3) == 0xFF) &&
            (*(p-4) == 0xCC) &&
             (*(p-5) == 0x75) &&
            (*p == 0xE8) &&
            (*(p+5) == 0x8b) &&
            (*(p+6) == 0xf8)&&
            (*(p+7) == 0x8D))
        {
            KdPrint(("%0X \n",(ULONG)p));
            break;
        }
        //推动指针向前走
        p++;
    }
 
    ///把RETURN的地址放进变量里
    NtOpenThreadreturn=p+5;
 
   NtOpenThread_TP_HOOK= (BYTE*)(p+5+*(ULONG*)(p+1));
 
    KdPrint((" NtOpenThread_TP_HOOK=%x\n",NtOpenThread_TP_HOOK));
     
 
 
    KdPrint((" NtOpenThreadHook的地址=%x\n",p));
 
    KdPrint(("MYHOOK的地址也就是 p-6的地址=%x\n",p-6));
 
   
 
 
    __asm //去掉页面保护
    {
        cli
            mov eax,cr0
            and eax,not 10000h //and eax,0FFFEFFFFh
            mov cr0,eax
 
    }
 
 
    ULONG jmpaddr=(ULONG)MyNtOpenThread-(ULONG)(p-6)-5;
 
    BYTE *pjian6=p-6;
 
    // in line hook
    __asm
    {
        mov ebx,pjian6
            mov byte ptr ds:[ebx],0xe9
            mov eax,jmpaddr
            mov DWORD ptr ds:[ebx+1],eax
            mov byte ptr ds:[ebx+6],0x90
    }
 
    __asm
    { //nt 3
         
        mov     eax, cr0
            or     eax, 10000h
            mov     cr0, eax
            sti
    }  
    return;
}
 
 
 
 
 
 
BYTE *KeAttachProcessAddress = NULL; //KeAttachProcess函数地址
BYTE *KiAttachProcessAddress=NULL;
BYTE *p;
BYTE MovEaxAddress[5] = {0xB8,0,0,0,0}; //
BYTE JmpEax[2] = {0xff,0xe0};
 
//特征码
BYTE Signature1 = 0x56, //p-1
Signature2 = 0x57, //p-2
Signature3 = 0x5F, //p-3
Signature4 = 0x5E, //p+5
Signature5 = 0xE8; //p第一个字节
BYTE* TP_HOOK_KI;
extern "C" NTSTATUS __declspec(naked) __stdcall MyKiAttachProcess()
{
 
    processEPROCESS=IoGetCurrentProcess();
    RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
    //将我们要比对的进程名放入str2
    RtlInitAnsiString(&p_str2,DNF_EXE);
    /*if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
    {
        KdPrint(("dnf 访问了HOOK_MyKiAttachProcess"));
        __asm
        {
            mov eax,TP_HOOK_KI
            jmp eax
        }
 
         
    }
    else
    {*/
        __asm
        {
            mov edi,edi
                push ebp
                mov ebp,esp
                push ebx
                push esi
                mov eax,KiAttachProcessAddress //注意这个是全局变量 BYTE*
                add eax,7
                jmp eax
        }
 
        __asm
        {
            retn
        }
 
    //}
   
 
     
 
}
    BYTE _bp1[]={0x8B,0xFF,0x55,0x8B,0xEC,0x53,0x56};
VOID HOOK_MyKiAttachProcess()
{
     
 
    //获得KeAttachProcess地址,然后通过特征码找到
    //KiAttachProcess的地址
    KeAttachProcessAddress = (BYTE*)MyGetFunAddress(L"KeAttachProcess");
     
    TP_HOOK_KI=(BYTE*)get_TP_kiprceoss_eaxaddrass();
     
     
    //将p指向KeAttachProcess函数开始处
    p = KeAttachProcessAddress;
    while (1)
    {
        if ((*(p-1) == Signature1) &&
            (*(p-2) == Signature2) &&
            (*(p+5) == Signature3) &&
            (*(p+6) == Signature4) &&
            (*p == Signature5))
        {
            //定位成功后取地址
            KiAttachProcessAddress = (BYTE *)*(PULONG)(p+1)+(ULONG)(p+5);
            KdPrint(("KiAttachProcessAddress==%x",KiAttachProcessAddress));
 
            break;
        }
 
        //推动指针
        p++;
    }
 
    
  // BYTE*  NtKiAttachProcess_TP_HOOK= (BYTE*)(p+5+*(ULONG*)(p+1));
 
    //计算中继函数地址
    *(ULONG *)(MovEaxAddress+1)=(ULONG)MyKiAttachProcess;
 
 
 
 
    __asm //去掉页面保护
    {
        cli
            mov eax,cr0
            and eax,not 10000h //and eax,0FFFEFFFFh
            mov cr0,eax
 
    }
    //写入
    RtlCopyMemory(KiAttachProcessAddress,MovEaxAddress,5);
    RtlCopyMemory(KiAttachProcessAddress+5,JmpEax,2);
     
    //RtlCopyMemory(KiAttachProcessAddress,_bp1,7);
 
    //恢复Irql
 
 
    __asm
    { //nt 3
 
        mov     eax, cr0
            or     eax, 10000h
            mov     cr0, eax
            sti
    }
 
 
 
 
 
 
 
}
 
 
 
 
 
 
// 名称: myGetCurrentAddress
// 功能: 获取SSDT表中指定函数的当前地址
// 参数: index:指定函数在表中的索引号
// 返回: 地址
//////////////////////////////////////////////////////////////////////
ULONG myGetCurrentAddress(IN ULONG index)
{
    ULONG SSDT_Cur_Addr;
    __asm
    {
        push ebx
            push eax
            mov ebx,KeServiceDescriptorTable
            mov ebx,[ebx]
            mov eax,index
                shl eax,2
                add ebx,eax
                mov ebx,[ebx]
                mov SSDT_Cur_Addr,ebx
                    pop eax
                    pop ebx
    }
 
    return SSDT_Cur_Addr;
}
 
 
 
 
BYTE *NtMy_RecoveryHook_NtReadAndWriteMemoryreturn=NULL;
BYTE *NtReadVirtualMemoryAddress = NULL; //NtReadVirtualMemory的地址
BYTE *NtWriteVirtualMemoryAddress = NULL; //NtWriteVirtualMemory的地址 
BYTE *NtMy_RecoveryHook_NtReadAndWrite=NULL;
 
extern "C" NTSTATUS __declspec(naked) __stdcall My_RecoveryHook_NtReadAndWriteMemory()
{
   
    __asm
    {
        push 0x1c
        push 0x804DAEE8
        mov edx,NtMy_RecoveryHook_NtReadAndWriteMemoryreturn
        jmp edx
 
    }
}
 
 
 
extern "C" NTSTATUS __declspec(naked) __stdcall My_RecoveryHook_NtReadAndWrite()
{
 
 
    processEPROCESS=IoGetCurrentProcess();
    RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
    //将我们要比对的进程名放入str2
    RtlInitAnsiString(&p_str2,DNF_EXE);
    if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
    {
        KdPrint(("dnf 访问了HOOK_My_RecoveryHook_NtReadAndWriteMemory"));
    }
 
    __asm
    {
        push 0x1c
            push 0x804DAEE8
            mov edx,NtMy_RecoveryHook_NtReadAndWrite
            jmp edx
 
    }
}
VOID HOOK_My_RecoveryHook_NtReadAndWriteMemory()
   
{
     
     
 
 
    //从SSDT表中获取NtReadVirtualMemory函数地址
    NtReadVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0xBA);
 
    //从SSDT表中获取NtWriteVirtualMemory函数地址
    NtWriteVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0x115);
     
     
     
    //写入
 
    ULONG jmpaddr=(ULONG)My_RecoveryHook_NtReadAndWriteMemory-(ULONG)(NtReadVirtualMemoryAddress)-5;
 
    ULONG jmpaddr1=(ULONG)My_RecoveryHook_NtReadAndWrite-(ULONG)(NtWriteVirtualMemoryAddress)-5;
 
 
    BYTE *pNtReadVirtualMemoryAddress=NtReadVirtualMemoryAddress;
    BYTE *pNtWriteVirtualMemoryAddress=NtWriteVirtualMemoryAddress;
 
 
 
    __asm //去掉页面保护
    {
        cli
            mov eax,cr0
            and eax,not 10000h //and eax,0FFFEFFFFh
            mov cr0,eax
 
    }
 
    NtMy_RecoveryHook_NtReadAndWriteMemoryreturn=NtReadVirtualMemoryAddress+7;
    // in line hook
    __asm
    {
        mov ebx,pNtReadVirtualMemoryAddress
            mov byte ptr ds:[ebx],0xe9
            mov eax,jmpaddr
            mov DWORD ptr ds:[ebx+1],eax
             
    }
 
    NtMy_RecoveryHook_NtReadAndWrite=NtWriteVirtualMemoryAddress+7;
    __asm
    {
        mov ebx,pNtWriteVirtualMemoryAddress
            mov byte ptr ds:[ebx],0xe9
            mov eax,jmpaddr1
            mov DWORD ptr ds:[ebx+1],eax
 
    }
     
    __asm  //回复保护
    { //nt 3
 
        mov     eax, cr0
            or     eax, 10000h
            mov     cr0, eax
            sti
    }
 
 
 
 
}

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

收藏
免费
支持
分享
最新回复 (9)
雪    币: 238
活跃值: (55)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
楼主头像挺好看
2012-4-2 08:46
0
雪    币: 32
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
同问
我也是过掉了
NtOpenThread    //防止调试器在它体内创建线程
NtOpenProcess   //防止OD等在进程列表看到它
KiAttachProcess   //防止其他软件附加它
NtReadVirtualMemory  //防止别人读取它的内存
NtWriteVirtualMemory  //防止别人在它的内存里面乱写乱画
怎么还是没有附加
2012-5-26 15:00
0
雪    币: 46
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
应该是我们的技术理论和技巧学的不好吧 这样的学习何时才能符合工程师的标准
同求
2013-2-23 13:44
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
各种清零之类的
2013-2-24 21:38
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
6
清零没搞。~~~
2013-2-25 16:01
0
雪    币: 64
活跃值: (60)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
清零没过会附加失败?楼上的写过驱动没?
2013-2-25 16:46
0
雪    币: 64
活跃值: (60)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
明显是DNF4月份更新了,添加了几个新的钩子。
现在这几个钩子又没有了,驱动相对来说容易过了。
Ring3加入了动态代码校验,使得Win7 64位OD附加后网络连接中断。
2013-2-25 16:49
0
雪    币: 64
活跃值: (60)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
明显是DNF4月份更新了,添加了几个新的钩子。
现在这几个钩子又没有了,驱动相对来说容易过了。
Ring3加入了动态代码校验,使得Win7 64位OD附加后网络连接中断。
2013-2-25 16:49
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
这才3月15啊。楼上的都穿越了。
2013-3-13 22:45
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册