zoukankan      html  css  js  c++  java
  • [转载] 关于Win7 x64下过TP保护的一些思路,内核层过保护,驱动过保护

    首先特别感谢梦老大,本人一直没搞懂异常处理机制,看了他的教程之后终于明白了。
    在他的教程里我学到了不少东西。
    第一次在论坛发帖,就说说Win7 x64位下怎么过TP保护。如果有讲错的地方,还望指出。
    说不定我发帖后一星期TP就会大更新呢。
    打字排版好辛苦。 
    先说说内核层,看大家的反应后再说说应用层的保护。(包括解决CE非法问题)

    调试对象:DXF
    调试工具:OD、Windbg
    调试环境:Win7 SP1 X64

    调试先言:我记得TP最近的一次大更新是在去年的暑假,在那之前的ring0保护和现在的已经大有不同了。
    不过还是少不了DebugPort清零。


    内核层部分:
    x64下因为有PatchGuard的限制,很多保护都被巨硬给抹掉了。
    比如SSDT Hook Inline Hook 所以TP无法继续使用这些保护手段了。
    除非腾Xun冒着被巨硬吊销数字签名的风险来阻止我们调试。
    我曾经在看雪论坛里看过有个人写的文章,它亲自测试在x64环境下清零调试端口,结果发生了蓝屏,
    所以在x64下TP是不会清零的。这样就省了不少的事情。
    但是自从那次TP大更新后新加入了ValidAccessMask清零。
    那么在ring0中 TP除了ValidAccessMask清零,还有反双机调试,这里不是我们讨论的范畴。
    我们只是讨论如何才能正常调试游戏,于是在内核层我们只要解决ValidAccessMask清零就可以了。

    调试权限(ValidAccessMask)的清零
    这个标志位其实是DebugObject (调试对象)的权限,如果为0将导致无法创建调试对象(缺少权限)。
    常见的情况就是OD无法附加任何进程,这个保护刚刚出的时候很多菜鸟都没搞懂,包括我自己(知道被我师傅说我等级太低时的心情是什么?)。
    这个DebugObject在很多调试函数中都有用到 ,比如NtCreateDebugObject就有需要访问调试对象。
    所以要想办法恢复这个标志位。
    我们有三种选择:1、自己恢复原来的值 2、找到TP清零的位置Nop掉 3、移位(重建DebugObject)
    这里我选择了第一种。

    具体步骤如下:
    ①定位DebugObject:
    在NtCreateDebugObject里就有DebugObject的地址。
    1: kd> uf NtCreateDebugObject
    nt!NtCreateDebugObject:
    fffff800`042697a0 48895c2408      mov     qword ptr [rsp+8],rbx
    fffff800`042697a5 4889742410      mov     qword ptr [rsp+10h],rsi
    fffff800`042697aa 57              push    rdi
    fffff800`042697ab 4883ec70        sub     rsp,70h
    fffff800`042697af 418bf9          mov     edi,r9d
    fffff800`042697b2 8bf2            mov     esi,edx
    fffff800`042697b4 488bd9          mov     rbx,rcx
    fffff800`042697b7 65488b042588010000 mov   rax,qword ptr gs:[188h]
    fffff800`042697c0 448a90f6010000  mov     r10b,byte ptr [rax+1F6h]
    fffff800`042697c7 4584d2          test    r10b,r10b
    fffff800`042697ca 7414            je      nt!NtCreateDebugObject+0x40 (fffff800`042697e0)
    nt!NtCreateDebugObject+0x2c:
    fffff800`042697cc 488b052d38e5ff  mov     rax,qword ptr [nt!MmUserProbeAddress (fffff800`040bd000)]
    fffff800`042697d3 483bc8          cmp     rcx,rax
    fffff800`042697d6 480f43c8        cmovae  rcx,rax
    fffff800`042697da 488b01          mov     rax,qword ptr [rcx]
    fffff800`042697dd 488901          mov     qword ptr [rcx],rax
    nt!NtCreateDebugObject+0x40:
    fffff800`042697e0 48832300        and     qword ptr [rbx],0
    fffff800`042697e4 41f7c1feffffff  test    r9d,0FFFFFFFEh
    fffff800`042697eb 740a            je      nt!NtCreateDebugObject+0x57 (fffff800`042697f7)
    nt!NtCreateDebugObject+0x4d:
    fffff800`042697ed b80d0000c0      mov     eax,0C000000Dh
    fffff800`042697f2 e9e4000000      jmp     nt!NtCreateDebugObject+0x13b (fffff800`042698db)
    nt!NtCreateDebugObject+0x57:
    fffff800`042697f7 488d442450      lea     rax,[rsp+50h]
    fffff800`042697fc 4889442440      mov     qword ptr [rsp+40h],rax
    fffff800`04269801 8364243800      and     dword ptr [rsp+38h],0
    fffff800`04269806 8364243000      and     dword ptr [rsp+30h],0
    fffff800`0426980b c744242868000000 mov     dword ptr [rsp+28h],68h
    fffff800`04269813 488364242000    and     qword ptr [rsp+20h],0
    fffff800`04269819 458aca          mov     r9b,r10b
    fffff800`0426981c 488b158dd3daff  mov     rdx,qword ptr [nt!DbgkDebugObjectType (fffff800`04016bb0)]
    fffff800`04269823 418aca          mov     cl,r10b
    fffff800`04269826 e84572f1ff      call    nt!ObCreateObject (fffff800`04180a70)
    fffff800`0426982b 4c8b4c2450      mov     r9,qword ptr [rsp+50h]
    fffff800`04269830 4c894c2460      mov     qword ptr [rsp+60h],r9
    fffff800`04269835 85c0            test    eax,eax
    fffff800`04269837 0f889e000000    js      nt!NtCreateDebugObject+0x13b (fffff800`042698db)
    这个红字就是了 
    继续定位ValidAccessMask的地址。

    1: kd> dq fffff800`04016bb0
    fffff800`04016bb0  fffffa80`00c33200 00000000`00000000
    fffff800`04016bc0  fffff8a0`0009a010 0000002a`00000012
    fffff800`04016bd0  00000024`000000a1 fffff880`0119d9a0
    fffff800`04016be0  00000002`00000001 fffff880`095deacc
    fffff800`04016bf0  fffff800`03f873f0 00000000`00000007
    fffff800`04016c00  00000003`00000000 fffff800`03e10448
    fffff800`04016c10  fffffa80`01bae060 00000000`00000000
    fffff800`04016c20  00000000`00000000 00000003`00000101

    1: kd> dt _OBJECT_TYPE fffffa80`00c33200
    nt!_OBJECT_TYPE
       +0x000 TypeList         : _LIST_ENTRY [ 0xfffffa80`00c33200 - 0xfffffa80`00c33200 ]
       +0x010 Name             : _UNICODE_STRING "DebugObject"
       +0x020 DefaultObject    : (null) 
       +0x028 Index            : 0xb ''
       +0x02c TotalNumberOfObjects : 0
       +0x030 TotalNumberOfHandles : 0
       +0x034 HighWaterNumberOfObjects : 0
       +0x038 HighWaterNumberOfHandles : 0
      +0x040 TypeInfo         : _OBJECT_TYPE_INITIALIZER
       +0x0b0 TypeLock         : _EX_PUSH_LOCK
       +0x0b8 Key              : 0x75626544
       +0x0c0 CallbackList     : _LIST_ENTRY [ 0xfffffa80`00c332c0 - 0xfffffa80`00c332c0 ]

    1: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`00c33200+40
    nt!_OBJECT_TYPE_INITIALIZER
       +0x000 Length           : 0x70
       +0x002 ObjectTypeFlags  : 0x8 ''
       +0x002 CaseInsensitive  : 0y0
       +0x002 UnnamedObjectsOnly : 0y0
       +0x002 UseDefaultObject : 0y0
       +0x002 SecurityRequired : 0y1
       +0x002 MaintainHandleCount : 0y0
       +0x002 MaintainTypeList : 0y0
       +0x002 SupportsObjectCallbacks : 0y0
       +0x002 CacheAligned     : 0y0
       +0x004 ObjectTypeCode   : 0
       +0x008 InvalidAttributes : 0
       +0x00c GenericMapping   : _GENERIC_MAPPING
       +0x01c ValidAccessMask  : 0x1f000f
       +0x020 RetainAccess     : 0
       +0x024 PoolType         : 0 ( NonPagedPool )
       +0x028 DefaultPagedPoolCharge : 0
       +0x02c DefaultNonPagedPoolCharge : 0x58
       +0x030 DumpProcedure    : (null) 
       +0x038 OpenProcedure    : (null) 
       +0x040 CloseProcedure   : 0xfffff800`042b18e0     void  nt!DbgkpCloseObject+0
       +0x048 DeleteProcedure  : 0xfffff800`04105200     void  nt!xHalEndOfBoot+0
       +0x050 ParseProcedure   : (null) 
       +0x058 SecurityProcedure : 0xfffff800`04170530     long  nt!SeDefaultObjectMethod+0
       +0x060 QueryNameProcedure : (null) 
       +0x068 OkayToCloseProcedure : (null) 

    于是我们就定位到了VaildAccessMask的地址了。

    ②恢复工作
    它的默认值是0x1F000F
    当我们自己手动修改成0时。
    使用OD附加任意进程。


    <ignore_js_op> 
    无法附加,那我们就要手动恢复成0x1F000F。
    具体方式我采用开DPC定时器的方法恢复,恢复的频率不会和TP的冲突。
    代码我贴出一部分,部分函数需要自己手动编写,因为在64位下编写驱动寻找SSDT等都比较麻烦。
    这些函数大家可以去网上一些x64驱动编写的教程里面抄下。
    我在这里推荐下Tesla.Angela的教程《WIN64驱动编程基础教程》

      1. #ifndef PROC
      2. #define PROC
      3. PVOID pNtCreateDebugObject;
      4. PVOID pDbgkDebugObject;
      5. PVOID pDebugObject;
      6. PVOID pValidMask;
      7. KTIMER PassObjTimer;
      8. KDPC PassObjDpc;
      9. LARGE_INTEGER PassObjTime;
      10. PVOID pKeStackAttachProcess;
      11. PVOID pKeStackAttachProcessJmpAddr;
      12. byte  bufKeStackAttachProcess[13];
      13. VOID
      14. PassObj(
      15. __in struct _KDPC  *Dpc,
      16. __in_opt PVOID  DeferredContext,
      17. __in_opt PVOID  SystemArgument1,
      18. __in_opt PVOID  SystemArgument2
      19. )
      20. {
      21.         __try
      22.         {
      23.                 WriteProtectOff();
      24.                 *((ULONG*)pValidMask) = 0x1F000F;
      25.                 WriteProtectOn();
      26.         }
      27.         __except (1)
      28.         {
      29.                 KeCancelTimer(&PassObjTimer);
      30.                 return;
      31.         }
      32.         KeSetTimer(&PassObjTimer, PassObjTime, &PassObjDpc);
      33.         return;
      34. }
      35. VOID PassObjectMask()
      36. {
      37.         PVOID pTargetAddr;
      38.         pNtCreateDebugObject = (PVOID)GetSSDTFunctionAddress(144);
      39.         pTargetAddr = (PVOID)(((ULONG64)pNtCreateDebugObject) + 0x7C);
      40.         pDbgkDebugObject=(PVOID)(MAKE_TARGETADDR((*((ULONG*)(((ULONG64)pTargetAddr) + 3))), (ULONG64)pTargetAddr));
      41.         pDebugObject = (PVOID)(*((ULONG64*)pDbgkDebugObject));
      42.         pValidMask = (PVOID)(((ULONG64)pDebugObject) + 0x40 + 0x1c);
      43.         PassObjTime.QuadPart = -10000 * 100;
      44.         KeInitializeTimer(&PassObjTimer);
      45.         KeInitializeDpc(&PassObjDpc, &PassObj, NULL);
      46.         KeSetTimer(&PassObjTimer, PassObjTime, &PassObjDpc);
      47. }
      48. VOID UnPassObjectMask()
      49. {
      50.         KeCancelTimer(&PassObjTimer);
      51. }
      52. #endif

    非常感谢大家那么支持我上一篇教程。
    Win10 快出了,所以我打算尽快把应用层的部分说完。


    调试对象:DXF
    调试工具:CE、OD、PCHunter、Windbg
    调试先言:TP的应用层保护做得比较多,包括对调试器的检测,比如CE工具会被DXF报非法。有的保护还是内核与应用层交替保护。

    应用层:
    1、TP让调试器卡死(内核互动)
    现象: <ignore_js_op> 
    如图,TP会检测调试器让调试器暂停运行,实际上就是暂停了调试器所有的线程而已。
    这个保护是今年7月份新出的,所以我这里重点分析下,我刚开始调试的时候就发现OD会莫名其妙地卡死。
    打开PCHunter发现OD的进程线程全部被暂停了。
    开始我认为是TP调用了SuspendThread(函数:暂停指定线程)来让调试器卡死的。
    于是我就打开Windbg附加并在这个函数上下断点,发现没有断下来。
    然后我认为是调用了接口函数NtSuspendThread(函数:暂停指定线程<内核接口>)
    但是还是没有断下。所以排除了DXF在Ring3调用了暂停线程让OD卡死。
    于是我思考了一下,打开虚拟机,简单过了双机调试保护(一段时间后还是会蓝屏),在DXF启动之后,
    在Windbg输入!process OD的进程ID 来查看线程的调用堆载,我发现了很有意思的东西。
    SuspendCount被置为了1,再看看调用堆载。
    原来TP在Ring0中调用了KiSuspendThread来暂停OD的线程啊。怪不得断不下来。
    于是我在KiSuspendThread头部下断点,发现当OD打开的时候会断下,
    这个是它的函数开头
    0: kd> u KiSuspendThread
    nt!KiSuspendThread:
    fffff800`03e6cc60 48895c2408      mov     qword ptr [rsp+8],rbx
    fffff800`03e6cc65 4889742410      mov     qword ptr [rsp+10h],rsi
    fffff800`03e6cc6a 57              push    rdi
    fffff800`03e6cc6b 4883ec30        sub     rsp,30h
    fffff800`03e6cc6f 8364245800      and     dword ptr [rsp+58h],0
    fffff800`03e6cc74 65488b1c2588010000 mov   rbx,qword ptr gs:[188h]
    fffff800`03e6cc7d 4885db          test    rbx,rbx
    它还保留着用__stdcall的调用约定,在64位下一般都是__fastcall
    通过对参数的分析,我发现这个函数的第一个参数也就是rbx,里面存的是线程对象。
    我在网上也没有找到相关的信息,于是我自己在头部改成了ret。
    之后运行OD就不会卡死了。
    继续深究,原来TP创建了一个内核回调,就是CreateProcess的回调,
    自己可以打开PCHunter查看。
    当发现是OD的进程被创建时,就会调用这个函数让进程暂停。
    哦,原来是这样,那我们有什么办法解决它呢?怎么才能让调试器正常运行呢?
    方案:1、自己恢复调试器的进程(推荐) 2、删除内核回调(驱动推荐)3、Hook KiSuspendThread 绕过(稍难)
    在这里我推荐第一种,因为我们是要在应用层下操作。
    方法很简单,当我们打开OD工具时,打开PCHunter选择OD的进程,右键恢复进程运行即可。
    也可以自己做一个工具,恢复OD的进程,但是你要确保自己的程序不会进入黑名单。
    至此,我们的调试器能正常打开了。

    2、函数钩子(Hook)
    这个保护不能说是新鲜了的吧,在应用层里很多游戏都这么干。
    其实就是把一些重要的调试函数进行钩子,导致程序崩溃或者无法调试。
    我们打开PCHunter,来到如图的位置,选择DXF的进程->右键选择扫描。
    <ignore_js_op> 
    现在你只需要坐下等大约5分钟吧,好像有一千多个钩子(笑),要有耐心。
    看到图中3个钩子了吗,它就是我们要说的。
    我这里来说明下这3个函数的用途。

    DbgUiRemoteBreakin:远程中断,附加调试器时调试器会发送信息让进程走这里。
    KiUserExceptionDispatcher:UEF异常处理函数,梦老大讲解过的,这个我们不能随便恢复,干脆不用管它
    因为DXF自己制造异常自己处理。
    LdrInitalizeThunk:映像文件链入口,当DLL载入时会经过这里,如果我们不恢复它将无法注入DLL。

    这3个钩子有两个是我们必须恢复的,就是一和三。
    第三个比较好处理,PCHunter中已经给出了函数原来的机器码。我们之间用PCHunter恢复也可以自己写个程序恢复
    但是第一个就不好了,我们必须用程序自己来恢复,因为:
    <ignore_js_op> 
    红线部分是需要重定位的,机器每次开机都会不同,我们可以通过获取自己程序的这个位置的代码来恢复。
    具体怎么恢复这里就不说了,我会贴出代码给大家。
    那么2个Hook搞定后我们就要来解决崩溃问题了。

    3、异常崩溃
    大家可以发现OD附加DXF后运行,游戏会莫名其妙地崩溃,你可能会认为OD被DXF检测到了,其实它是个通用
    的反调试的手法。
    自己给自己制造异常,自己处理,如果OD抢着处理这个异常,反而会使进程崩溃。
    这个就是它异常崩溃的原理。
    其实是一个线程在自发异常的,怎么把它揪出来呢?
    打开Windbg,附加DXF,运行,可以发现一段时间后,Windbg断下
    如图所示:
    <ignore_js_op> 
    线程ID:F08 发送了一个内存访问异常(0x80000002)它故意让Windbg断下。
    它需要试探是否有调试器,于是我们就找到它了,把f08换成十进制发现是
    3848的线程发送异常的,在PCHunter中可以看到,如图所示,它是由ntdll.dll发送的。
    唯一的办法就是结束这个线程,右键->结束线程,搞定,OD附加DXF不会崩溃了。
    但是你得自己做个程序来找到这条线程然后来结束掉,可以通过搜索线程入口特征码的方式来
    找到它。
    那么现在,我们调试DXF再也没有问题了。但是CE工具开启久了也会被提示非法,怎么办?

    4、检测非法工具
    也许大家非常想要知道怎么办。
    它检测非法工具的原理是:
    使用ReadProcessMemory(函数:读取进程内存)搜索进程特征码,找到属于非法工具的特征码后游戏消失,提示非法重启。
    若想解决它,我们有以下方案:
    1、删除工具中的特征码 2、在内核中拦截NtReadVirtualMemory或KeStackAttachProcess来绕过搜索
    3、找到搜索的线程,结束该线程。

    其实我发现第3种是一劳永逸,所以我在这里说下第三种方法。
    打开PCHunter找到如下几条线程。选择后同时右键结束,OK,CE再也不会非法了。
    <ignore_js_op> 
    这几条线程都是TenSLX.dll模块里的,其实这个方法在腾Xun游戏里面通用。
    别问我是怎么知道的,其实我是一个个试过的(笑)。

    5、关于CRC代码自校验
    通过上面的说明,大家应该可以总结一个结论
    在应用层中游戏若想保护自己都是采用走线程或Hook方式。
    所以大家可以自己找到CRC代码自校验的线程吧?结束掉,OK,可以下软件断点(int 3)了。

    结束语:
    别以为这样就能在DXF里为所欲为了,还有三方检测等着你呢!
    这些还需要靠大家自己多去练习,总结规律,其实你会发现,
    再难的保护还都是这样子的了(笑)......

    附赠代码(部分):

    1. void CAnitTP_AppDlg::OnBnClickedButtonAnit()
    2. {
    3.         DWORD pid = GetProcessIdByProcName(TEXT("DNF.exe"));
    4.         if (pid==0)
    5.         {
    6.                 MessageBox(TEXT("对不起,没有找到指定游戏进程.(DNF.exe)"), TEXT("操作失败"), MB_OK | MB_ICONERROR);
    7.                 return;
    8.         }
    9.         const BYTE code[8] = {0x90,0x90,0x90,0x90,0x90,0x55,0x8b,0xec};
    10.         const BYTE code2[13] = { 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 ,0xE9};
    11.         
    12.         DWORD trds[521];
    13.         int trdcount=0;
    14.         trdcount=GetProcessThreadId(pid, trds);
    15.         LPVOID pEntryPoint=NULL;
    16.         BYTE buf[13];
    17.         HANDLE hThread;
    18.         for (int i = 0; i < trdcount;i++)
    19.         {
    20.                 pEntryPoint=GetThreadEntryPointById(trds[i]);
    21.                 ReadProcessMemoryEx(pid, pEntryPoint, buf, 8);
    22.                 TCHAR ModuleName[256];
    23.                 GetProcessThreadModuleNameByTid(pid, trds[i], ModuleName);
    24.                 
    25.                 if (memcmp(buf, code, 8) == 0 || lstrcmp(ModuleName, L"TenSLX.dll")==0)
    26.                 {
    27.                         hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, trds[i]);
    28.                         if (!hThread)continue;
    29.                         TerminateThread(hThread,0);
    30.                         CloseHandle(hThread);
    31.                         
    32.                 }
    33.                 
    34.                 ReadProcessMemoryEx(pid, (LPVOID)((int)pEntryPoint - 0xc), buf, 13);
    35.                 if (memcmp(buf, code2, 13) == 0)
    36.                 {
    37.                         hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, trds[i]);
    38.                         if (!hThread)continue;
    39.                         SuspendThread(hThread);
    40.                         CloseHandle(hThread);
    41.                 }
    42.         }
    43.         
    44.         byte code3[7] = { 0x6A, 0x08, 0x68, 0x00, 0x00, 0x00, 0x00 };
    45.         LPVOID pDbgUiRemoteBreakin = (LPVOID)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "DbgUiRemoteBreakin");   //调试用
    46.         memcpy(&code3[3], (LPVOID)((int)pDbgUiRemoteBreakin + 3), 4);
    47.         WriteProcessMemoryEx(pid, pDbgUiRemoteBreakin, code3, 7);
    48.         byte code4[6] = { 0x8b, 0xff, 0x55, 0x8b, 0xec, 0xff };
    49.         LPVOID pLdrInitializeThunk = (LPVOID)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "LdrInitializeThunk");  //DLL注入用
    50.         WriteProcessMemoryEx(pid, pLdrInitializeThunk, code4, 6);
    51.         MessageBox(TEXT("操作完毕,开始调试吧!"),TEXT("OK"),MB_OK|MB_ICONINFORMATION);
    52. }
    复制代码

    功能函数头文件:

    1. #ifndef HANSHU
    2. #define HANSHU
    3. #include <TlHelp32.h>
    4. #include <psapi.h>
    5. #pragma comment(lib,"psapi.lib")
    6. typedef enum _THREADINFOCLASS {
    7.         ThreadBasicInformation,
    8.         ThreadTimes,
    9.         ThreadPriority,
    10.         ThreadBasePriority,
    11.         ThreadAffinityMask,
    12.         ThreadImpersonationToken,
    13.         ThreadDescriptorTableEntry,
    14.         ThreadEnableAlignmentFaultFixup,
    15.         ThreadEventPair_Reusable,
    16.         ThreadQuerySetWin32StartAddress,
    17.         ThreadZeroTlsCell,
    18.         ThreadPerformanceCount,
    19.         ThreadAmILastThread,
    20.         ThreadIdealProcessor,
    21.         ThreadPriorityBoost,
    22.         ThreadSetTlsArrayAddress,
    23.         ThreadIsIoPending,
    24.         ThreadHideFromDebugger,
    25.         ThreadBreakOnTermination,
    26.         MaxThreadInfoClass
    27. } THREADINFOCLASS;
    28. typedef struct _CLIENT_ID {
    29.         HANDLE UniqueProcess;
    30.         HANDLE UniqueThread;
    31. } CLIENT_ID;
    32. typedef CLIENT_ID *PCLIENT_ID;
    33. typedef struct _THREAD_BASIC_INFORMATION { // Information Class 0
    34.         LONG     ExitStatus;
    35.         PVOID    TebBaseAddress;
    36.         CLIENT_ID ClientId;
    37.         LONG AffinityMask;
    38.         LONG Priority;
    39.         LONG BasePriority;
    40. } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
    41. typedef LONG (__stdcall *fZwQueryInformationThread) (
    42.         IN HANDLE ThreadHandle,
    43.         IN THREADINFOCLASS ThreadInformationClass,
    44.         OUT PVOID ThreadInformation,
    45.         IN ULONG ThreadInformationLength,
    46.         OUT PULONG ReturnLength OPTIONAL
    47.         );
    48. fZwQueryInformationThread  ZwQueryInformationThread;
    49. DWORD GetProcessPidByWndName(LPCTSTR szWndName)
    50. {
    51.         HWND hWnd = FindWindow(NULL,szWndName);
    52.         if (IsWindow(hWnd))
    53.         {
    54.                 DWORD pid;
    55.                 GetWindowThreadProcessId(hWnd,&pid);
    56.                 return pid;
    57.         }
    58.         return 0;
    59. }
    60. DWORD GetProcessIdByProcName(LPCTSTR szProcName)
    61. {
    62.         HANDLE hSnapshot= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    63.         PROCESSENTRY32 pro;
    64.         pro.dwSize=sizeof(pro);
    65.         BOOL bMore=Process32First(hSnapshot,&pro);
    66.         while (bMore)
    67.         {
    68.                 if (lstrcmp(szProcName,pro.szExeFile)==0)
    69.                 {
    70.                         CloseHandle(hSnapshot);
    71.                         return pro.th32ProcessID;
    72.                 }
    73.                 bMore=Process32Next(hSnapshot,&pro);
    74.         }
    75.         CloseHandle(hSnapshot);
    76.         return 0;
    77. }
    78. BOOL ReadProcessMemoryEx(DWORD pid,LPVOID addr,LPVOID buffer,DWORD size)
    79. {
    80.         HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
    81.         if (hProcess==0)
    82.         {
    83.                 return FALSE;
    84.         }
    85.         BOOL bResult=ReadProcessMemory(hProcess,addr,buffer,size,NULL);
    86.         CloseHandle(hProcess);
    87.         return bResult;
    88. }
    89. BOOL WriteProcessMemoryEx(DWORD pid,LPVOID addr,LPVOID buffer,DWORD size)
    90. {
    91.         HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
    92.         if (hProcess==0)
    93.         {
    94.                 return FALSE;
    95.         }
    96.         BOOL bResult=WriteProcessMemory(hProcess,addr,buffer,size,NULL);
    97.         CloseHandle(hProcess);
    98.         return bResult;
    99. }
    100. int GetProcessThreadId(DWORD pid,DWORD *trds)
    101. {
    102.         HANDLE hSnapshot= CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,pid);
    103.         if (hSnapshot==INVALID_HANDLE_VALUE)
    104.                 return 0;
    105.         THREADENTRY32 trd;
    106.         trd.dwSize=sizeof(trd);
    107.         BOOL bMore=Thread32First(hSnapshot,&trd);
    108.         int i=0;
    109.         while (bMore)
    110.         {
    111.                 if (trd.th32OwnerProcessID==pid)
    112.                 {
    113.                         trds[i]=trd.th32ThreadID;
    114.                         i++;
    115.                 }
    116.                 bMore=Thread32Next(hSnapshot,&trd);
    117.         }
    118.         CloseHandle(hSnapshot);
    119.         return i;
    120. }
    121. LPVOID GetThreadEntryPointById(DWORD tid)
    122. {
    123.         HANDLE hThread=OpenThread(THREAD_ALL_ACCESS,FALSE,tid);
    124.         if (hThread==0)
    125.         {
    126.                 return NULL;
    127.         }
    128.         LPVOID Addr=NULL;
    129.         ZwQueryInformationThread=(fZwQueryInformationThread)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")),"ZwQueryInformationThread");
    130.         ZwQueryInformationThread(hThread,ThreadQuerySetWin32StartAddress,&Addr,4,NULL);
    131.         CloseHandle(hThread);
    132.         return Addr;
    133. }
    134. BOOL GetProcessThreadModuleNameByTid(DWORD pid, DWORD tid, LPWSTR pszModuleName)
    135. {
    136.         HANDLE hProcess = NULL;
    137.         LPVOID pStart = NULL;
    138.         TCHAR tmpStr[256];
    139.         hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    140.         if (!hProcess)return FALSE;
    141.         pStart = GetThreadEntryPointById(tid);
    142.         if (!pStart) return FALSE;
    143.         GetMappedFileName(hProcess, pStart, tmpStr, 256);
    144.         for (int i = lstrlen(tmpStr); i >0; i--)
    145.         {
    146.                 if (tmpStr[i]== '\')
    147.                 {
    148.                         lstrcpy(pszModuleName, &tmpStr[i+1]);
    149.                         break;
    150.                 }
    151.         }
    152.         CloseHandle(hProcess);
    153.         return TRUE;
    154. }
    155. void TerminateThreadEx(DWORD tid,DWORD exitcode=0)
    156. {
    157.         HANDLE hThread=OpenThread(THREAD_ALL_ACCESS,FALSE,tid);        
    158.         if (hThread!=NULL)
    159.         {
    160.                 TerminateThread(hThread,exitcode);
    161.                 CloseHandle(hThread);
    162.         }
    163.         
    164. }
    165. BOOL EnableDebugPrivilege()  
    166. {  
    167.         HANDLE token;  
    168.         //提升权限   
    169.         if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&token))  
    170.         {   
    171.                 return FALSE;  
    172.         }  
    173.         TOKEN_PRIVILEGES tkp;  
    174.         tkp.PrivilegeCount = 1;  
    175.         ::LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);  
    176.         tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
    177.         if(!AdjustTokenPrivileges(token,FALSE,&tkp,sizeof(tkp),NULL,NULL))  
    178.         {  
    179.                 return FALSE;  
    180.         }  
    181.         CloseHandle(token);  
    182.         return TRUE;  
    183. }  
    184. #endif
  • 相关阅读:
    hdu 5007 水题 (2014西安网赛A题)
    hdu 1698 线段树(成段替换 区间求和)
    poj 3468 线段树 成段增减 区间求和
    hdu 2795 公告板 (单点最值)
    UVaLive 6833 Miscalculation (表达式计算)
    UVaLive 6832 Bit String Reordering (模拟)
    CodeForces 124C Prime Permutation (数论+贪心)
    SPOJ BALNUM (数位DP)
    CodeForces 628D Magic Numbers (数位DP)
    POJ 3252 Round Numbers (数位DP)
  • 原文地址:https://www.cnblogs.com/csnd/p/11587490.html
Copyright © 2011-2022 走看看