簡體   English   中英

如何使用函數指針從其內存地址調用成員函數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM