alliedmodders / sourcemod

SourceMod - Source Engine Scripting and Administration
http://www.sourcemod.net/
980 stars 424 forks source link

GetReturnAddress call does not preserve 16-byte stack alignment for Linux #1997

Open qubka opened 1 year ago

qubka commented 1 year ago

Description

Not so long ago, I delved into the DynamicHooks/DHook library in order to understand its inner workings. After thoroughly examining the library, I decided to create my own version that would be compatible with both x64 and x32 and would include the ability to work with Virtual Hook.

As I was working on this project, I encountered a small issue on 32bit. While it may not be a serious problem, I noticed that calling GetReturnAddress does not preserve 16-byte stack alignment for Linux, when HookHandler call took this into account.

Problematic Code

// Get the original return address
void* (__cdecl CHook::*GetReturnAddress)(void*) = &CHook::GetReturnAddress;
masm.push(esp);
masm.push(intptr_t(this));
masm.call(ExternalAddress((void *&)GetReturnAddress));
masm.addl(esp, 8);

->

// Get the original return address
void* (__cdecl CHook::*GetReturnAddress)(void*) = &CHook::GetReturnAddress;
masm.movl(eax, esp);
masm.subl(esp, 4);
masm.push(eax);
masm.push(intptr_t(this));
masm.call(ExternalAddress((void *&)GetReturnAddress));
masm.addl(esp, 12);
sapphonie commented 1 year ago

vaguely related to https://github.com/alliedmodders/sourcemod/pull/1849