在 DLL 中调用非导出函数

2021-12-25 00:00:00 function dll assembly c++

我有一个加载 DLL 的程序,我需要调用它包含的非导出函数之一.有什么办法可以通过在调试器中搜索或其他方式来做到这一点吗?在有人问之前,是的,我有函数的原型和东西.

I have a program which loads DLLs and I need to call one of the non-exported functions it contains. Is there any way I can do this, via searching in a debugger or otherwise? Before anyone asks, yes I have the prototypes and stuff for the functions.

推荐答案

是的,至少有一点,但这不是一个好主意.

Yes there is, at least sort of, but it isn't a good idea.

在 C/C++ 中,函数指针就是内存中的地址.所以如果你能以某种方式找到这个函数的地址,你可以调用它.

In C/C++ all a function pointer is, is an address in memory. So if you somehow where able to find the address of this function you could call it.

让我问一些问题,你怎么知道这个DLL包含这个函数?你有源代码吗?否则我不知道您如何确定此函数存在或调用是否安全.但是,如果您有源代码,则只需公开该函数即可.如果 DLL 编写者没有公开这个函数,他们永远不会期望你调用它并且可以随时更改/删除实现.

Let me ask some questions though, how do you know this DLL contains this function? Do you have the source code? Otherwise I don't know how you could know for certain that this function exists or if it is safe to call. But if you have the source code, then just expose the function. If the DLL writer didn't expose this function, they never expect you to call it and can change/remove the implementation at any time.

除了警告之外,如果您有调试符号或MAP 文件,您可以在 DLL 中找到偏移量.如果您除了 DLL 之外什么都没有,那么就无法知道该函数在 DLL 中的位置――它没有存储在 DLL 本身中.

Warnings aside, you can find the function address if you have debug symbols or a MAP file you can find the offset in the DLL. If you don't have anything but the DLL, then there is no way to know where that function exists in the DLL - it is not stored in the DLL itself.

一旦你有了偏移量,你就可以像这样将它插入到代码中:

Once you have the offset you can then insert that into the code like so:

const DWORD_PTR funcOffset = 0xDEADBEEF;
typedef void (*UnExportedFunc)();

....
void CallUnExportedFunc() {
     // This will get the DLL base address (which can vary)
     HMODULE hMod = GetModuleHandle("My.dll"); 
     // Calcualte the acutal address 
     DWORD_PTR funcAddress = (DWORD_PTR)hMod + funcOffset;
     // Cast the address to a function poniter
     UnExportedFunc func = (UnExportedFunc)funcAddress;
     // Call the function
     func();
}

还要意识到这个函数的偏移量会在每次重建 DLL 时发生变化,所以这非常脆弱,让我再说一遍,这不是一个好主意.

Also realize that the offset of this function WILL CHANGE EVERY TIME the DLL is rebuilt so this is very fragile and let me say again, not a good idea.

相关文章