在wrapper.dll中仅调用一次loadlibrary [英] calling loadlibrary only once in wrapper.dll

查看:63
本文介绍了在wrapper.dll中仅调用一次loadlibrary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个第三方dll base.dll及其关联的lib文件bass.lib.我没有头文件.

我想编写一个包装器dll(wrapper.dll),该文件可以导出许多函数,每个函数都可以调用base.dll中的一个或多个funcitons.

我的问题是:
1)是否可以从base.dll和base.lib生成base.h,以便我可以隐式链接到base.dll?

2)如果我动态链接到base.dll,则有一种方法是在第一次包装wrapper.dll时仅调用一次LoadLibrary(base.dll),而在wrapper.dll卸载时仅调用一次FreeLibrary(),或者我可以调用LoadLibrary和wrapper.dll中每个函数的FreeLibrary会调用base.dll中的函数吗?

我正在使用MSVS2010,C ++.
我的C ++知识非常有限,请慢慢进行...

在此先感谢
Dave

Hi,

I have a third party dll, base.dll, and its associated lib file, bass.lib. I do not have the header file.

I would like to write a wrapper dll, (wrapper.dll) that exports a number of functions, each of which may call one or more of the funcitons in base.dll.

My questions are:
1) Is it possible to generate base.h from base.dll and base.lib so that I can implicitly link to base.dll?

2) If I dynamically link to base.dll is there a way to call LoadLibrary(base.dll) only once when wrapper.dll is first loaded and FreeLibrary() only once when wrapper.dll is unloaded or do I have call LoadLibrary and FreeLibrary in every function in wrapper.dll that calls a function in base.dll?

Im using MSVS2010, C++.
My C++ knowledge is very limited, please go slowly...

Thanks in advance
Dave

推荐答案

1)如果幸运的话.
获取 Dependency Walker [ ^ ]并检查函数名称.
通常,使用C约定导出函数,该函数仅存储函数名称,并且如果不进行逆向工程,则无法获取参数和返回类型.
如果幸运的话,这些函数将使用C ++约定导出,该约定会破坏函数名称以包括参数类型和返回类型. (在Dependency Walker中使用View> Undecorate C ++函数以可读的方式查看它)

如果您在google上浏览,可能会有一种工具可以执行此操作,但是它无法从丢失的头文件中获取结构,#define和类似内容.

2)有一个 DllMain [
1) If you are lucky.
Get a copy of Dependency Walker[^] and check the function names.
Functions are generally exported using the C convention, this only stores the function name, and without reverse engineering there is no way to get parameters and return type.
If you are lucky, then the functions will be exported with the C++ convention, which mangles the function names to include parameter types and return type. (View>Undecorate C++ Functions to view it in a readable manner in Dependancy Walker)

There may be a tool for doing exactly this if you look on google, however it wont be able to get structures, #defines and the likes back from the missing header files.

2) There is a DllMain[^] function that you can export from the DLL which is called when a process/thread attaches/detatches
HMODULE g_hLib = NULL;

BOOL WINAPI DllMain(HINSTANCE hInst, DWORD nReason, LPVOID pReserved) {
	switch (nReason) {
		case DLL_PROCESS_ATTACH:
			g_hLib = LoadLibrary("Base.dll");
			break;

		case DLL_PROCESS_DETACH:
			FreeLibrary(g_hLib);
			break;

		case DLL_THREAD_ATTACH:
			break;

		case DLL_THREAD_DETACH: //EDIT: corrected typo
			break;
	}
	return TRUE;
}


您可以使用免费的 Visual Dumpbin 创建头文件.

可以在XThemeHelper.cpp中找到DLL包装器类的示例(仅调用LoadLibrary一次),该类包含在
You can use the free Visual Dumpbin to create the header file.

An example of a DLL wrapper class (that only calls LoadLibrary once) can be found in XThemeHelper.cpp, which is included in the download for XButtonXP.


我要做的第一件事是去制造商并说帮助!".虽然我过去曾经做过反向工程,但是DLL的接口实在是让人头疼.

您可以按C ++ Dll具有的接口类型对其进行划分.作为广泛的概括,它们是:

-完整的表述-DLL导出类(或者足够一个类,以使其可由客户端程序使用). DLL中的类的行为就像在客户端程序中一样.

-围墙花园-DLL导出一组成对的工厂/拆除功能,其余通过头文件中描述的接口完成.

-伟大的伪装者-它说它是C ++,但它只有一个C接口.

他们每个人都有自己独特的怪癖和困难.请注意,任何DLL都可以包含所有这三个元素,从而为混合添加乐趣和轻巧.

在某些方面,完整的Monte是最容易处理的.如果您有一个导出整个类的库,您可能会从Dependency Walker(如安德鲁建议的)中获得足够的信息,从而能够重建类似于该类的公共接口的内容.这里的问题是,由于您不知道其大小,因此您没有足够的信息来创建该类的实例.我发现解决此问题的唯一方法是尝试使用不同的大小(使类的数据成为字符数组),直到发现没有崩溃的字符为止.一件好事是,如果您高估了大小,那么通常可以通过引用传递对象.如果您必须通过值传递,尽管Dll会以与客户端代码不同的方式解释调用堆栈,因此会产生许多乐趣.哦,您将不会获得任何内联函数-取决于它们的工作方式和工作方式,这可能是问题也可能不是问题.

