当前位置:网站首页>Easyanticheat uses to inject unsigned code into a protected process (2)

Easyanticheat uses to inject unsigned code into a protected process (2)

2022-06-24 04:11:00 franket

If you can't tell from the code , This is just a standard manual mapper . It tries to hide by allocating additional memory around its memory , Hopefully the reverser won't see that this is actually dynamic code ! You should also pay attention to , As long as one part contains the original data , We can map its content into the game . This means that an attacker can intentionally attach an extra part ( Or maybe hijack an existing part ) also EasyAntiCheat.sys Carelessly mapping this code without any form of validation .

Code execution


Getting code execution is very simple .EAC Use APC Delivery is performed in user mode shellcode, The shellcode Mapped by :

PVOID MapShellcode(ModuleMapInstance* Instance)
{
        SIZE_T ShellcodeSize = PAGE_SIZE; // 0x1000
        PVOID ShellcodeBase = nullptr;


        BOOLEAN VirtualApiResult = 
                NT_SUCCESS( NtAllocateVirtualMemory( NtCurrentProcess(), &ShellcodeBase, 0, &ShellcodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );


        if ( !VirtualApiResult || !ShellcodeBase )
                return nullptr;


        if ( Instance->ImageType == ImageType::Image64 )
        {
                UINT8 ShellcodeBuffer[] =
                {
                        0x48, 0x83, 0xEC, 0x28,        // SUB RSP, 0x28
                        0x4D, 0x31, 0xC0, // XOR R8, R8
                        0x48, 0x31, 0xD2, // XOR RDX, RDX
                        0x48, 0xFF, 0xC2, // INC RDX
                        0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MOV RAX, 0
                        0xFF, 0xD0,        // CALL RAX
                        0x48, 0x83, 0xC4, 0x28, // ADD RSP, 0x28
                        0xC3 // RETN
                };


                memcpy( &ShellcodeBuffer[15], Instance->DllEntryPoint, sizeof( Instance->DllEntryPoint ) );
                memcpy( ShellcodeBase, ShellcodeBuffer, sizeof( ShellcodeBuffer ) );
        }
        else
        {
                UINT8 ShellcodeBuffer[] =
                {
                        0x6A, 0x00,        // PUSH 0
                        0x6A, 0x01,        // PUSH 1
                        0xFF, 0x74, 0xE4, 0x0C, // PUSH [RSP+0xC]
                        0xB8, 0x00, 0x00, 0x00, 0x00, // MOV EAX, 0
                        0xFF, 0xD0,        // CALL EAX
                        0xC2, 0x04, 0x00 // RETN 4
                };


                memcpy( &ShellcodeBuffer[9], Instance->DllEntryPoint, sizeof( Instance->DllEntryPoint ) / 2 );
                memcpy( ShellcodeBase, ShellcodeBuffer, sizeof( ShellcodeBuffer ) );
        }


        return ShellcodeBase;
}

Once this module is EP Be performed , Its head will be erased , This ensures that reverse engineers cannot access it . contrary ,EasyAntiCheat.dll Meeting HANDLE In this unused space EasyAntiCheat.sys Driver and other specific data . This manual mapper has more functions , For example, the parsing module IAT. Since this information is not a prerequisite for understanding this section , We can skip the introductory content .

A quick look at EasyAntiCheat.dll


Before we start exploiting vulnerabilities , Let's take a look at the actual EasyAntiCheat.dll modular , Look at the impact of hijacking this payload . as everyone knows , Manual mapping is a popular code injection mechanism shared by cheating developers . To make sure EasyAntiCheat Detection data will not be collected from legitimate memory areas , It builds the internal white list system of the system module , And manually mapped image ranges . We can see an example of how to use it in the following function :

BOOLEAN IsInValidMemory( EACGlobal* GlobalContext, ULONG64 VirtualAddress )
{
        if ( !VirtualAddress )
                return FALSE;


        ModuleListEntry* ModuleList = &GlobalContext->ModuleList;
        RtlEnterCriticalSection( ModuleList ); // Wait until the list is available....
        ModuleListEntry* CurrentEntry = ModuleList->Flink;
        for ( i = ModuleList->Flink; CurrentEntry != i; CurrentEntry = CurrentEntry->Flink; )
        {
                if ( CurrentEntry->Unk0 && CurrentEntry->Unk1 && 
                        VirtualAddress >= CurrentEntry->ImageBase && VirtualAddress < CurrentEntry->ImageBase + CurrentEntry->SizeOfImage )
                {
                        break;
                }
        }


        RtlLeaveCriticalSection(ModuleList);
        InternalModuleBase = GlobalContext->MappedImageBase;


        // If it landed inside a legit module or within EasyAntiCheat.dll, return TRUE.
        if ( i != ModuleList || VirtualAddress >= StartAddress && VirtualAddress < GlobalContext->MappedImageSize + StartAddress )
                return TRUE;


        // Other regions like dynamically allocated shellcode below....
        return FALSE;
}

This function is in EasyAntiCheat.dll Regular execution of , To determine whether the address exists in legal memory . As you know , If the address is in the internal module , Then return to TRUE.EAC Many things that protect games from ( Illegal thread creation 、 Inline hook, etc ) Can be passed in EasyAntiCheat.dll Map your image in to avoid . deadly , Right ?

Be careful :EAC This function is not always used , And performs inline checks quite frequently to detect whether the address exists in its memory .

Development


Now we know how the image is mapped to the process , We can develop our own payloads to hijack user mode execution , Attach our image to EAC In the existing image of . The layout of this exploit is as follows :

In more detail , You need to put a DLL Injection into eac_launcher.exe in , To do the following :

  1. SetupEasyAntiCheatModule Recursively scan the function for patterns .
  2. Once we find a hit , Hook the function and pull the existing image .
  3. Use Decrypt the image DecryptModule, Then modify the existing part to map the new code .
  4. Change some properties to include PAGE_EXECUTE_READWRITE attribute .
  5. to update ImageSize Parameters ( and IMAGE_OPTIONAL_HEADER The structure of the SizeOfImage ) And call EncryptModule Repackage the module .
  6. Repair the original DllEntryPoint With REL32 JMP To your DllEntryPoint perform a .
  7. Once we call EP, Recover these patches and call EasyAntiCheat.dll Entrance point .
  8. complete !

To avoid handling x86 Calling convention , I decided it was best to put one int3 Instruction to cause an interrupt after the function is executed . And then I use VEH( Vector exception handler ) To execute our hook procedure , Last , Restore the original operation code with the modified parameters .

We should also pay attention to , You must put the PE Header information is attached to EasyAntiCheat.dll In the head of . This is because information such as relocating and importing data will not be parsed , So another form of solution is needed to load your module correctly or to anticipate a crash . For the sake of simplicity , I avoided completely solving these problems . If you like , You can map your PE Header and read it out and resolve all problems within your entry point .

You should also know EasyAntiCheat.dll stay EasyAntiCheat.sys Run integrity check in ; So don't try to fix non writable parts without bypassing them ! PS: This also means that you can deliberately create multiple parts in a binary file , And force the driver to protect specific parts of the code for you .

demonstration


The following video demonstrates the practical application of this technology ,DbgView.exe adopt OutputDebugStringA Call inside the game to display the internal log .

Conclusion


EasyAntiCheat.sys Inadvertently created an ideal condition for code execution in the game , It allows you to dynamically run in-process code from user mode , And allows you to hook and execute any code , And will not conflict with anti cheating . You can even associate this project with enabling secure boot + HVCI( Manage program code integrity ) Machine pairing for . Further application , You can turn this project into a local process injection vulnerability , Used by BattlEye And other alternative solutions to protect the game . Of course , There are ways to completely detect and prevent this condition .

For clarity , stay EasyAntiCheat Some ways to prevent such exploits in the game include :

  • Change the user mode dll Embed the driver and inject it directly into the game ...... I don't know why it hasn't been finished yet ?
  • Yes EasyAntiCheat.dll The module is signed and verified EasyAntiCheat.sys Signature in
  • Check the section title to ensure that each section has the correct number of permissions
  • Protection after service operation eac_launcher.exe To prevent placing hooks .
  • monitor DLL And analyze it , To ensure that it detects some outliers that are hijacking this module .

without doubt ,EasyAntiCheat Can achieve more ( If they haven't ) To prevent this type of attack . Even though EasyAntiCheat In recent years, we have done a good job in catching up with kernel vulnerabilities and even the recent hypervisor technology , But it's also a good idea to review old design models and make sure they work as expected without any warning .

原网站

版权声明
本文为[franket]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/09/20210910165620853j.html