C++ C/C++—;使用_ufuncsig__;宏获取函数签名?

C++ C/C++—;使用_ufuncsig__;宏获取函数签名?,c++,visual-c++,hook,C++,Visual C++,Hook,我试图找到从DLL导出的函数的签名,并为挂钩定义完全相同的回调函数 这是当前项目的需要,我正在工作 下面是我为查找函数位置所做的工作 HMODULE hModd = LoadLibraryEx("xxx.dll",NULL,DONT_RESOLVE_DLL_REFERENCES); dosHeader = ((PIMAGE_DOS_HEADER)hModd); /*if(((PIMAGE_DOS_HEADER)hModd)->e_magic == IMAGE_DOS_SIGNAT

我试图找到从DLL导出的函数的签名,并为挂钩定义完全相同的回调函数

这是当前项目的需要,我正在工作

下面是我为查找函数位置所做的工作

HMODULE hModd = LoadLibraryEx("xxx.dll",NULL,DONT_RESOLVE_DLL_REFERENCES);

dosHeader = ((PIMAGE_DOS_HEADER)hModd);
    /*if(((PIMAGE_DOS_HEADER)hModd)->e_magic == IMAGE_DOS_SIGNATURE)
        MessageBoxA(NULL,"wow","exe",MB_OK);/**/
    ntHeader = (PIMAGE_NT_HEADERS)((PBYTE)hModd + ((PIMAGE_DOS_HEADER)hModd)->e_lfanew);
    PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE *)hModd + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    PVOID names = (BYTE *)hModd + exports->AddressOfNames;
    WORD *pOrds = (WORD*)((BYTE*)hModd + exports->AddressOfNameOrdinals);
    DWORD* addr = (DWORD*)((BYTE*)hModd + exports->AddressOfFunctions); 
    for (int i = 0; i < exports->NumberOfNames; ++i,addr++)
        {
            char funcName[255];
            char const *target = "Test";
            ZeroMemory(funcName,sizeof(funcName));
            //strcpy(funcName,(char*)((BYTE *)hModd + ((DWORD *)names)[i]));
            if(strcmp((char*)((BYTE *)hModd + ((DWORD *)names)[i]),target))
            {
                printf("Export: %s Address: %X \n", (char*)((BYTE *)hModd + ((DWORD *)names)[i]),*addr);
                offsetTarget = *addr;
            }
        }
HMODULE hModd=LoadLibraryEx(“xxx.dll”,NULL,不解析dll\u引用);
dosHeader=((PIMAGE_DOS_HEADER)hModd);
/*if((PIMAGE\u DOS\u HEADER)hModd)->e\u magic==IMAGE\u DOS\u签名)
MessageBoxA(空,“哇”,“exe”,MB_OK)/**/
n头=(PIMAGE\u NT\u头)((PBYTE)hModd+((PIMAGE\u DOS\u头)hModd)->e\u lfanew);
PIMAGE\u EXPORT\u DIRECTORY EXPORT=(PIMAGE\u EXPORT\u DIRECTORY)((字节*)hModd+nheader->OptionalHeader.DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u EXPORT].VirtualAddress);
PVOID名称=(字节*)hModd+导出->地址名称;
WORD*pOrds=(WORD*)((BYTE*)hModd+exports->AddressOfNameOrdinals);
DWORD*addr=(DWORD*)((字节*)hModd+导出->AddressOffFunction);
对于(inti=0;iNumberOfNames;++i,addr++)
{
字符名称[255];
char const*target=“测试”;
零内存(funcName,sizeof(funcName));
//strcpy(funcName,(char*)((BYTE*)hModd+((DWORD*)名称)[i]);
if(strcmp((char*)((BYTE*)hModd+((DWORD*)名称)[i]),目标))
{
printf(“导出:%s地址:%X\n”,(字符*)((字节*)hModd+((DWORD*)名称)[i]),*addr);
offsetTarget=*地址;
}
}
如何使用
\uuu funcsig\uuu
宏获取DLL函数签名


\uuuuu funcsig\uuuuu
通常会返回包含它的函数的签名。

您不能为此使用
\uuuuuuu funcsig\uuuu
:正如您所说,它会生成包含函数的签名


无法获取由任意模块导出的任意函数的签名。这些信息根本不存在:您需要某种形式的附加元数据来描述函数的类型。

这取决于具体情况。需要做什么“工作”?如果您可以确定目标函数的调用约定,那么您可以确定参数的位置以及哪些寄存器对调用“重要”。如果没有DLL的头文件或源代码,则需要使用disasassembler(IDA Pro的免费版本应该可以)要研究函数并找出参数和返回值。@divideandconquer.se:不允许使用dis汇编程序。。。仅代码。无法可靠地自动检测任何DLL中任何方法的输入和输出。请注意,导出是按字典顺序排列的,这意味着您可以使用二进制搜索来查找具有特定名称的导出。不需要线性搜索。