Reputation: 21
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
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