Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example showing how to cast member function pointers and use proxy stubs during DLL injection / code reuse
#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