简体   繁体   English

MFC 应用程序和共享库

[英]MFC app and shared libs

I have a application which seems has written in MFC (process hacker and DependencyWalker show link to MFC90).我有一个似乎是用 MFC 编写的应用程序(进程黑客和 DependencyWalker 显示指向 MFC90 的链接)。

Also, There is a library(FTD2XX) in the installation path.另外,安装路径中有一个库(FTD2XX)。 But the DependencyWalker won't show the MFC90 link for the lib and show:但是 DependencyWalker 不会显示库的 MFC90 链接并显示:

SetupAPI.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll

In what framework the lib is built? lib是在什么框架中构建的? I don't have experience in MFC.我没有 MFC 的经验。 I don't have information in its compiler and if VC++ libs can be used to link with MFC apps.我的编译器中没有信息,以及是否可以使用 VC++ 库与 MFC 应用程序链接。

If you want to log calls going to a dll, the best way is to write a proxy dll (a dll redirection).如果要记录对 dll 的调用,最好的方法是编写代理 dll(dll 重定向)。 But for that you must know the signature (syntax) of the function which you are going to override , ie exact number of parameters, their types and return type etc. If I can assume that you somehow can find out signature of all the functions in ftd2xx.dll, then it is merely simple to get it done.但是为此,您必须知道要覆盖的函数的签名(语法) ,即参数的确切数量、它们的类型和返回类型等。如果我可以假设您可以以某种方式找出所有函数的签名ftd2xx.dll,那么完成它就很简单了。

Get dll functions and Ordinal numbers: For this just use dumpbin.exe comes with Visual Studio (use it by running Visual Studio command prompt)获取 dll 函数和序数:为此只需使用 Visual Studio 附带的 dumpbin.exe(通过运行 Visual Studio 命令提示符使用它)

dumpbin.exe /exports {yourpath}\\ftd2xx.dll > ftd2xx.txt dumpbin.exe /exports {你的路径}\\ftd2xx.dll > ftd2xx.txt

Now your ftd2xx.txt has all the function names and ordinal numbers of the ftd2xx.dll.现在您的 ftd2xx.txt 包含 ftd2xx.dll 的所有函数名称和序号。 You can even use your dependency walker to export and get this list.您甚至可以使用您的依赖项walker 导出并获取此列表。

Create you own dll named ftd2xx.dll: Open Visual Studio, choose VC++ >> Win32 >> Win32 Project >> Dll (with Export symbols option) and finally use #pragma directive to declare all your exported original dll functions within your dll code like below,创建名为 ftd2xx.dll 的 dll:打开 Visual Studio,选择 VC++ >> Win32 >> Win32 Project >> Dll(带导出符号选项),最后使用 #pragma 指令在 dll 代码中声明所有导出的原始 dll 函数,例如以下,

//#pragma comment (linker, "/export:<function>=<origdll_name>.<function>,@<ordinal_number>")

#pragma comment (linker, "/export:FT_Open=ftd2xx_.FT_Open,@1")
#pragma comment (linker, "/export:FT_Close=ftd2xx_.FT_Close,@2")
// :
// :
// :
// delcare all your exported functions here with ordinal number
// :
// :
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
}

Now, you need to write your own function which can pretend as an original function of ftd2xx.dll which will get called when the application calls a original function of ftd2xx.dll.现在,您需要编写自己的函数,该函数可以伪装成 ftd2xx.dll 的原始函数,当应用程序调用 ftd2xx.dll 的原始函数时会调用该函数。 The below code is just to explain how it works.下面的代码只是为了解释它是如何工作的。 As I said earlier you need to know the exact signature of the dll functions which you want to override (redirect).正如我之前所说,您需要知道要覆盖(重定向)的 dll 函数的确切签名。 And also keep in mind that you need to call the original function after whatever you wanted to do, otherwise you may endup having unexpected behaviour with your application.还要记住,无论你想做什么,你都需要调用原始函数,否则你的应用程序最终可能会出现意外行为。

Assuming FT_Close() function takes no parameter and returns void, I am putting this just for example in which I override FT_Close() function of ftd2xx.dll with a proxy NewFT_Close() function.假设 FT_Close() 函数不接受参数并返回 void,我只是将其作为示例,其中我使用代理 NewFT_Close() 函数覆盖 ftd2xx.dll 的 FT_Close() 函数。 Note that, if you override a function, then remove it from #pragma directive and add it in a .def file (add a new ftd2xx.def file to your project and declare your new functions like below).请注意,如果您覆盖一个函数,则从 #pragma 指令中删除它并将其添加到 .def 文件中(将新的 ftd2xx.def 文件添加到您的项目并声明您的新函数,如下所示)。

DEF file example DEF 文件示例

LIBRARY ftd2xx.dll
EXPORTS
FT_Close = NewFT_Close @2

Dll code example dll代码示例

HINSTANCE   hInstance = NULL;        // handle to ftd2xx.dll
FARPROC     fpFTClose = {NULL};      // function pointer to hold original function address

extern "C" void __stdcall NewFT_Close()
{
    // This is our proxy function for FT_Close()
    // Do whatever you want to do here and the 
    // finally call the original FT_Close() using 
    // the function pointer we got from GetProcAddress()
    typedef void (__stdcall *PFTCLOSE)();
    PFTCLOSE pFc = (PFTCLOSE)fpFTClose;
    if(pFc) pFc();
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            // Load the original dll in to the memory and get the handle
            hInstance = LoadLibraryA("ftd2xx_.dll");
            if(!hInstance) return FALSE;
            // Get the address of the function to be overriden
            fpFTClose = GetProcAddress(hInstance,"FT_Close");
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            // Our dll is getting unloaded from the application, unload original as well
            FreeLibrary(hInstance);
            break;
    }
    return TRUE;
}

Note that the original dll is referred as ftd2xx_.dll in LoadLibraryA() call.请注意,原始 dll 在 LoadLibraryA() 调用中称为 ftd2xx_.dll。 So, rename the original dll to ftd2xx_.dll or name it whatever you want.因此,将原始 dll 重命名为 ftd2xx_.dll 或随意命名。 Build your proxy dll code and take your proxy dll (ftd2xx.dll) to the path where the original ftd2xx.dll present.构建您的代理 dll 代码并将您的代理 dll (ftd2xx.dll) 带到原始 ftd2xx.dll 所在的路径。 Now, your application will call ftd2xx.dll (proxy) as usual, but ftd2xx.dll will call the original dll ftd2xx_.dll internally.现在,您的应用程序将像往常一样调用 ftd2xx.dll(代理),但 ftd2xx.dll 将在内部调用原始 dll ftd2xx_.dll。

Update #1: I kept mentioning that you need to know the signature of the functions your are trying to override, and by luck I just found the ftd2xx.h file in the linux version of the driver.更新 #1:我一直提到你需要知道你试图覆盖的函数的签名,幸运的是我刚刚在 linux 版本的驱动程序中找到了 ftd2xx.h 文件。

Linux version of ftd2xx ftd2xx 的 Linux 版本

Download the libftd2xx-i386-1.3.6.tgz file from above link and extract it to a folder (I used 7zip), further extract the .tar file to get the release folder and you'll find ftd2xx.h file within the "release" folder.从上面的链接下载 libftd2xx-i386-1.3.6.tgz 文件并将其解压缩到一个文件夹(我使用 7zip),进一步解压缩 .tar 文件以获取发布文件夹,您将在“释放”文件夹。 There you go, now you got complete function signatures of the dll and you know how to write a proxy dll.好了,现在您获得了 dll 的完整函数签名,并且您知道如何编写代理 dll。 Good Luck.祝你好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM