I'm trying to create a bot for a game called "Mech Warrior Online". I've just completed my DLL injector which I want to use as mean to call function from the MWO client such as (fire, move, look around, etc...).
My problem is that I'm not great at reverse engineering, I'm trying hard to learn with tutorials, but I haven't found a particular one which addresses my problem.
So here goes, by using IDA and looking at strings, I've found this:
Fire1 through Fire6 are most likely related to shooting weapons group 1-6. So if I click on it I get this;
Now this function looks very interesting, seems to control the power on/off of the mech, jumpjets, turning, throttle, weapons firing etc.
My problem is that I'd like to call this function to fire the weapons, but I can't seem to figure out how. I did some tutorials where I was able to inject my dll and call functions remotely via exports. But this function is very complex (in my opinion). Here's a look inside:
int __stdcall sub_37FC7C90(int a1)
{
int result; // eax@5
int v2; // edx@5
int v3; // [sp+14h] [bp-4h]@2
int result; // eax@5
int v2; // edx@5
int v3; // [sp+14h] [bp-4h]@2
if ( !(dword_38CB3580 & 1) )
{
dword_38CB3580 |= 1u;
dword_38CB33F8 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 1;
dword_38CB33E8 = (int)"Enabled";
dword_38CB33EC = 0;
dword_38CB33F0 = (int)szAgent;
dword_38CB33F4 = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB33FC,
&v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3410 = (unsigned int)&unk_389BAF54 | 1;
v3 = 0;
dword_38CB3400 = (int)"Throttle";
dword_38CB3404 = 0;
dword_38CB3408 = (int)szAgent;
dword_38CB340C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB3414,
&v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3428 = (unsigned int)&unk_389BAF54 | 1;
v3 = 0;
dword_38CB3418 = (int)"Turn";
dword_38CB341C = 0;
dword_38CB3420 = (int)szAgent;
dword_38CB3424 = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB342C,
&v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3440 = (unsigned int)&unk_389BB168 | 1;
v3 = 0;
dword_38CB3430 = (int)"TurnTarget";
dword_38CB3434 = 0;
dword_38CB3438 = (int)szAgent;
dword_38CB343C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB3444,
&v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3458 = (unsigned int)&unk_389BB168 | 1;
v3 = 0;
dword_38CB3448 = (int)"LookTarget";
dword_38CB344C = 0;
dword_38CB3450 = (int)szAgent;
dword_38CB3454 = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB345C,
&v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3470 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 0;
dword_38CB3460 = (int)"JumpJet";
dword_38CB3464 = 0;
dword_38CB3468 = (int)szAgent;
dword_38CB346C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB3474,
&v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3488 = (int)&unk_389BAE60;
dword_38CB3478 = (int)"PowerOn";
dword_38CB347C = 0;
dword_38CB3480 = (int)szAgent;
dword_38CB3484 = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB348C, &v3);
(*(void (__cdecl **)(int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
dword_38CB34A0 = (int)&unk_389BAE60;
dword_38CB3490 = (int)"PowerOff";
dword_38CB3494 = 0;
dword_38CB3498 = (int)szAgent;
dword_38CB349C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB34A4, &v3);
(*(void (__cdecl **)(int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
dword_38CB34B8 = (int)&unk_389BAE60;
dword_38CB34A8 = (int)"TogglePower";
dword_38CB34AC = 0;
dword_38CB34B0 = (int)szAgent;
dword_38CB34B4 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB34BC, &v3);
(*(void (__cdecl **)(_DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
dword_38CB34D0 = (int)&unk_389BAE60;
dword_38CB34C0 = (int)"ToggleWeaponDoors";
dword_38CB34C4 = 0;
dword_38CB34C8 = (int)szAgent;
dword_38CB34CC = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB34D4, &v3);
(*(void (__cdecl **)(_DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
dword_38CB34E8 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 0;
dword_38CB34D8 = (int)"Fire1";
dword_38CB34DC = 0;
dword_38CB34E0 = (int)szAgent;
dword_38CB34E4 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB34EC,
&v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3500 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 0;
dword_38CB34F0 = (int)"Fire2";
dword_38CB34F4 = 0;
dword_38CB34F8 = (int)szAgent;
dword_38CB34FC = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB3504,
&v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3518 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 0;
dword_38CB3508 = (int)"Fire3";
dword_38CB350C = 0;
dword_38CB3510 = (int)szAgent;
dword_38CB3514 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB351C,
&v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3530 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 0;
dword_38CB3520 = (int)"Fire4";
dword_38CB3524 = 0;
dword_38CB3528 = (int)szAgent;
dword_38CB352C = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB3534,
&v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3548 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 0;
dword_38CB3538 = (int)"Fire5";
dword_38CB353C = 0;
dword_38CB3540 = (int)szAgent;
dword_38CB3544 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB354C,
&v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3560 = (unsigned int)&unk_389BAE80 | 1;
LOBYTE(v3) = 0;
dword_38CB3550 = (int)"Fire6";
dword_38CB3554 = 0;
dword_38CB3558 = (int)szAgent;
dword_38CB355C = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
&unk_38CB3564,
&v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
dword_38CB3568 = 0;
dword_38CB356C = 0;
dword_38CB3570 = 0;
dword_38CB3574 = 0;
dword_38CB357C = 0;
dword_38CB3578 = (int)&unk_389BAEA0;
atexit(sub_386F1FC0);
}
if ( !(dword_38CB3580 & 2) )
{
dword_38CB3580 |= 2u;
dword_38CB33D4 = 0;
dword_38CB33D8 = 0;
dword_38CB33DC = 0;
dword_38CB33E0 = 0;
}
result = a1;
v2 = *(_DWORD *)(a1 + 8);
*(_DWORD *)(a1 + 12) = szAgent;
*(_DWORD *)a1 = &dword_38CB33E8;
*(_DWORD *)(a1 + 4) = &dword_38CB33D4;
*(_DWORD *)(a1 + 8) = v2 & 0xFFFFF01F | 0x11;
return result;
}
I'm sorry, I know it's very messy, but the function is pretty big.
Anybody could tell me how to call let's say Fire1
from my DLL? I really have no idea how to do it at this point. I know I'm totally over my head, but I'd like to learn!
Thx to anyone willing to lend a hand! Cheers
__usercall
s, but it's very easily adaptable to__stdcall
s.