[英]How to use function pointers to call member functions from its memory address?
我正在為舊應用程序開發補丁,該應用程序的所有者不再擁有src代碼。
我在其main()之前將dll注入到目標應用程序的.exe中。 這個dll安裝了我做的補丁。
該應用程序具有C ++自定義類型(類或結構),似乎是圖形字體管理器,具有一些我需要通過其中一些補丁調用的功能。
我通常稱這些“本機”成員函數的方式是創建一個包裝函數,該函數通過asm內聯調用本機成員函數。 我這樣做是因為我無法找到如何通過C ++函數指針來完成此操作。
與創建許多腫的函數包裝器相比,我再次嘗試以更好的方式完成此任務。 這次,我嘗試使用類/結構作為該本機類型的虛擬包裝器,但是似乎缺少與我無法弄清的函數指針語法相關的內容。
這是我正在嘗試做的一個示例:
/* NC for Native Class */
class NC_FontDevice
{
public:
typedef void(NC_FontDevice::*_UseTexturesTransparency)();
_UseTexturesTransparency *UseTexturesTransparency = reinterpret_cast<_UseTexturesTransparency*>(0x635FD0);
private:
NC_FontDevice(){}
};
NC_FontDevice* GetFontDevice()
{
NC_FontDevice* lpFontDevice = nullptr;
/*
This asm inline block is here to show more or less what I do in those wrappers I told.
I know this can be converted to a simple function pointer.
*/
__asm
{
mov eax, 0x0041FE10
call eax
mov lpFontDevice, eax
}
return lpFontDevice;
}
void foo()
{
auto lpFontDevice = GetFontDevice();
// Here I get and "identifier X is undefined"
(lpFontDevice->**UseTexturesTransparency)();
}
如果很清楚我想要什么,除了該函數包裝器之外,還有更好的方法嗎?
提前致謝。
您的問題之一至少是您的代碼與您的問題不匹配。 您談論的是函數指針,但您編寫的是void(NC_FontDevice::*_UseTexturesTransparency)()
。 那不是函數指針。 這是指向成員函數(PMF)的指針。 完全不同的野獸,您不能假設它們是簡單的指針。 它們通常甚至都不相同。
我懷疑您在0x635FD0
處找到了一個函數。 該函數可能看起來像void _UseTexturesTransparency(NC_FontDevice*)
。 當然,在編譯時它可能是成員函數的一部分,但這並不重要。 這是黑客行為,我們在這里很實用。 如果我們可以將它視為普通的函數指針,為什么還要處理PMF的復雜性呢?
[edit]根據注釋,MSVC ++將在成員函數中使用ECX
作為this
參數。 碰巧的是,它還支持常規函數的__fastcall
調用約定,該約定將前32位參數放入ECX
。 這不是一個完美的替代品。 __fastcall
還使用EDX作為第二個參數。 如果現有代碼在堆棧上需要其他參數,則可能需要在其中使用虛擬參數。
您可以檢查堆棧參數,因為在成員函數的__thiscall
調用約定下,被調用方將清理堆棧。 幸運的是,這與__fastcall
約定匹配。
您是否考慮過使用std :: bind和std :: function代替? C ++ 11和boost有它。
std::function x = std::bind(&ClassName::function,this);
這將創建一個對您的對象起作用的回調函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.