<cite id="pnnrn"><strike id="pnnrn"><form id="pnnrn"></form></strike></cite>

        <menuitem id="pnnrn"><strike id="pnnrn"></strike></menuitem>

        <th id="pnnrn"></th>

            當前位置:手機游戲 > 手游資訊 > 新手問答 > 一篇關于xtrap保護檢測詳細的技術分析

            一篇關于xtrap保護檢測詳細的技術分析

            作者:佚名 來源:互聯網 2021-06-03 16:26:43

            一篇關于xtrap保護檢測詳細的技術分析,哪吒游戲網給大家帶來詳細的一篇關于xtrap保護檢測詳細的技術分析介紹,大家可以閱讀一下,希望這篇一篇關于xtrap保護檢測詳細的技術分析可以給你帶來參考價值。

            一篇關于xtrap保護檢測詳細的技術分析,xtrap是韓國的一款游戲保護,知名度好像不是很高,網上搜了一圈得到的信息很少,于是只能自己動手了。中途因為難度太大(對我而言)棄坑了好幾次,現在基本上放棄,遂分享一下成果。環境是win 10 64位系統下的某32位游戲。

            通過PCHunter觀察得知,該保護的驅動文件在路徑C:WindowsSysWOW64drivers下。拖進DIE中顯示驅動是沒有殼的,于是可以很高興的直接拖進IDA中。

            整個驅動文件其實不大,只有幾十kb,IDA中分析出來的函數也只有二三十個,允許我們一個個看過去。在這個驅動中有個貫穿全文的全局變量,我把它命名為XtrapGlobalData,在這里我先把我分析得到該變量有限的結構體貼出。

            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
            
            struct 
            {
              ULONG32 MajorVersion;
              ULONG32 MinorVersion;
              ULONG32 BuildNumber;
              ULONG32 Unknown1;
              WINDOWS_VERSION WindowsVersionMark;
              XTRAP_FIELD_OFFSET Offset;
              CHAR Unknown2[36];
              SYSTEM_HANDLE_TABLE_ENTRY_INFO Unknown3[2];
              ULONG64 Unknown4;
              ULONG64 ThreadHandle1;
              ULONG64 ThreadHandle2;
              ULONG32 Start;
              ULONG64 CurrentPid;
              ULONG64 CurrentEpr;
              ULONG32 Unknown5;
              XTRAP_HANDLE_INFORMATION XtrapHandleInfo;
              CHAR Unknown6[16];
              ULONG64 CallbackHandle;
              ULONG32 UnknownPid[6];
            };
            
            struct XTRAP_FIELD_OFFSET
            {
              ULONG32 KPROCESS_ThreadListHead;
              ULONG32 EPROCESS_UniqueProcessId;
              ULONG32 EPROCESS_ImageFileName;
              ULONG32 EPROCESS_InheritedFromUniqueProcessId;
              ULONG32 EPROCESS_ThreadListHead;
              ULONG32 KTHREAD_ThreadListEntry;
              ULONG32 KTHREAD_WaitMode;
              ULONG32 KTHREAD_WaitReason;
              ULONG32 KTHREAD_FreezeCount;
              ULONG32 KTHREAD_SuspendCount;
              ULONG32 ETHREAD_Win32StartAddress;
              ULONG32 ETHREAD_Cid;
              ULONG32 ETHREAD_ThreadListEntry;
              ULONG32 ETHREAD_CrossThreadFlags;
            };
            
            struct XTRAP_HANDLE_INFORMATION
            {
            	ULONG HandleCounts;
            	ULONG UniqueProcessId[30];
            	ULONG GrantedAccess[30];
            };
            

            DriverEntry

            首先初始化了設備名和符號鏈接名,從而得知了應用層和驅動層是通過設備通信的。

            1
            2
            
            memmove(&SourceString, L"\Device\X6va066", 0x20u);
            memmove(&Dst, L"\DosDevices\X6va066", 0x28u);// SymbolicLinkName
            

            使用PsGetVersion獲取版本號,確認系統版本。

            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
            
            PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, 0i64);
            WindowsVersionMark = WINDOWS_UNKNOWN0;
            if ( MajorVersion == WINDOWS_7 )
            {
                if ( MinorVersion != WINDOWS_XP_PRO_X64 )
                    return 0xC00000BB;
                WindowsVersionMark = WINDOWS_XP_PRO_X64;    // Windows XP Professional x64
            }
            if ( MajorVersion != WINDOWS_8 )
                goto LABEL_13;
            if ( !MinorVersion )
                WindowsVersionMark = WINDOWS_VISTA;         // Windows Vista
            if ( MinorVersion == 1 )
                WindowsVersionMark = WINDOWS_7;             // Windows 7
            if ( MinorVersion == 2 )
                WindowsVersionMark = WINDOWS_8;             // Windows 8
            if ( MinorVersion == 3 )
            {
                WindowsVersionMark = 7;                     // Window 8.1
                LABEL_13:
                if ( MajorVersion == WINDOWS_10_14393 && !MinorVersion )
                {                                           // Win 10
                    WindowsVersionMark = 8;                   // Win 10 under 10586 ?
                    if ( BuildNumber >= 10586 )
                        WindowsVersionMark = WINDOWS_10_10586;  // Win 10 10586
                    if ( BuildNumber >= 14393 )
                        WindowsVersionMark = WINDOWS_10_14393;  // Win 10 14393
                    if ( BuildNumber >= 15063 )
                        WindowsVersionMark = WINDOWS_10_15063;  // Win 10 15063
                    if ( BuildNumber >= 16299 )
                        WindowsVersionMark = WINDOWS_10_16299;  // Win 10 16299
                    if ( BuildNumber >= 17133 )
                        WindowsVersionMark = WINDOWS_10_17133;  // Win 10 17133
                }
            }
            if ( WindowsVersionMark == WINDOWS_UNKNOWN0 )
                return 0xC00000BB;
            

            根據系統版本,填寫一些硬編碼,比如各種結構的偏移。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            
            if ( result == WINDOWS_10_10586 )
            {
                v1_XtrapGlobalData->Offset.KPROCESS_ThreadListHead = 0x30;
                v1_XtrapGlobalData->Offset.EPROCESS_UniqueProcessId = 744;
                v1_XtrapGlobalData->Offset.EPROCESS_InheritedFromUniqueProcessId = 992;
                v1_XtrapGlobalData->Offset.EPROCESS_ImageFileName = 1104;
                v1_XtrapGlobalData->Offset.EPROCESS_ThreadListHead = 1160;
                v1_XtrapGlobalData->Offset.KTHREAD_ThreadListEntry = 0x2F8;
                v1_XtrapGlobalData->Offset.KTHREAD_WaitMode = 391;
                v1_XtrapGlobalData->Offset.KTHREAD_WaitReason = 643;
                v1_XtrapGlobalData->Offset.KTHREAD_FreezeCount = 120;
                v1_XtrapGlobalData->Offset.KTHREAD_SuspendCount = 644;
                v1_XtrapGlobalData->Offset.ETHREAD_Win32StartAddress = 1664;
                v1_XtrapGlobalData->Offset.ETHREAD_Cid = 1576;
                v1_XtrapGlobalData->Offset.ETHREAD_ThreadListEntry = 1680;
                v1_XtrapGlobalData->Offset.ETHREAD_CrossThreadFlags = 1724;
            }
            

            設置了設備的派遣函數。

            1
            2
            3
            4
            
            Device->MajorFunction[0xE] = DispatchGeneral;// IRP_MJ_DEVICE_CONTROL
            Device->MajorFunction[0] = DispatchGeneral; // IRP_MJ_CREATE
            Device->MajorFunction[2] = DispatchGeneral; // IRP_MJ_CLOSE
            Device->MajorFunction[0x12] = DispatchGeneral;// IRP_MJ_CLEANUP
            

            具體是在DispatchGeneral中判斷功能號再調用對應的Dispatcher。

            派遣函數

            總共有3個函數,DispatchCreate DispatchClose 和 DispatchIoControl 分別對應IRP_MJ_CREATE IRP_MJ_CLOSE 和 IRP_MJ_DEVICE_CONTROL。

            DispatchCreate

            該函數做了幾件事:一是使用PsCreateSystemThread創建了兩個線程,這兩個線程分別用來檢測線程和查句柄;二是使用ObRegisterCallbacks注冊了一個進程回調。

            先講兩個線程,其中一個線程用來檢測被保護的游戲進程的線程是否被暫停,具體操作如下:

            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
            
            do
            {
                KeDelayExecutionThread(0, 0, &Interval);    // 每秒循環一次
                SuspendedThreadCount = 0;
                if ( XtrapGlobalData.CurrentEpr )
                {
                    ThreadListHead = (XtrapGlobalData.CurrentEpr + XtrapGlobalData.Offset.EPROCESS_ThreadListHead);
                    if ( ThreadListHead )
                    {
                        ThreadListEntry = ThreadListHead->Flink;
                        do
                        {
                            EThread = ThreadListEntry - XtrapGlobalData.Offset.ETHREAD_ThreadListEntry;
                            if ( *(&ThreadListEntry->Flink
                                   + XtrapGlobalData.Offset.KTHREAD_SuspendCount
                                   - XtrapGlobalData.Offset.ETHREAD_ThreadListEntry)
                                && *(EThread + XtrapGlobalData.Offset.KTHREAD_WaitReason) == 5// _KWAIT_REASON Suspended
                                && *(EThread + XtrapGlobalData.Offset.ETHREAD_Win32StartAddress) >= *&XtrapGlobalData.Unknown2[4]
                                && *(EThread + XtrapGlobalData.Offset.ETHREAD_Win32StartAddress) <= *&XtrapGlobalData.Unknown2[12] )// 猜測這里的兩個Unknown指的是XTrapVa.dll的起始地址和結束地址
                            {
                                ++SuspendedThreadCount;             // 記錄被暫停的線程個數
                            }
                            ThreadListEntry = ThreadListEntry->Flink;
                        }
                        while ( ThreadListEntry != ThreadListHead );
                        if ( SuspendedThreadCount >= 3 && !LODWORD(XtrapGlobalData.Unknown4) )// 暫停的線程大于等于3個就關閉游戲進程
                            TerminateProcessByPid(XtrapGlobalData.CurrentPid);
                        if ( *&XtrapGlobalData.Unknown2[24] )
                            TerminateProcessByPid(XtrapGlobalData.CurrentPid);
                    }
                }
            }
            while ( XtrapGlobalData.Start );
            

            通過遍歷游戲的ThreadList來檢測游戲某個地址范圍內的線程,我猜測這個范圍是該保護本身的模塊XTrapVa.dll(下面會講),如果暫停的線程大于等于3個就結束進程,目的應該是為了防止調試器附加或者人為暫停該保護的檢測線程。

            第二個線程是用來枚舉擁有被保護游戲進程句柄的進程,操作如下:

            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
            
            if ( XtrapGlobalData.Start )
            {
                while ( 1 )                                 // 每秒循環一次
                {
                    CurrentEpr = XtrapGlobalData.CurrentEpr;
                    RetLength = 0;
                    if ( !XtrapGlobalData.CurrentEpr )
                        goto LABEL_22;
                    ZwQuerySystemInformation = GetAddrZwQuerySystemInformation();// 獲取ZwQuerySystemInformation的地址
                    if ( !ZwQuerySystemInformation )
                        goto LABEL_22;
                    buffer_v3 = ExAllocatePoolWithTag(0, 0x1000ui64, &Tag);
                    v4 = buffer_v3;
                    if ( !buffer_v3 )
                        goto LABEL_22;
                    status = ZwQuerySystemInformation(16i64, buffer_v3, 0x1000i64, &RetLength);// SystemHandleInformation
                    v6 = v4;
                    if ( status != 0xC0000004 )
                        goto LABEL_21;
                    ExFreePoolWithTag(v4, &Tag);
                    v7 = RetLength + 0x1000;
                    buffer_v8 = ExAllocatePoolWithTag(0, (RetLength + 0x1000), &Tag);
                    SysHandleInfo = buffer_v8;
                    if ( buffer_v8 )
                        break;
                    LABEL_22:
                    KeDelayExecutionThread(0, 0, &Interval);  // 1s
                    if ( !XtrapGlobalData.Start )
                        goto LABEL_23;
                }
                if ( !ZwQuerySystemInformation(16i64, buffer_v8, v7, &RetLength) )// SystemHandleInformation 枚舉系統句柄
                {
                    v10 = 0;
                    if ( LODWORD(SysHandleInfo->NumberOfHandles) )
                    {
                        v11 = XtrapGlobalData.XtrapHandleInfo.HandleCounts;
                        v12 = &SysHandleInfo->Handles[0].GrantedAccess;
                        do
                        {
                            if ( *(v12 - 1) == CurrentEpr )       // Handles->Object 判斷句柄對象是否是本身進程
                            {
                                UniqueProcessId = *(v12 - 8);       // Handles->UniqueProcessId
                                GrantedAccess = *v12;
                                if ( *(v12 - 8) )                   // Handles->UniqueProcessId
                                {
                                    if ( UniqueProcessId != 4 )       // 判斷是否是System進程
                                    {                                 // 不是System進程
                                        v15 = 0;
                                        if ( v11 )
                                        {
                                            v16 = XtrapGlobalData.XtrapHandleInfo.UniqueProcessId;
                                            while ( UniqueProcessId != *v16 )
                                            {                             // 檢查UniqueProcessId是否重復
                                                ++v15;
                                                ++v16;
                                                if ( v15 >= v11 )
                                                    goto LABEL_17;
                                            }
                                        }
                                        else
                                        {
                                            LABEL_17:
                                            if ( v11 < 30 )               // 如果UniqueProcessId沒有重復且總量小于30個就記錄
                                            {
                                                XtrapGlobalData.XtrapHandleInfo.UniqueProcessId[v11 + 1] = UniqueProcessId;
                                                XtrapGlobalData.XtrapHandleInfo.GrantedAccess[XtrapGlobalData.XtrapHandleInfo.HandleCounts + 1] = GrantedAccess;
                                                v11 = XtrapGlobalData.XtrapHandleInfo.HandleCounts++ + 1;
                                            }
                                        }
                                    }
                                }
                            }
                            ++v10;
                            v12 += 6;                             // 下一個句柄
                        }
                        while ( v10 < LODWORD(SysHandleInfo->NumberOfHandles) );
                    }
                }
                v6 = SysHandleInfo;
                LABEL_21:
                ExFreePoolWithTag(v6, &Tag);
                goto LABEL_22;
            }
            

            通過調用ZwQuerySystemInformation的16號功能SystemHandleInformation遍歷系統中所有的句柄,從中找出指向被保護的游戲進程的句柄,將擁有該句柄的進程的PID以及權限GrantedAccess記錄到XtrapGlobalData當中。記錄的格式是UniqueProcessId[i]對應GrantedAccess[i]。

            然后是進程回調,做的事情和上面那個線程大同小異,代碼如下:

            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
            
            __int64 __fastcall PreProcessCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
            {
              struct _EPROCESS *TargetEpr; // rbx
              POB_PRE_OPERATION_INFORMATION OperationInformation_v3; // rsi
              XTRAP_GLOBAL_DATA *XtrapGlobalData; // rdi
              struct _EPROCESS *CurrentEpr; // rbp
              int TargetPid; // ebx
              int CurrentPid; // eax
              ULONG DesiredAccess; // edx
              ULONG32 v9; // ecx
              int v10; // ecx
              int v11; // er8
            
              TargetEpr = OperationInformation->Object;
              OperationInformation_v3 = OperationInformation;
              XtrapGlobalData = RegistrationContext;
              CurrentEpr = IoGetCurrentProcess();
              if ( CurrentEpr != TargetEpr && !(OperationInformation_v3->Flags & 1) )// 句柄的對象不是自身且句柄不是內核句柄
              {
                TargetPid = PsGetProcessId(TargetEpr);
                CurrentPid = PsGetProcessId(CurrentEpr);
                DesiredAccess = OperationInformation_v3->Parameters->CreateHandleInformation.OriginalDesiredAccess;
                v9 = XtrapGlobalData->UnknownPid[5];        // 推測為被保護進程的PID
                if ( TargetPid == v9 )
                {
                  if ( DesiredAccess & 0x20 )               // PROCESS_VM_WRITE
                  {
                    if ( CurrentPid != XtrapGlobalData->UnknownPid[0]
                      && CurrentPid != XtrapGlobalData->UnknownPid[1]
                      && CurrentPid != XtrapGlobalData->UnknownPid[2]
                      && CurrentPid != XtrapGlobalData->UnknownPid[3]
                      && CurrentPid != v9
                      && OperationInformation_v3->Operation == 1 )// OB_OPERATION_HANDLE_CREATE
                    {
                      v10 = XtrapGlobalData->Unknown3[0].UniqueProcessId;
                      if ( CurrentPid != v10 )
                      {
                        v11 = XtrapGlobalData->Unknown3[1].UniqueProcessId;
                        if ( CurrentPid != v11 )
                        {
                          if ( v10 )
                          {
                            if ( !v11 )
                            {
                              XtrapGlobalData->Unknown3[1].UniqueProcessId = CurrentPid;
                              XtrapGlobalData->Unknown3[1].GrantedAccess = DesiredAccess;
                              XtrapGlobalData->Unknown3[1].Object = CurrentEpr;
                            }
                          }
                          else
                          {
                            XtrapGlobalData->Unknown3[0].UniqueProcessId = CurrentPid;
                            XtrapGlobalData->Unknown3[0].GrantedAccess = DesiredAccess;
                            XtrapGlobalData->Unknown3[0].Object = CurrentEpr;
                          }
                        }
                      }
                    }
                  }
                }
              }
              return 0i64;
            }
            

            記錄以PROCESS_VM_WRITE權限打開游戲的進程的PIDEPROCESS以及打開的權限GrantedAccess。

            DispatchClose

            主要做了一些清理操作,比如取消進程回調,結束兩個檢測的線程等等。

            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
            
            void *DispatchClose()
            {
              void (__fastcall *ObUnRegisterCallbacks)(void *); // rax
              UNICODE_STRING DestinationString; // [rsp+20h] [rbp-48h]
              WCHAR SourceString[2]; // [rsp+30h] [rbp-38h]
              char Dst; // [rsp+34h] [rbp-34h]
            
              *SourceString = 0;
              memset(&Dst, 0, 0x2Cu);
              DecryptString(&encstr_ObUnRegisterCallbacks, 0x30u, SourceString);
              RtlInitUnicodeString(&DestinationString, SourceString);
              ObUnRegisterCallbacks = MmGetSystemRoutineAddress(&DestinationString);// ObUnRegisterCallbacks
              if ( ObUnRegisterCallbacks && XtrapGlobalData.CallbackHandle )
              {
                (ObUnRegisterCallbacks)();
                XtrapGlobalData.Unknown3[0].UniqueProcessId = 0;
                XtrapGlobalData.Unknown3[1].UniqueProcessId = 0;
                XtrapGlobalData.CallbackHandle = 0i64;
              }
              *XtrapGlobalData.Unknown2 = 0;
              *&XtrapGlobalData.Unknown2[4] = 0i64;
              *&XtrapGlobalData.Unknown2[12] = 0i64;
              *&XtrapGlobalData.Unknown2[20] = 0;
              *&XtrapGlobalData.Unknown2[24] = 0;
              *&XtrapGlobalData.Unknown2[28] = 0;
              XtrapGlobalData.Start = 0;
              XtrapGlobalData.CurrentPid = 0i64;
              XtrapGlobalData.CurrentEpr = 0i64;
              return memset(&XtrapGlobalData.Unknown5, 0, 0x108u);
            }
            

            DispatchIoControl

            這個就是負責通信的函數了,很常規的通過自己定義的控制碼來進行通信??偣捕x了5個控制碼0x86000880 0x8600089C 0x860008C0 0x86000900 0x86001804,這里挑幾個通過已知條件能整得明白的講。

            控制碼0x86000880

            主要工作就是把之前通過進程回調和檢測線程記錄下來的游戲認為的可疑進程的相關信息稍做加工后傳回應用層。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            
            case 0x86000880:
                if ( SystemBuffer && InputBufferLength == 0x790 && OutBuffer && OutputBufferLength == 0x790 )
                {
                    memmove(Dst, SystemBuffer, 0x790u);
                    CurrentEpr = IoGetCurrentProcess();
                    sub_11CC0(&XtrapGlobalData, CurrentEpr, Dst);// 記錄擁有自身進程句柄的非指定進程的各種信息
                    sub_11BA0(&XtrapGlobalData, XtrapGlobalData.CurrentEpr, &Dst[424]);// 記錄SuspectProcess的EPROCESS 父進程ID ImageFileName
                    memmove(OutBuffer, Dst, 0x790u);
                    IoStatus->Information = 0x790i64;
                    break;
                }
            

            sub_11CC0做的工作好像和之前有點重復,這里不再講。sub_11BA0則是獲取之前記錄下來的可疑進程的父進程ID和進程名,然后將它們傳回應用層。

            控制碼0x86001804

            主要工作是遍歷游戲的線程,然后把相關信息傳回應用層。

            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
            
            PEPROCESS __fastcall sub_12160(XTRAP_GLOBAL_DATA *XtrapGlobalData, _DWORD *a2, _DWORD *a3)
            {
              _DWORD *v3; // rbx
              _DWORD *v4; // rdi
              XTRAP_GLOBAL_DATA *XtrapGlobalData_v5; // rsi
              PEPROCESS v6; // rax
              __int64 v7; // r8
              _QWORD **ThreadListHead; // rcx
              _QWORD *ThreadListEntry; // r9
              _QWORD *v10; // rdx
              _DWORD *v11; // r10
              char *Thread; // r11
              char WaitMode; // bp
              char WaitReason; // r12
              char SuspendCount; // r13
              int CrossThreadFlags; // er14
              __int64 Win32StartAddress; // r15
              struct _EPROCESS *ThreadId; // rax
              struct _EPROCESS *v19; // [rsp+60h] [rbp+18h]
            
              v3 = a3;
              v4 = a2;
              XtrapGlobalData_v5 = XtrapGlobalData;
              *a3 = 0x60001;
              a3[3] = 0x600000;
              v6 = IoGetCurrentProcess();
              v7 = 0i64;
              if ( !v6 )
              {
                v3[1] = 0x60002;
            LABEL_3:
                v3[2] = 0;
                return v6;
              }
              ThreadListHead = (v6 + XtrapGlobalData_v5->Offset.EPROCESS_ThreadListHead);
              if ( !ThreadListHead )
              {
                v3[1] = 0x60003;
                goto LABEL_3;
              }
              ThreadListEntry = *ThreadListHead;
              v10 = v4 + 566;
              v11 = v4 + 115;
              do
              {
                Thread = ThreadListEntry - XtrapGlobalData_v5->Offset.ETHREAD_ThreadListEntry;
                WaitMode = Thread[XtrapGlobalData_v5->Offset.KTHREAD_WaitMode];
                WaitReason = Thread[XtrapGlobalData_v5->Offset.KTHREAD_WaitReason];
                SuspendCount = Thread[XtrapGlobalData_v5->Offset.KTHREAD_SuspendCount];
                CrossThreadFlags = *&Thread[XtrapGlobalData_v5->Offset.ETHREAD_CrossThreadFlags];
                Win32StartAddress = *&Thread[XtrapGlobalData_v5->Offset.ETHREAD_Win32StartAddress];
                ThreadId = *&Thread[XtrapGlobalData_v5->Offset.ETHREAD_Cid + 8];
                ++*v4;
                v19 = ThreadId;
                v6 = v4[1];
                if ( v6 < 150 )
                {                                           // 獲取當前進程每個線程的狀態
                  v4[1] = v6 + 1;
                  v6 = v19;
                  *(v4 + v7 + 8) = WaitMode;
                  *(v4 + v7 + 158) = WaitReason;
                  *(v4 + v7 + 308) = SuspendCount;
                  *v11 = CrossThreadFlags;
                  *(v10 - 150) = v19;                       // ThreadId
                  *v10 = Win32StartAddress;
                  v10[150] = Thread;
                }
                ThreadListEntry = *ThreadListEntry;
                ++v7;
                ++v11;
                ++v10;
              }
              while ( ThreadListEntry != ThreadListHead );
              *v3 = 0x60001;
              v3[3] = 0x600001;
              return v6;
            }
            

            通過該函數和一些其它信息可以整理出一個結構體。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            
            typedef struct _XTRAP_THREAD_ENUM_INFO
            {
            	ULONG32 ThreadCount1;
            	ULONG32 ThreadCount2;
            	UCHAR WaitMode[150];
            	UCHAR WaitReason[150];
            	UCHAR SuspendCount[150];
            	ULONG32 CrossThreadFlags[150];
            	ULONG64 UniqueThread[150];
            	ULONG64 Win32StartAddress[150];
            	ULONG64 EthreadAddress[150];
            }XTRAP_THREAD_ENUM_INFO, *PXTRAP_THREAD_ENUM_INFO;
            

            這個結構體就是該控制碼傳回應用層的內容,也就是說記錄了游戲每個線程在這個結構體里有的成員。和XTRAP_HANDLE_INFORMATION類似,每個結構體成員同一個索引對應的就是同一個線程。不過這里還有一個有趣的地方就是這個結構體不是明文傳回應用層的,還做了一個很簡單的加密。

            1
            2
            3
            4
            5
            6
            7
            
            do
            {                                             // buffer內容加密
                *buffer = ~*buffer;
                ++buffer;
                --buffer_len;
            }
            while ( buffer_len );
            

            大概就是把這個結構體的每個字節取反,加解密都是同樣的操作。

            其他控制碼

            其他的控制碼做的工作主要是讓應用層傳了一些信息過來設置了XtrapGlobalData中的Unknown部分,以及一些蜜汁操作(反調試?),比如修改ETHREAD中的FreezeCountSuspendCount。通過已知條件尚不能解釋得很清楚,所以這里就不講了。

            驅動層總結

            驅動部分其實沒做多少事情,主要是收集信息然后傳回應用層接著分析。

            應用層

            其實應用層才是讓人崩潰的地方。

            看了一下XTrap的文件夾,確定了兩個比較主要的文件XTrap.xtXTrapVa.dll。使用DIE

            查殼顯示Themida/Winlicense(2.X)[-],WDNMD直接就來了個下馬威。不過通過大量的百度我還是稀里糊涂的把殼脫掉了(?)。把這兩個程序拖進IDA后,導入表看不到太多函數,一開始我還以為是我脫殼失敗,后來才發現是通過GetProcAddress動態獲取需要用的函數。比如像這樣:

            1
            2
            3
            4
            5
            6
            
            *EnumProcesses = GetProcAddress_0(v4, aEnumprocesses);
            *EnumProcessModules = GetProcAddress_0(v4, aEnumprocessmod);
            *GetModuleFileNameExA = GetProcAddress_0(v4, aGetmodulefilen_1);
            *GetModuleFileNameExW = GetProcAddress_0(v4, aGetmodulefilen_2);
            *GetModuleInformation = GetProcAddress_0(v4, aGetmoduleinfor);
            *GetModuleBaseNameA = GetProcAddress_0(v4, aGetmodulebasen);
            

            于是我只能每個變量慢慢的重命名過去。

            大致瀏覽過后,猜測XTrap.xt應該主要負責UI和其他工作,重頭戲還是在XTrapVa.dll中(當然并不是說XTrap.xt沒什么用,我感覺里面應該也有一部分操作,只是我沒仔細研究過)。當我開始瀏覽XTrapVa.dll后,我崩潰了,到處都是神奇的函數調用,放一些代碼讓大家感受一下。

            比如虛函數

            1
            2
            3
            4
            
            int __thiscall sub_40796B60(int (__thiscall ***this)(_DWORD))
            {
              return (*this[295])(this + 295);
            }
            

            或者加密調用

            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
            
            void __thiscall sub_404225B0(_DWORD *this, int a2)
            {
              sub_4041D280(this + 442, (this + 441), &a2);
            }
            
            void __thiscall sub_4041D280(_DWORD *this, unsigned int a2, unsigned int *a3)
            {
              _DWORD *v3; // ebx
              unsigned int v4; // eax
              unsigned int v5; // ebp
              char v6; // dl
              unsigned int v7; // ecx
              int *v8; // edi
              int v9; // ebp
              unsigned int v10; // esi
              unsigned int v11; // [esp+4h] [ebp-28h]
              unsigned int v12; // [esp+8h] [ebp-24h]
              unsigned int v13; // [esp+Ch] [ebp-20h]
              unsigned int v14; // [esp+10h] [ebp-1Ch]
              char v15; // [esp+14h] [ebp-18h]
              int v16; // [esp+18h] [ebp-14h]
              int v17; // [esp+1Ch] [ebp-10h]
              char v18; // [esp+20h] [ebp-Ch]
              unsigned int v19; // [esp+24h] [ebp-8h]
              int v20; // [esp+28h] [ebp-4h]
              unsigned int v21; // [esp+30h] [ebp+4h]
            
              v3 = this;
              v20 = 0;
              if ( this[4] & 0xFFFFFFFC )
              {
                v4 = a2;
                v5 = a2;
                v11 = (a2 >> 6) & 7;
                v6 = a2 & 7;
                v12 = (a2 >> 9) & 7;
                v13 = (a2 >> 12) & 7;
                v14 = (a2 >> 15) & 7;
                v7 = (a2 >> 18) & 7;
                v21 = a2 & 7;
                v15 = v7;
                v8 = 2;
                v16 = (v4 >> 21) & 7;
                v17 = (v4 >> 24) & 7;
                v9 = (v5 >> 3) & 7;
                v19 = v4 >> 30;
                v18 = (v4 >> 27) & 7;
                while ( 1 )
                {
                  v10 = *a3;
                  sub_4041D210(v3, (v8 - 2), *a3 & 1, v6);
                  sub_4041D210(v3, (v8 - 1), (v10 >> 1) & 1, v21);
                  sub_4041D210(v3, v8, (v10 >> 2) & 1, v21);
                  sub_4041D210(v3, (v8 + 1), (v10 >> 3) & 1, v9);
                  sub_4041D210(v3, (v8 + 2), (v10 >> 4) & 1, v9);
                  sub_4041D210(v3, (v8 + 3), (v10 >> 5) & 1, v9);
                  sub_4041D210(v3, v8 + 1, (v10 >> 6) & 1, v11);
                  sub_4041D210(v3, (v8 + 5), (v10 >> 7) & 1, v11);
                  sub_4041D210(v3, (v8 + 6), v10 >> 8, v11);
                  sub_4041D210(v3, (v8 + 7), (v10 >> 9) & 1, v12);
                  sub_4041D210(v3, v8 + 2, (v10 >> 10) & 1, v12);
                  sub_4041D210(v3, (v8 + 9), (v10 >> 11) & 1, v12);
                  sub_4041D210(v3, (v8 + 10), (v10 >> 12) & 1, v13);
                  sub_4041D210(v3, (v8 + 11), (v10 >> 13) & 1, v13);
                  sub_4041D210(v3, v8 + 3, (v10 >> 14) & 1, v13);
                  sub_4041D210(v3, (v8 + 13), (v10 >> 15) & 1, v14);
                  sub_4041D210(v3, (v8 + 14), v10 >> 16, v14);
                  sub_4041D210(v3, (v8 + 15), (v10 >> 17) & 1, v14);
                  sub_4041D210(v3, v8 + 4, (v10 >> 18) & 1, v15);
                  sub_4041D210(v3, (v8 + 17), (v10 >> 19) & 1, v15);
                  sub_4041D210(v3, (v8 + 18), (v10 >> 20) & 1, v15);
                  sub_4041D210(v3, (v8 + 19), (v10 >> 21) & 1, v16);
                  sub_4041D210(v3, v8 + 5, (v10 >> 22) & 1, v16);
                  sub_4041D210(v3, (v8 + 21), (v10 >> 23) & 1, v16);
                  sub_4041D210(v3, (v8 + 22), HIBYTE(v10) & 1, v17);
                  sub_4041D210(v3, (v8 + 23), (v10 >> 25) & 1, v17);
                  sub_4041D210(v3, v8 + 6, (v10 >> 26) & 1, v17);
                  sub_4041D210(v3, (v8 + 25), (v10 >> 27) & 1, v18);
                  sub_4041D210(v3, (v8 + 26), (v10 >> 28) & 1, v18);
                  sub_4041D210(v3, (v8 + 27), (v10 >> 29) & 1, v18);
                  sub_4041D210(v3, v8 + 7, (v10 >> 30) & 1, v19);
                  sub_4041D210(v3, (v8 + 29), (v10 & 0x80000000) != 0, v19);
                  ++a3;
                  v8 += 8;
                  if ( ++v20 >= v3[4] >> 2 )
                    break;
                  v6 = v21;
                }
              }
            }
            
            int *__thiscall sub_4041D210(_DWORD *this, int *a2, char a3, char a4)
            {
              int *result; // eax
              int v5; // esi
            
              result = a2;
              v5 = this[1];
              *(a2 + v5) = a3 << a4;
              if ( (a2 & 3) == 3 )
              {
                result = (v5 + 4 * (a2 >> 2));
                *result = this[2] ^ *(v5 + 4 * (a2 >> 2));
              }
              return result;
            }
            

            當然惡心的東西還不止是這些。這么一看,只靠靜態分析這條路確實是會讓人崩潰的。于是我努力地靠著有限的動態調試和有限的靜態分析以及自殺式的嘗試得出了一些結果,當然得出的這些結果并不一定準確。

            窗口檢測

            使用了EnumWindow,并且可能調用GetWindowLong獲取了以下屬性:

            • GWL_HINSTANCE
            • GWL_HWNDPARENT
            • GWL_WNDPROC
            • GWL_STYLE

            還調用了GetClassName獲取了類名。

            創建快照

            調用了CreateToolhelp32Snapshot,參數為TH32CS_SNAPMODULETH32CS_SNAPPROCESS,即遍歷了自身模塊和進程。至于干了什么,我覺得需要靠完整的動態調試才能略窺一二。

            x64代碼調用

            在有限的動態調試過程中,我發現了一個很有趣的函數。

            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
            
            ___:40D224D0 55                                                  push    ebp
            ___:40D224D1 8B EC                                               mov     ebp, esp
            ___:40D224D3 83 EC 20                                            sub     esp, 20h
            ___:40D224D6 8B 45 08                                            mov     eax, [ebp+8]
            ___:40D224D9 8B 4D 0C                                            mov     ecx, [ebp+arg_0]
            ___:40D224DC 8B 55 10                                            mov     edx, [ebp+arg_4]
            ___:40D224DF 89 45 F8                                            mov     [ebp+var_8], eax ; ssdt index
            ___:40D224E2 8B 45 14                                            mov     eax, [ebp+arg_8]
            ___:40D224E5 89 4D FC                                            mov     [ebp+var_4], ecx
            ___:40D224E8 8B 4D 18                                            mov     ecx, [ebp+arg_C]
            ___:40D224EB 89 55 E0                                            mov     [ebp+var_20], edx ; para1
            ___:40D224EE 8B 55 1C                                            mov     edx, [ebp+arg_10]
            ___:40D224F1 89 45 E4                                            mov     [ebp+var_1C], eax
            ___:40D224F4 8B 45 20                                            mov     eax, [ebp+arg_14]
            ___:40D224F7 89 4D E8                                            mov     [ebp+var_18], ecx ; para2
            ___:40D224FA 8B 4D 24                                            mov     ecx, [ebp+arg_18]
            ___:40D224FD 89 55 EC                                            mov     [ebp+var_14], edx
            ___:40D22500 8B 55 28                                            mov     edx, [ebp+arg_1C]
            ___:40D22503 89 45 F0                                            mov     [ebp+var_10], eax ; para3
            ___:40D22506 8B 45 2C                                            mov     eax, [ebp+arg_20]
            ___:40D22509 89 4D F4                                            mov     [ebp+var_C], ecx
            ___:40D2250C 8B 4D 30                                            mov     ecx, [ebp+arg_24]
            ___:40D2250F 89 55 20                                            mov     [ebp+arg_14], edx ; para4
            ___:40D22512 8B 55 34                                            mov     edx, [ebp+arg_28]
            ___:40D22515 89 45 24                                            mov     [ebp+arg_18], eax
            ___:40D22518 8B 45 38                                            mov     eax, [ebp+arg_2C]
            ___:40D2251B 89 4D 10                                            mov     [ebp+arg_4], ecx ; para5
            ___:40D2251E 8B 4D 3C                                            mov     ecx, [ebp+arg_30]
            ___:40D22521 89 55 14                                            mov     [ebp+arg_8], edx
            ___:40D22524 89 45 18                                            mov     [ebp+arg_C], eax ; para6
            ___:40D22527 89 4D 1C                                            mov     [ebp+arg_10], ecx
            ___:40D2252A C7 45 0C 00 00 00 00                                mov     [ebp+arg_0], 0
            ___:40D22531 89 65 0C                                            mov     [ebp+arg_0], esp
            ___:40D22534 83 E4 F8                                            and     esp, 0FFFFFFF8h
            ___:40D22537 6A 33                                               push    33h
            ___:40D22539 E8 00 00 00 00                                      call    $+5
            ___:40D2253E 83 04 24 05                                         add     [esp+28h+var_28], 5
            ___:40D22542 CB                                                  retf
            ___:40D22542                                     x64syscall      endp ; sp-analysis failed
            ___:40D22542
            ___:40D22543                                     ; ---------------------------------------------------------------------------
            ___:40D22543 48                                                  dec     eax             ; mov rcx, qword ptr ss:[rbp-0x20]
            ___:40D22543                                                                             ; mov rdx, qword ptr ss:[rbp-0x18]
            ___:40D22543                                                                             ; push qword ptr ss:[rbp-0x10]
            ___:40D22543                                                                             ; pop r8
            ___:40D22543                                                                             ; push qword ptr ss:[rbp+0x20]
            ___:40D22543                                                                             ; pop r9
            ___:40D22543                                                                             ; push qword ptr ss:[rbp+0x18]
            ___:40D22543                                                                             ; push qword ptr ss:[rbp+0x10]
            ___:40D22543                                                                             ; sub rsp, 0x28
            ___:40D22543                                                                             ; mov rax, qword ptr ss:[rbp-0x08]
            ___:40D22543                                                                             ; mov r10, rcx
            ___:40D22543                                                                             ; syscall
            ___:40D22543                                                                             ; add rsp, 0x38
            ___:40D22543                                                                             ; mov qword ptr ss:[rbp-0x08], rax
            ___:40D22543                                                                             ; call 0x0000000000000032
            ___:40D22543                                                                             ; mov dword ptr ss:[rsp+0x04], 0x23
            ___:40D22543                                                                             ; add dword ptr ss:[rsp], 0x0D
            ___:40D22543                                                                             ; ret far
            ___:40D22544 8B 4D E0                                            mov     ecx, [ebp-20h]
            ___:40D22547 48                                                  dec     eax
            ___:40D22548 8B 55 E8                                            mov     edx, [ebp-18h]
            ___:40D2254B FF 75 F0                                            push    dword ptr [ebp-10h]
            ___:40D2254E 49                                                  dec     ecx
            ___:40D2254F 58                                                  pop     eax
            ___:40D22550 FF 75 20                                            push    dword ptr [ebp+20h]
            ___:40D22553 49                                                  dec     ecx
            ___:40D22554 59                                                  pop     ecx
            ___:40D22555 FF 75 18                                            push    dword ptr [ebp+18h]
            ___:40D22558 FF 75 10                                            push    dword ptr [ebp+10h]
            ___:40D2255B 48                                                  dec     eax
            ___:40D2255C 83 EC 28                                            sub     esp, 28h
            ___:40D2255F 48                                                  dec     eax
            ___:40D22560 8B 45 F8                                            mov     eax, [ebp-8]
            ___:40D22563 4C                                                  dec     esp
            ___:40D22564 8B D1                                               mov     edx, ecx
            ___:40D22566 0F 05                                               syscall                 ; Low latency system call
            ___:40D22568 48                                                  dec     eax
            ___:40D22569 83 C4 38                                            add     esp, 38h
            ___:40D2256C 48                                                  dec     eax
            ___:40D2256D 89 45 F8                                            mov     [ebp-8], eax
            ___:40D22570 E8 00 00 00 00                                      call    $+5
            ___:40D22575 C7 44 24 04 23 00 00 00                             mov     dword ptr [esp+4], 23h
            ___:40D2257D 83 04 24 0D                                         add     dword ptr [esp], 0Dh
            ___:40D22581 CB                                                  retf
            

            很經典的一段32位調用64位代碼,通過

            1
            2
            3
            4
            
            ___:40D22537 6A 33                                               push    33h
            ___:40D22539 E8 00 00 00 00                                      call    $+5
            ___:40D2253E 83 04 24 05                                         add     [esp+28h+var_28], 5
            ___:40D22542 CB                                                  retf
            

            這段代碼,改變了段寄存器cs,進入了x64代碼模式。因為ida32沒辦法看x64代碼,于是我用注釋將x64代碼補了上去。從代碼中可以看到調用了syscall,所以整個函數其實就是一個利用syscall調用Nt函數的封裝。該函數的格式如下:

            1
            2
            3
            
            NTSTATUS
            NTAPI
            x64syscall(ULONG64 Index, ULONG64 Para1, ULONG64 Para2, ULONG64 Para3, ULONG64 Para4, ULONG64 Para5, ULONG64 Para6);
            

            第一個參數為要調用的Nt函數的Index,其余參數就為該Nt函數的參數。通過搜索特征碼,我得知在XTrapVa.dll中一共有兩個函數實現了類似的效果,即利用syscall調用Nt函數。并通過測試發現,XTrap使用該函數調用過以下幾個Nt函數(可能不全):

            • NtQueryInformationProcess
            • NtTerminateProcess
            • NtReadVirtualMemory

            至于干了什么,任憑各位想象。

            應用層總結

            雖然應用層沒有vm也沒有混淆之類的東西,但它還是用了一些神奇的操作阻擋了我的靜態分析(畢竟我太菜了)。當然肯定不只干了我講的這些,還有內存掃描、線程檢測等等,然而精力和技術的雙重限制讓我只能講到這了。

            Bypass

            雖然沒有能夠完全透爛這個保護,但是Bypass的話我還是能提供一點思路的。首先需要準備一個dll,該dll需要實現的功能如下:

            • 結束XTrapVa.dll的所有線程
            • 結束XTrap.xt進程
            • HookNtTerminateProcessx64syscall

            結束進程和線程的部分:

            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
            
            VOID KillThread()
            {
            	HANDLE hSnap;
            	THREADENTRY32 te32;
            	HANDLE hThread;
            	MODULEINFO mi;
            	ULONG DllBase;
            	ULONG DllSize;
            	DWORD RetLen;
            	ULONG StartAddress;
            	decltype(NtQueryInformationThread)* pfnNtQueryInformationThread;
            
            	GetModuleInformation(GetCurrentProcess(), GetModuleHandle(_T("XTrapVa.dll")), &mi, sizeof(MODULEINFO));
            	DllBase = (ULONG)mi.lpBaseOfDll;
            	DllSize = mi.SizeOfImage;
            	pfnNtQueryInformationThread = (decltype(NtQueryInformationThread)*)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationThread");
            
            	hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
            	if (hSnap == INVALID_HANDLE_VALUE)
            	{
            		return;
            	}
            
            	te32.dwSize = sizeof(THREADENTRY32);
            	if (!Thread32First(hSnap, &te32))
            	{
            		CloseHandle(hSnap);
            		return;
            	}
            	do
            	{
            		if (te32.th32OwnerProcessID == GetCurrentProcessId())
            		{
            			hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
            			pfnNtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &StartAddress, sizeof(StartAddress), &RetLen);
            			if (StartAddress > DllBase && StartAddress < DllBase + DllSize)
            			{
            				TerminateThread(hThread, 0);
            			}
            			CloseHandle(hThread);
            		}
            
            	} while (Thread32Next(hSnap, &te32));
            
            	CloseHandle(hSnap);
            }
            
            VOID KillProcess()
            {
            	PROCESSENTRY32 pe32;
            	HANDLE hSnap;
            	HANDLE hProcess;
            
            	hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
            	if (hSnap == INVALID_HANDLE_VALUE)
            	{
            		return;
            	}
            
            	pe32.dwSize = sizeof(PROCESSENTRY32);
            	if (!Process32First(hSnap, &pe32))
            	{
            		CloseHandle(hSnap);
            		return;
            	}
            	do
            	{
            		if (!_tcsicmp(pe32.szExeFile, _T("XTrap.xt")))
            		{
            			hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
            			TerminateProcess(hProcess, 0);
            			CloseHandle(hProcess);
            		}
            	} while (Process32Next(hSnap, &pe32));
            
            	CloseHandle(hSnap);
            }
            

            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
            
            NTSTATUS
            NTAPI
            MyNtTerminateProcess(
            	_In_opt_ HANDLE ProcessHandle,
            	_In_ NTSTATUS ExitStatus
            )
            {
            	return STATUS_SUCCESS;
            }
            
            NTSTATUS
            NTAPI
            Myx64syscall(ULONG64 Index, ULONG64 Para1, ULONG64 Para2, ULONG64 Para3, ULONG64 Para4, ULONG64 Para5, ULONG64 Para6)
            {
            	switch (Index)
            	{
            	case 0x2c:	//NtTerminateProcess 這里根據系統自己改
            		return STATUS_SUCCESS;
            
            	default:
            		break;
            	}
            
            	return pfnx64syscall(Index, Para1, Para2, Para3, Para4, Para5, Para6);
            }
            

            準備好dll之后用任意注入方式注入游戲進程即可,只需要注意一點就是注入一定要快。

            當我注入后發現我可以使用CE正常附加和調試了(VEH),于是我興沖沖的準備使用動態調試進行深入分析,然后我發現。。。

            有關檢測的線程都被我干掉了,我還調試個雞兒。

            總結:以上內容就是針對一篇關于xtrap保護檢測詳細的技術分析詳細闡釋,如果您覺得有更好的建議可以提供給哪吒游戲網小編,一篇關于xtrap保護檢測詳細的技術分析部分內容轉載自互聯網,有幫助可以收藏一下。



            上一篇: 新手利用夢幻西游怎么賺錢人民幣又快又穩

            下一篇: 返回列表

            本文標簽:
            猜你喜歡
            60分钟从头啪到尾无遮挡,国产成本人片免费AV,女厕真实偷拍撒尿视频,中文字幕夫妇交换乱叫 广水市| 宿迁市| 丰县| 清河县| 醴陵市| 宜章县| 平江县| 天等县| 思茅市| 太和县| 荔波县| 甘泉县| 晋州市| 云龙县| 宁都县| 肇庆市| 闽清县| 新邵县| 神木县| 沁水县| 枣庄市| 桃源县| 孟州市| 济南市| 汽车| 鱼台县| 井研县| 九寨沟县| 抚松县| 边坝县| 阳新县| 江达县| 吕梁市| 会昌县| 乌拉特后旗| 白玉县| 卫辉市| 巫溪县| 介休市| 潞西市| 贵阳市| http://444 http://444 http://444 http://444 http://444 http://444