好的伪装者也可以很容易地被调用,而不会在调用时崩溃您的程序,但仅对于某些类型的函数而言.类型为__stdcall的函数的参数大小会附加在其名称后.因此,如果您看到类似Function@4这样的名称,则知道它需要4个字节的参数.将其声明为单个4字节参数可以解决该问题.如果将其声明为C函数,则可以开始尝试使用巨大的参数大小,因为客户端需要执行清理操作.

围墙花园是一个完整的母狗.您没有类型信息.您不知道所提供的是什么,只是它是一个指针.某种.然后您必须将其归还.如果工厂函数为__stdcall,则您甚至都没有返回类型的类型名称.

无论如何,如果幸运的话,您可能最终会得到一个头文件,该头文件描述了经过某种方式后与DLL的接口.您将不知道函数的参数是什么-您可能知道完整的monte类的类型名称,但不知道它们的用途.接下来要做的是开始通过您发现的界面对Dll进行标记,然后查看是否可以使其适当地咯咯地笑.您可以通过调试器来破解自己的方法,也可以尝试将其分解.想法是找到参数用于什么以及它们将修改哪些内部状态(如果有).一些功能很容易发现-例如,大脑受损的获取/设置对.但是,有时编译器会有些笑,您会发现优化器很忙,而您正在查看的代码似乎没有很好的描述性.如果您的库具有虚函数,则可以为类的实例找到v表的地址(通常是对象的前4个字节,请注意多重继承),然后跟踪特定调用的方式将执行.对于围墙花园,您将不得不做很多事情.

这样的结果是,您确实确实需要像这样的库来摆弄.等到您可以获得可靠的东西时,最好编写自己的代码来做到这一点.请不要认为这是一件容易的事!尽管了解我做出这样的声明的记录,但也许有人会得到一个开源程序,它将为您完成所有这些工作:-).

干杯,



PS:只要想到我尝试过的其他方法-如果您已经编译了一个示例客户端,则可以看到对Dll的调用发生了什么.如果某些东西使堆栈指针下降了24个字节,则将地址压入堆栈,然后调用具有该类大小的默认构造函数.

因此,如果您愿意吸引任何客户,以获取更多信息.
The first thing I''d do is go to the manufacturer and say "help!" While I''ve done it in the past reverse engineering the interface to a DLL is a real pain in the bum.

You can divide C++ Dlls up by what sort of interface they have. As a broad sweeping generalisation they are:

- The full monte - the DLL exports classes (or rather enough of a class to enable it''s use by a client program). Classes in the DLL act just like they were in the client program.

- Walled garden - the DLL exports a set of pairs of factory/demolition functions and the rest is done through interfaces described in a header file.

- The great pretender - it says it''s C++ but it''s just got a C interface.

Each of them have their own particular quirks and difficulties. Note that any DLL can have elements of all three in it to add fun and frivolity to the mix.

In some respects the full Monte is the easiest to handle. If you''ve got a library that exports whole classes you''ll probably get enough information from Dependency Walker (as Andrew suggested) to be able to reconstruct something that looks like the public interface to that class. The problem here is that you''ve not quite got enough information to create instances of the class as you don''t know it''s size. About the only way I found of working this out was trying different sizes (making the data of a class an array of characters) until I found one that didn''t crash. One good thing is that if you overestimate the size then you can generally get away with passing the object by reference. If you have to pass by value though the Dll will interpret the call stack differently from your client code and much merriment follows. Oh, and you won''t get any inline functions - which may or may not be a problem depending on what they do and how they do it.

The great pretender can also be fairly easy to call without crashing your program on the call but only for certain types of functions. Functions with a __stdcall type have the size of their parameters appended to their name. So if you see something like Function@4 as a name you know it wants 4 bytes worth of parameters. Declaring it as something as a single 4 byte parameter would sort that out. if it''s declared as a C function then you can start experimenting with huge parameter sizes as the client is the thing that does the cleanup.

The walled garden is a complete bitch. You have no type information. You don''t know what you''re being supplied, except that it''s a pointer. Of some kind. And you have to give it back afterwards. If the factory functions are __stdcall you won''t even have a type name for a return type.

Anyway, if you''re lucky you might end up with a header file that describes the interface to the DLL after a fashion. You won''t know what the parameters to the functions are - you might know their type names for a full monte class but you won''t know what they''re used for. The next thing you have to do is start tickling the Dll through the interface you''ve discovered and see if you can get it to giggle appropriately. You can either start hacking your way through with a debugger or try disassembling it. The idea is to find what the parameters are used for and what internal state, if any, they modify. Some functions are easy to spot - brain damaged get/set pairs for example. However sometimes the compiler has a bit of a laugh and you''ll find that the optimiser has been busy and the code you''re looking at doesn''t appear very descriptive. If your library has virtual functions you can find the address of the v-table (it''s usually the first 4 bytes of an object, watch out for multiple inheritance) for an instance of the class and then trace through how a particular call would execute. You''re going to have to do a lot of that for walled gardens.

The upshot of this lot is that you really have to need that library to fiddle around like this. By the time you can get something reliable out of it you might be better off writing your own code to do it. Please don''t think it''s an easy job! Although knowing my track record of making such pronouncements someone''s probably got an open source program that''ll do all this for you :-).

Cheers,

Ash

PS: Just thought of something else I''ve tried - if you''ve got an example client that''s compiled you can see what happens around the calls to the Dll. If something drops the stack pointer by 24 bytes, pushes the address on the stack then calls the default constructor you''ve got the size of the class.

So if you''ve got one pull any clients to pieces for extra information.


这篇关于在wrapper.dll中仅调用一次loadlibrary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