如果我有符号,如何在 DLL 中找到参数签名并调用未导出的方法?
Posted
技术标签:
【中文标题】如果我有符号,如何在 DLL 中找到参数签名并调用未导出的方法?【英文标题】:How do I find the argument signature for and call an unexported method in a DLL if I have the symbol for it? 【发布时间】:2012-08-31 18:38:44 【问题描述】:这是一个内置于 Windows 中的 dll,odbc32.dll。该函数称为LoadTraceDll()
Visual Studio 2008 中的堆栈帧是:
odbc32.dll!LoadTraceDll() + 0x42f 字节
我使用了 PE 分析器,但在 odbc32.dll 的导出列表中没有看到它。
我的问题如下:
如何确定参数类型和返回类型(方法签名)? 我怎么称呼它?我可以避免调用它的相对地址吗?完整的堆栈跟踪如下:
ODBCTracer.dll!TraceVersion() Line 2259 C++
odbc32.dll!LoadTraceDll() + 0x42f bytes
odbc32.dll!FInitTrace() + 0xf3 bytes
odbc32.dll!DllMain() + 0x14692 bytes
odbc32.dll!_CRT_INIT() - 0x3e3 bytes
ntdll.dll!LdrpRunInitializeRoutines() + 0x1e8 bytes
ntdll.dll!LdrpLoadDll() - 0x336 bytes
ntdll.dll!LdrLoadDll() + 0x9e bytes
KernelBase.dll!LoadLibraryExW() + 0x13f bytes
odbccp32.dll!LoadDM() + 0x2a bytes
odbccp32.dll!TracingPageProc() + 0xc46 bytes
user32.dll!UserCallDlgProcCheckWow() - 0x180d bytes
user32.dll!DefDlgProcWorker() + 0xba bytes
user32.dll!DefDlgProcW() + 0x36 bytes
user32.dll!UserCallWinProcCheckWow() + 0x11d bytes
user32.dll!InternalCreateDialog() - 0xc7 bytes
user32.dll!CreateDialogIndirectParamAorW() + 0x5b bytes
user32.dll!CreateDialogIndirectParamW() + 0x18 bytes
comctl32.dll!_CreatePageDialog() + 0xb1 bytes
comctl32.dll!_CreatePage() + 0x161 bytes
comctl32.dll!PageChange() + 0xca bytes
comctl32.dll!PropSheetDlgProc() + 0x36e bytes
user32.dll!UserCallDlgProcCheckWow() + 0x11b bytes
user32.dll!DefDlgProcWorker() + 0xba bytes
user32.dll!DefDlgProcW() + 0x36 bytes
user32.dll!UserCallWinProcCheckWow() + 0x11d bytes
user32.dll!SendMessageWorker() + 0x158 bytes
user32.dll!SendMessageW() + 0x5d bytes
comctl32.dll!CCSendNotify() + 0xfbd bytes
comctl32.dll!SendNotifyEx() + 0x80 bytes
comctl32.dll!ChangeSel() + 0x2dc bytes
comctl32.dll!Tab_OnLButtonDown() + 0xfc bytes
comctl32.dll!Tab_WndProc() + 0x56d bytes
user32.dll!UserCallWinProcCheckWow() + 0x11d bytes
user32.dll!DispatchMessageWorker() + 0x12a bytes
user32.dll!IsDialogMessageW() + 0x102 bytes
comctl32.dll!Prop_IsDialogMessage() + 0x1f0 bytes
comctl32.dll!_RealPropertySheet() + 0x31b bytes
comctl32.dll!_PropertySheet() + 0x55 bytes
odbccp32.dll!MainSheet() + 0x18c bytes
odbccp32.dll!SQLManageDataSources() + 0x4b bytes
odbcad32.exe!WinMain() + 0x25b bytes
odbcad32.exe!ODBC___GetSetupProc() + 0x4ae bytes
kernel32.dll!BaseThreadInitThunk() + 0xd bytes
ntdll.dll!RtlUserThreadStart() + 0x21 bytes
【问题讨论】:
【参考方案1】:如何确定参数类型和返回类型(方法签名)?
你不能。
(嗯,你可以,有一定的信心,但它需要强大的逆向工程技能。你必须反汇编库,找到函数的定义和调用方式,以及典型的操作序列和参数/变量大小,你可以推断出参数的类型和返回值可以是什么)
我怎么称呼它?我可以避免调用它的相对地址吗?
您可以dlopen()
...呃...LoadLibrary()
DLL 然后使用GetProcAddres()
获取其地址,将其存储在函数指针中,然后调用它:
HMODULE hndl = LoadLibrary("My.DLL");
void (*func)() = GetProcAddress(hndl, "MyFunction");
func();
【讨论】:
这就是我所害怕的。 @JustinDearing 如果您想要方法签名,请切换到 Objective-C 并将类转储库进行逆向工程:P【参考方案2】:如果您有图像的符号(PDB 文件),您可以检索未导出的符号及其签名,前提是这些符号是公开的(按照 PDB 公开与私有的说法)。使用DIA,您可以将符号与关联的图像文件匹配。有关 PDB 符号和图像之间的映射如何工作的示例,请参阅 here。
【讨论】:
看起来很有希望,让我们看看这个兔子洞有多深。以上是关于如果我有符号,如何在 DLL 中找到参数签名并调用未导出的方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何检查检查PInvoke签名的调用约定和参数与非托管的目标签名是不是匹配?