jjthompson
jjthompson

Reputation: 51

Accessing Memory in DLL Injection results in Memory Access Violation

I recently started trying to get into game hacking to develop my reverse engineering skills. I am running Windows 10. For now, I am trying to write a basic DLL Injection program that will let me read certain bytes from the game and print them out. Unfortunately, when I inject my DLL the game immediately crashes with the following log recovered from Windows Event Viewer:

Faulting application name: game_to_hack.exe, version: 2019.4.19.23316, time stamp: 0x6007d1a6
Faulting module name: IL2CppDLL.dll, version: 0.0.0.0, time stamp: 0x618dc9c6
Exception code: 0xc0000005
Fault offset: 0x0000000000248f48
Faulting process id: 0x8ca8

which seems to indicate a memory access violation on the given address.

The code for my DLL is relatively simple. There is a class which is supposed to scan the game for a certain pattern of bytes:

class SigScan
{
    public:
        // For getting information about the executing module
        MODULEINFO GetModuleInfo(char *szModule)
        {
            MODULEINFO modinfo = { 0 };
            HMODULE hModule = GetModuleHandle(szModule);
            if (hModule == 0)
                return modinfo;
            GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
            return modinfo;
        }
    // for finding a signature/pattern in memory of another process
    DWORD FindPattern(char *module, char *pattern, char *mask)
    {
        MODULEINFO mInfo = GetModuleInfo(module);
        DWORD base = (DWORD)mInfo.lpBaseOfDll;
        DWORD size = (DWORD)mInfo.SizeOfImage;
        DWORD patternLength = (DWORD)strlen(mask);

        char test = *(char*)base; // <- This is the memory access that causes the crash.
        
        // TODO: Actually scan for the pattern
};

My dllmain.cpp then uses the above class to try and find the pattern:

void Run()
{
    SigScan Scanner;

    // It's a Unity game.
    char proc_name[] = "gameassembly.dll";
    char byte_sequence[] = "\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x70\x18";
    char pattern[] = "xxxxxxxxxxx";

    Scanner.FindPattern(proc_name, byte_sequence, pattern);
}


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        init_il2cpp();
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Run, NULL, 0, NULL);
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

My question is why does the crash happen and how can I fix it? I have confirmed that the MODULEINFO struct returned from the GetModuleInfo function is initialized to a non-null value, and the base address that I read from it seems legitimate. From reading other posts I understand that Windows will throw a memory access violation if you try to read another process's memory, but since my code is running in a DLL Injection my understand is that it should be able to read the memory without issue, since it is within the same process.

Any help is greatly appreciated! Thanks for your time.

Upvotes: 2

Views: 843

Answers (1)

jjthompson
jjthompson

Reputation: 51

I am a fool.

This line is the cause of all my issues: DWORD base = (DWORD)mInfo.lpBaseOfDll;

This code is running on a 64-bit OS, whereas a DWORD is only 4 bytes, so it is presumably just taking the lower 4 bytes of the base pointer and using that, which results in invalid memory accesses as I am essentially looking at random addresses. Using a DWORD_PTR instead (8 bytes on a 64-bit OS) has solved all my issues.

Upvotes: 3

Related Questions