-1

I had follow Guided hacking video about How to detour. i tried to detour code that decrease armor after shoot in AssaultCube game. That piece of assembly code is (viewed in Cheat Engine):

(0x004637E9)ac_client.exe+637E9      FF 0E                 - dec [esi]
                                     57                    - push edi
                                     8B 7C 24 14           - mov edi,[esp+14]
(0x004637F0)ac_client.exe+637F0      8D 74 24 28           - lea esi,[esp+28]

So follow the video i had to place a jump hook at 0x4637E9 that jump to the function called ourFunction which increase bullet number instead of decrease it (for hacking test purpose). To do it i create a C++ DLL like this:

#include <Windows.h>
#include "pch.h"
bool Hook(void* toHook, void* ourFunct, int len) {
    if (len < 5) {
        return false;
    }

    DWORD curProtection;
    VirtualProtect(toHook, len, PAGE_EXECUTE_READWRITE, &curProtection);

    memset(toHook, 0x90, len);

    DWORD relativeAddress = ((DWORD)ourFunct - (DWORD)toHook) - 5;

    *(BYTE*)toHook = 0xE9;
    *(DWORD*)((DWORD)toHook + 1) = relativeAddress;

    DWORD temp;
    VirtualProtect(toHook, len, curProtection, &temp);

    return true;
}

//DWORD jmpBackAddy;  // i have tweak this a bit from video to make jmp instruction work
void __declspec(naked) ourFunction() {
    
    __asm {
        inc [esi]
        push edi
        mov edi, [esp + 14]
        mov eax, 0x004637F0
        jmp eax
        //jmp [jmpBackAddy]
    }
    
 
}

DWORD WINAPI MainThread(LPVOID param) {
    int hookLength = 7;
    DWORD hookAddress = 0x4637E9;
    //jmpBackAddy = hookAddress + hookLength;

    Hook((void*)hookAddress, ourFunction, hookLength);
    while (true) {
        if (GetAsyncKeyState(VK_ESCAPE)) break;
        Sleep(50);
    }
    FreeLibraryAndExitThread((HMODULE)param, 0);
    return 0;
}

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) {
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        CreateThread(0, 0, MainThread, hModule, 0, 0);
        break;
    }
    return TRUE;
}

I compile that DLL in C:\Users\Admin\source\repos\DETOUR_DLL\Debug\DETOUR_DLL.dll and i inject that DLL to the ac_client.exe process by this C++ injector:

#include ....
....
void DLL_INJECTION(LPCWSTR exe_name, const char* dllPath) {
    
    DWORD PID = 0;

    while (!PID)
    {
        //function that get process id by it name in task manager
        PID = obtain_process_id_with_exe_name(exe_name);
        Sleep(30);
    }

    HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, 0, PID);
    if (process && process != INVALID_HANDLE_VALUE)
    {
        void* loc = VirtualAllocEx(process, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (loc) {
            WriteProcessMemory(process, loc, dllPath, strlen(dllPath) + 1, 0);
        }

        HANDLE hThread = CreateRemoteThread(process, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);

        //VirtualFreeEx(process, loc, MAX_PATH, MEM_DECOMMIT | MEM_RELEASE);

        if (hThread) {
            CloseHandle(hThread);
        }


    }

    if (process) {
        CloseHandle(process);
    }
}
int main()
{
    DWORD PID = obtain_process_id_with_exe_name(L"ac_client.exe");
    HANDLE process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, PID);
    DLL_INJECTION(L"ac_client.exe", "C:\\Users\\Admin\\source\\repos\\DETOUR_DLL\\Debug\\DETOUR_DLL.dll");
    CloseHandle(process);
}

Before run the injector it decrease armor after shoot at normal but after inject DLL and tried to click shoot it crash and pop up a Message Box say:
Assault Cube fatal error Win32 Exception: 0xc0000005. I had checked in assembly show by cheat engine that the Injector successfully inject a jump at 0x004637E9, jump to a strange code line in my DETOUR_DLL and that line jump to the ourFuntion code which does the magic, then jump back to the after-hook code line which is 0x4637F0. So this must be work ! Can you help me show where is the problem ? Thanks very much

dauhuong68
  • 19
  • 1
  • 7
  • `0xc0000005` indicates, that you're illegally dereferencing an uninitialized pointer. – πάντα ῥεῖ Feb 21 '22 at 16:53
  • @πάντα ῥεῖ can you tell me what is that pointer there are plenty pointer out there ? This dll injector worked before with another DLL so i think problem might be in the new DLL – dauhuong68 Feb 21 '22 at 16:58
  • 1
    No, that's the job of your debugger, not mine. Check the stack trace, at the point you're receiving the exception, this will give you the line with the _undefined behavior_. – πάντα ῥεῖ Feb 21 '22 at 16:59
  • i think that error occur in game when it running after the injection not in the visual studio. how do i check the game stack trace ? – dauhuong68 Feb 21 '22 at 17:07
  • 1
    You need to attach the debugger to the game so you can debug the crashes in it. – Raymond Chen Feb 21 '22 at 17:13
  • i add debugger to the game by cheat-engine debugger and also using cheatengine built-in dll injector to inject dll. after debug session i found out it crash at **jmp eax** instruction. why ? – dauhuong68 Feb 23 '22 at 14:13

1 Answers1

0

i found it. problem was in my declspec(naked)function. mov edi, [esp + 14] must be fix to mov edi, [esp + 0x14]

dauhuong68
  • 19
  • 1
  • 7