3

这是一个糟糕的想法,但在我走这条路之前,我正在看看它是否可行。

我必须编写一个 Win32 C++ 程序,它可以基于一个文件动态加载一个库,该文件具有关于要使用的 dll、函数、签名和参数的序列化信息。加载库很简单(LoadLibraryEx 工作正常)。然后获取函数指针很容易(没什么大不了的,GetProcAdderss 会处理这个)。然而,其余的很棘手。

这是我的攻击计划,如果这不是最好的方法,请随时告诉我:

  1. 从文件中打开关于要加载什么 DLL 以及要执行什么函数的序列化信息。
  2. LoadLibraryEx 引入 DLL
  3. GetProcAddress 获取函数指针(将字节数组转换为字符串后)
  4. 以字节为单位将参数(作为字节数组读入)写入内存。
  5. 获取每个参数开头的地址(我将从序列化中知道每个参数的大小是多少)。
  6. 使用汇编跳转到函数指针的开头,将堆上的地址推送到堆栈中的参数(以相反的顺序)。
  7. 执行并取回返回值地址(作为 void * ?)
  8. 使用返回值的内存地址(我从程序集中获得)和返回类型值的大小(我从序列化中获得)并将原始字节写回文件。

请记住我的局限性:

  1. 除了运行时,我永远不会知道签名、dll、函数名是什么。
  2. 它总是从文件中读入。

有没有更好的方法,这种方法是否有效?

更新

对于任何在此线程中戳以了解更多信息的人,我找到了一个解决方案。在 C 中,您可以使用 dlopen 动态加载库(为了便于使用,有一个 winlib)。加载后,您可以使用 libffi 动态执行函数(支持 mac/ios/win 64 和 32 位)。这只会让您了解 C 函数和原始类型(指针、uint、int、double、float),仅此而已。但是,使用 macosx Objective-c 桥接器,您可以通过加载 libobjc(osx 的本机 obj-c 到 c“免费”桥接器)来访问 Objective-c。然后通过它动态创建 obj-c 和 c++ 类。可以使用 C# 及其编组功能在 Windows 上完成类似的技术。

这最终会导致高开销,并且您必须非常小心您的内存,此外不要混合来自 C/C#/C++ 的指针。最后,无论你做什么,在运行时。绝对确定你知道你的类型......认真。顺便说一句,libffi/cinvoke,很棒的库。

4

2 回答 2

3

现有的库可以执行您描述的操作,例如 C/Invoke:

http://www.nongnu.org/cinvoke/

于 2013-06-11T21:50:32.083 回答
2

General rule, that if you have a terrible idea, drop it and find a good one.

If the signature is not known at all, what you describe will fall on face. Suppose your call works for my function as it is. I change the function from __stdcall to __cdecl or back, and you will crash.

Also you don't handle the return.

If you relax the "unknown" to allow some limitations, like fixing a return type and calling convention, you are somewhat ahead -- then really you can emulate the call but what is it good for? This whole thing sounds like a self-service hack-me engine.

The normal way is to publish some fixed interface (using function signatures), and make the DLL support it. Or arrange some uniform data transfer mechanism.

I'd suggest you to describe what you're after really and post ask that, maybe on Programmers SE.

于 2013-06-11T18:31:49.293 回答