I was inspired by Tutrakan's guide ([1.12.1] Trouble calling DefaultServerLogin) to making the client log in automatically using Lua GLUE function DefaultServerLogin(), but I couldn't find the offset for it in 2.4.3 (I thought it to be 0x00899398, but that crashed immediately), so I used AttemptLogin2() instead (see this article which describes the login proces indepth: Under the Hood: World of Warcraft – Logging In – Recelate Blog)
I found the following offsets for 2.4.3 using IDA Pro and Cheat Engine:
PHP Code:
#define GAMESTATE 0x00C07CD0 // string
#define LOGIN 0x0046E560 // function
#define ENTERWORLD 0x00471940 // function
typedef void(__cdecl *AttemptLogin2)(char *name, char *password);
typedef void(__cdecl *EnterWorld)();
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /* reserved */)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
// disables thread notifications (DLL_THREAD_ATTACH, DLL_THREAD_DETACH)
DisableThreadLibraryCalls(hModule);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&MainThreadControl, NULL, 0, NULL);
}
return TRUE;
}
DWORD MainThreadControl(LPVOID lpParm)
{
while (1) {
char *gamestate = (char*)GAMESTATE;
if (strcmp(gamestate, "login") == 0) {
char user[]{ "MyAccount" };
char pass[]{ "MyPassword" };
AttemptLogin2 login = (AttemptLogin2)LOGIN;
login(user, pass);
} else if (strcmp(gamestate, "charselect") == 0) {
EnterWorld enterworld = (EnterWorld)ENTERWORLD;
enterworld();
break;
}
Sleep(500); // std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
return 0;
}
This is how I got to AttemptLogin2() using IDA Pro: [ASM (NASM)] WoW 2.4.3 DefaultServerLogin() - Pastebin.com
Now, the problém is that this successfully logs me into the game only 1 out of 5 times. 4 out of 5 it crashes with different errors such as:
>> The instruction at "0x663C8E75" referenced memory at "0X00000078". The memory could not be "written". <<
or
>> The instruction at "0x6639CC33" referenced memory at "0x00000010". The memory could not be "read". <<
or
>> AsyncFileReadWait(): s_waiting != FALSE <<
I would appreciate any advice. My guess is that I am skipping some vital functions which initialize some variables which the game relies on.