Skip to content

Instantly share code, notes, and snippets.

@tame-64
Last active August 3, 2022 14:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tame-64/1aa0132fc899a044112c53a29d21bf1b to your computer and use it in GitHub Desktop.
Save tame-64/1aa0132fc899a044112c53a29d21bf1b to your computer and use it in GitHub Desktop.
a fix for airstrike3D game crash for modern hardware. (a buffer overrun fix).
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdio.h>
// compile with msvc or with mingw with -m32 flag; with target name as3dres.dll;
// rename original as3dres.dll to as3dre2.dll
// drop in the compiled dll into game folder.
void init_patch();
#ifdef _MSC_VER
#define FORWARDED_EXPORT(exp_name, target_name) __pragma (comment (linker, "/export:" #exp_name "=" #target_name))
#elif __MINGW32__
#define FORWARDED_EXPORT(exp_name, target_name) asm (".section .drectve\n\t.ascii \" -export:" #exp_name "= " #target_name "\"");
#endif
FORWARDED_EXPORT(DoMessage, as3dre2.DoMessage);
BOOL __stdcall DllMain(HMODULE hInstance, UINT_PTR ulReason, LPVOID pvReserved)
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
init_patch();
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
bool write_memory(void* destination, const void* source, size_t size) {
DWORD old_protection = 0;
if (::VirtualProtect(destination, size, PAGE_READWRITE, &old_protection)) {
::memcpy(destination, source, size);
DWORD throw_away = 0;
return ::VirtualProtect(destination, size, old_protection, &throw_away);
}
return false;
}
bool write_jump(LONG From, LONG To)
{
if ((To < (From + 128)) && (To > (From - 128))) {
BYTE bpJump[2] = { 0xEB, BYTE((To - From) - 0x02) };
return write_memory((void*)From, bpJump, 2);
}
BYTE bpJump[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
*(DWORD*)&bpJump[1] = (To - From) - 5; //Calculate jump
return write_memory((void*)From, bpJump, 5);
}
// return might be incorrect, but hey! it works!
void __cdecl write_log(const char* format_string, ...) {
FILE* log = nullptr;
#ifdef _MSC_VER
if (0 == ::fopen_s(&log, "astrike.log", "a+"))
#else
if (log = fopen("astrike.log", "a+"))
#endif //
{
va_list arg_list;
va_start(arg_list, format_string);
#ifndef _MSC_VER
if (log) ::vfprintf(log, format_string, arg_list);
#else
if (log) ::vfprintf_s(log, format_string, arg_list);
#endif
if (log) ::fclose(log);
va_end(arg_list);
}
}
void init_patch()
{
// another game version require another address
// WriteJump(0x0041E0B0, (DWORD)write_log);
write_jump(0x0040C280, (LONG)write_log);
}
@SalimF
Copy link

SalimF commented Jul 15, 2022

I got this error (I'm compile it on Linux )

$ i686-w64-mingw32-g++ airstrike3d_fix.cpp -m32  -mwindows -o as3dres
/usr/lib/gcc/i686-w64-mingw32/12.1.0/../../../../i686-w64-mingw32/bin/ld: /usr/lib/gcc/i686-w64-mingw32/12.1.0/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o): in function `main':
/build/mingw-w64-crt/src/mingw-w64-v10.0.0/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain@16'
collect2: error: ld returned 1 exit status

@tame-64
Copy link
Author

tame-64 commented Jul 31, 2022

Hi, it need to be compiled as a dll, not as an executable. please append an extension to the output name.
Also this 'fix' is for GH (game house) version. Another version required another specific offset to patch.

@SalimF
Copy link

SalimF commented Aug 3, 2022

Thanks for reply, actually I tried to compile it on Linux and looks it won't work, can you gave me hint how to compile it on Windows e.g. via MS Visual Studio 2015 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment