Created
October 31, 2020 18:55
-
-
Save RolfRolles/7e5103948266202458adfbfaee3265f1 to your computer and use it in GitHub Desktop.
Example showing how to cast member function pointers and use proxy stubs during DLL injection / code reuse
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#undef USE_MAY20_VERSION | |
#define USE_OCT20_VERSION 1 | |
#ifdef USE_OCT20_VERSION | |
#define OFFS_ValveBuffer_Constructor 0x83A9E0 | |
#define OFFS_ValveBuffer_Destructor 0x83FC30 | |
#define OFFS_ValveBuffer_PutByte 0x83C8D0 | |
#define OFFS_ValveBuffer_PutByteBuffer 0x83BDA0 | |
#define OFFS_ValveBuffer_PutString 0x44C940 | |
#define OFFS_ValveBuffer_GetByteBuffer 0x44C070 | |
#endif | |
// Code taken from StackExchange | |
template<typename classT, typename memberT> | |
union u_ptm_cast { | |
memberT classT::*pmember; | |
void *pvoid; | |
}; | |
class ValveBuffer | |
{ | |
protected: | |
typedef ValveBuffer *(ValveBuffer::constructor)(uint32_t GrowSize, uint32_t AllocationCount, uint8_t flags); | |
static u_ptm_cast<ValveBuffer,constructor> mFPConstructor; | |
typedef void (ValveBuffer::destructor)(); | |
static u_ptm_cast<ValveBuffer, destructor> mFPDestructor; | |
typedef void (ValveBuffer::putByte)(uint8_t); | |
static u_ptm_cast<ValveBuffer, putByte> mFPPutByte; | |
typedef void (ValveBuffer::putByteBuffer)(uint8_t *, size_t); | |
static u_ptm_cast<ValveBuffer, putByteBuffer> mFPPutByteBuffer; | |
typedef bool (__cdecl *putString)(ValveBuffer *, const char *); | |
static putString mFPPutString; | |
typedef bool (__cdecl *getByteBuffer)(ValveBuffer *, uint8_t *, size_t); | |
static getByteBuffer mFPGetByteBuffer; | |
public: | |
static void InitFuncPtrs(void *DLLBase) { | |
//mFPConstructor.pvoid = NULL; | |
mFPConstructor.pvoid = (reinterpret_cast<char *>(DLLBase) + OFFS_ValveBuffer_Constructor); | |
mFPDestructor.pvoid = (reinterpret_cast<char *>(DLLBase) + OFFS_ValveBuffer_Destructor); | |
mFPPutByte.pvoid = (reinterpret_cast<char *>(DLLBase) + OFFS_ValveBuffer_PutByte); | |
mFPPutByteBuffer.pvoid = (reinterpret_cast<char *>(DLLBase) + OFFS_ValveBuffer_PutByteBuffer); | |
mFPPutString= reinterpret_cast<putString>(reinterpret_cast<char *>(DLLBase) + OFFS_ValveBuffer_PutString); | |
mFPGetByteBuffer = reinterpret_cast<getByteBuffer>(reinterpret_cast<char *>(DLLBase) + OFFS_ValveBuffer_GetByteBuffer); | |
} | |
ValveBuffer(uint32_t GrowSize = 64, uint32_t AllocationCount = 32, uint8_t flags = 0) { | |
auto x = mFPConstructor.pmember; | |
(this->*x)(GrowSize, AllocationCount, flags); | |
} | |
~ValveBuffer() { | |
(this->*mFPDestructor.pmember)(); | |
} | |
void PutByte(uint8_t b) { | |
(this->*mFPPutByte.pmember)(b); | |
} | |
void PutWord(uint16_t w) { | |
PutByteBuffer((uint8_t *)&w, sizeof(uint16_t)); | |
} | |
void PutDword(uint32_t d) { | |
PutByteBuffer((uint8_t *)&d, sizeof(uint32_t)); | |
} | |
void PutQword(uint64_t q) { | |
PutByteBuffer((uint8_t *)&q, sizeof(uint64_t)); | |
} | |
void PutByteBuffer(uint8_t *b, size_t n) { | |
(this->*mFPPutByteBuffer.pmember)(b, n); | |
} | |
void PutString(const char *str) { | |
mFPPutString(this, str); | |
} | |
bool GetByteBuffer(uint8_t *b, size_t n) { | |
return mFPGetByteBuffer(this, b, n); | |
} | |
bool GetByte(uint8_t *b) { | |
return GetByteBuffer(b, sizeof(uint8_t)); | |
} | |
bool GetWord(uint16_t *w) { | |
return GetByteBuffer((uint8_t*)w, sizeof(uint16_t)); | |
} | |
bool GetDword(uint32_t *d) { | |
return GetByteBuffer((uint8_t*)d, sizeof(uint32_t)); | |
} | |
bool GetQword(uint64_t *q) { | |
return GetByteBuffer((uint8_t*)q, sizeof(uint64_t)); | |
} | |
}; | |
decltype(ValveBuffer::mFPConstructor) ValveBuffer::mFPConstructor; | |
decltype(ValveBuffer::mFPDestructor) ValveBuffer::mFPDestructor; | |
decltype(ValveBuffer::mFPPutByte) ValveBuffer::mFPPutByte; | |
decltype(ValveBuffer::mFPPutByteBuffer) ValveBuffer::mFPPutByteBuffer; | |
decltype(ValveBuffer::mFPGetByteBuffer) ValveBuffer::mFPGetByteBuffer; | |
decltype(ValveBuffer::mFPPutString) ValveBuffer::mFPPutString; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment