在Delphi中获取DLL类过程地址
我有一个 DLL 文件,我需要从中获取类过程的内存地址。我正在获取 DLL 文件的句柄,但是当我使用 GetProcAddress 时,我无法获取该过程的地址。我已尝试使用以下字符串作为进程名称参数:
"ProcName"
"ProcClass.ProcName"
"ProcClass::ProcName"
"ProcInterface::ProcName"
"ProcInterface.ProcName"
在任何情况下我都没有获得过程的内存地址。我基本确定该程序是公开的。
执行此操作的字符串格式是什么?声明一个指向外部过程的函数并稍后获取地址会更容易吗?像这样:
procedure ProcName(); stdcall; far; external 'Example.DLL';
ProcPointer := @ProcName;
I have a DLL file from which I need the memory address of a class procedure. I am getting the handle to the DLL file, but when I use GetProcAddress, I can't get the address of the procedure. I have tried the following strings for the process name parameter:
"ProcName"
"ProcClass.ProcName"
"ProcClass::ProcName"
"ProcInterface::ProcName"
"ProcInterface.ProcName"
In none of the cases have I gotten the memory address of the procedure. I am mostly certain that the procedure is public.
What is the string format for doing this? Would it be easier to declare a function pointing to the external procedure and get the address later? Like this:
procedure ProcName(); stdcall; far; external 'Example.DLL';
ProcPointer := @ProcName;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
GetProcAddress
只为您提供导出函数的地址。你的 DLL 肯定不会导出类的方法!使用
PE
浏览器查找导出的名称。例如,使用 GExperts 中提供的PE
浏览器。我在 GExperts 菜单下有一个“PE 信息”菜单项。GetProcAddress
only gives you the address for exported functions. Your DLL surely doesn't export the methods of a class!Use an
PE
explorer to look for the exported names. For example, use thePE
explorer available in GExperts. I've got a "PE Information" menu entry under the GExperts menu.您已经进入了逆向工程领域。
我想,如果我是你,我会在调用感兴趣的方法之后,在调试器的 CPU 视图中单步执行,并找到入口点地址。我将从 DLL 的基地址中减去它,这就是偏移量。然后,要在运行时计算地址,只需将偏移量添加到当时内存中 DLL 的基地址即可。您可以通过调用 LoadLibrary 或 GetModuleHandle 找到基地址。
为什么要对偏移量进行硬编码?好吧,既然你不能修改你的 DLL,它似乎并没有太大的限制。如果对偏移进行硬编码不可行,那么还有其他方法来定位入口点,但我必须承认我不是世界上最伟大的专家。
最后,当您实现替换方法时,您需要将其替换为带有额外参数的全局函数/过程,即第一个参数,它取代了 Self。
You are into reverse engineering territory here.
I think that if I were you I would just step through in the CPU view of the debugger, following a call to the method of interest, and find the entry point address. I'd subtract it from the base address of the DLL and that would be the offset. Then to calculate the address at runtime you just add the offset it to the base address of the DLL in memory at that time. You can find out the base address with calls to LoadLibrary or GetModuleHandle.
Why hard code the offset? Well, since you can't modify your DLL it doesn't seem to be too limiting. If hard coding the offset is not viable then there are other means of locating entry points, but I must admit I'm not the world's greatest expert on that.
Finally, when you implement the replacement method, you will need to replace it with a global function/procedure with an extra parameter, the first parameter, which takes the place of Self.
我可能读错了。但在我看来,DLL 是你写的。
您应该编写一个不属于任何类的函数,并将其从 DLL 中导出。在该函数内,调用您的类方法。
如果您没有编写 DLL,您仍然需要找出它导出的函数,并且它们中的任何一个都不太可能是类方法,至少在 Pascal 中不是。
如果有人用 C++ 编写了一个 dll 并导出了它的方法,那么您就必须研究 C++ 名称修饰规则。
I might be reading this wrong. But it seems to me you wrote the DLL.
You should write a function that is NOT a member of any class, and export it from your DLL. Inside that function, call your class method.
If you didn't write the DLL, you still need to find out what functions it exports, and it is very unlikely any of them were class methods, at least not in Pascal.
If someone wrote a dll in C++ and exported its methods, then you would have to investigate C++ name mangling rules.