Lauri Uusaro
Lauri Uusaro

Reputation: 21

Access violation when calling function of a game from dll

I tried to call a function of game called The Binding of Isaac: Rebirth that sets the current amount of key you have. This is my injected dll code currently:

main.cpp

#include <iostream>

typedef void(__cdecl *funcB)(byte namePtr);
funcB originalFunction;

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
{
    uintptr_t modBase = (uintptr_t)GetModuleHandle(NULL);
    originalFunction = (funcB)(modBase + 0x150860);
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        originalFunction(17); //set keys to 17
        break;
    default:
        break;
    }
    return TRUE;
}

This is the assembly of the function from x64dbg:

010E0860 | 55                       | push ebp                                |
010E0861 | 8B EC                    | mov ebp,esp                             |
010E0863 | 83 EC 08                 | sub esp,8                               |
010E0866 | 8B 81 D8 24 00 00        | mov eax,dword ptr ds:[ecx+24D8]         | ;line that calls the EXCEPTION_ACCESS_VIOLATION
010E086C | 8D 55 08                 | lea edx,dword ptr ss:[ebp+8]            |
010E086F | 03 45 08                 | add eax,dword ptr ss:[ebp+8]            |
010E0872 | 83 F8 63                 | cmp eax,63                              | 63:'c'
010E0875 | 89 45 08                 | mov dword ptr ss:[ebp+8],eax            |
010E0878 | 56                       | push esi                                |
010E0879 | 8D 75 FC                 | lea esi,dword ptr ss:[ebp-4]            |
010E087C | C7 45 FC 63 00 00 00     | mov dword ptr ss:[ebp-4],63             | 63:'c'
010E0883 | 0F 4D D6                 | cmovge edx,esi                          |
010E0886 | C7 45 F8 00 00 00 00     | mov dword ptr ss:[ebp-8],0              |
010E088D | 8D 45 F8                 | lea eax,dword ptr ss:[ebp-8]            |
010E0890 | 5E                       | pop esi                                 |
010E0891 | 83 3A 00                 | cmp dword ptr ds:[edx],0                |
010E0894 | 0F 4F C2                 | cmovg eax,edx                           |
010E0897 | 8B 00                    | mov eax,dword ptr ds:[eax]              |
010E0899 | 89 81 D8 24 00 00        | mov dword ptr ds:[ecx+24D8],eax         |
010E089F | A1 D0 A0 4C 01           | mov eax,dword ptr ds:[14CA0D0]          |
010E08A4 | 83 B8 6C F5 10 00 02     | cmp dword ptr ds:[eax+10F56C],2         |
010E08AB | 74 14                    | je isaac-ng.10E08C1                     |
010E08AD | C7 80 6C F5 10 00 01 00  | mov dword ptr ds:[eax+10F56C],1         |
010E08B7 | C7 80 74 F5 10 00 02 00  | mov dword ptr ds:[eax+10F574],2         |
010E08C1 | 8B E5                    | mov esp,ebp                             |
010E08C3 | 5D                       | pop ebp                                 |
010E08C4 | C2 04 00                 | ret 4                                   |

I assume the only parameter the function takes is the number to set the keys to, but as I'm fairly new to RE I'm not so sure. Also if I'm not horribly mistaken, the calling convention should be __cdecl.

I think it may have something to do with ecx set wrong, as its set to something different before the function call in the assembly.

x64dbg log:

EXCEPTION_DEBUG_INFO:
           dwFirstChance: 1
           ExceptionCode: C0000005 (EXCEPTION_ACCESS_VIOLATION)
          ExceptionFlags: 00000000
        ExceptionAddress: 010E0866 isaac-ng.010E0866
        NumberParameters: 2
ExceptionInformation[00]: 00000000 Read
ExceptionInformation[01]: 01661ED8 Inaccessible Address
First chance exception on 010E0866 (C0000005, EXCEPTION_ACCESS_VIOLATION)!

Upvotes: 0

Views: 442

Answers (1)

Lauri Uusaro
Lauri Uusaro

Reputation: 21

Ok, so I researched a bit of how thiscall works and now its sorted out. I changed my dll code to this,

#include <windows.h>
#include <iostream>

struct _Isaac { //Make a class for the function
    typedef void(__thiscall *funcB)(void *pThis, int keyAmount);
    funcB originalFunction;

    void *pThis = (void*)0x12ED56E8; //Address for the instance
};

_Isaac Isaac;

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
{
    uintptr_t modBase = (uintptr_t)GetModuleHandle(NULL);
    Isaac.originalFunction = (_Isaac::funcB)(modBase + 0x150860);
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        Isaac.originalFunction((void*)Isaac.pThis, 17);
        break;
    default:
        break;
    }
    return TRUE;
}

and now it works like it should. Anyway, thx for the quick responds and advices, I'm such a newbie to forget about OOP :)

Upvotes: 2

Related Questions