通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE(转)

在有些情况下需要得到函数调用者的模块名字。比如你想限制你的某个函数只能被自己某个特定的DLL调用。 或者比如在异常处理中你想了解是那个DLL/EXE抛出了异常。

API函数_ReturnAddress 和GetModuleHandleEx 函数可以帮助我们达到这个目的。以下代码演示它们的用法:

  1. void  ShowCallerModuleName()
  2. {
  3. HMODULE  hCallerModule = NULL;
  4. TCHAR  szModuleName[MAX_PATH] = _T( "" );
  5. void  *callerAddress = _ReturnAddress();
  6. if  (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, ( LPCTSTR)callerAddress, &hCallerModule))
  7. {
  8. GetModuleFileName(hCallerModule, szModuleName, ARRAYSIZE(szModuleName));
  9. MessageBox(NULL, szModuleName, _T("Who is calling me?" ), MB_OK);
  10. }
  11. }

解释:

_ReturnAddress 可以给你所在函数的返回地址,也就是调用者的地址。

GetModuleHandleEx 可以给你某个地址所在的模块Handle 。 得到这个Handle 之后,就可以用GetModuleFileName 来得到模块的文件名了。

///////////////////////////////////////////////////////////////////////////////

扩展:

用在dll劫持的时候,在判断呼叫本DLL的主程序模块中,获取返回地址,可以在naked函数中用汇编获取返回地址

以下是我测试的代码,程序运行正确!11(可以在函数里面判断返回地址,这样可以对抗DLL劫持)

void __declspec(naked) test()
{

__asm pop returnaddress
char aa21[1024];
sprintf(aa21,"%08X",returnaddress);
MessageBox(NULL,aa21,NULL,NULL);
__asm jmp returnaddress

}

时间: 2024-10-13 18:28:01

通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE(转)的相关文章

【转】匹配dll(exe)和pdb方法

1. 静态检查windbg 调试工具包中有一个工具symchk.exe, 选项很多, 下面一个简单的用法可以检查一个 test.exe能不能找到与它匹配的PDB: 这是成功的情形. 下面来个失败的作为对比: 2. 如果已经在windbg内部, 可以通过下面的命令检查 最后一行说 MATCH, 肯定没问题. 3. 在windbg中(在VS中不行), 如果你100%确信源代码没有任何改动, 只不过被重新编译了一下.可以通过 .symopt +40 来关闭对GUID的强行检查. 从而load一个不匹配

c#:Reflector+Reflexil 修改编译后的dll/exe文件

原文:c#:Reflector+Reflexil 修改编译后的dll/exe文件 不知道大家有没有这样的经历:现场实施时测试出一个bug,明明知道某个dll/exe文件只要修改一二行代码即可,但手头没有开发环境,紧急情况下,可以用reflector + reflexil 临时直接修改dll代码,然后重编译,替换原来的文件(当然:代码未混淆的情况下,这个也可以用来搞破解,这不在本文讨论之列) 步骤: 1.Relector 加载相关的dll后,启用Reflexil界面 2.找到需要修改的代码位置,然

DLL/EXE查看工具Dumpbin

一般情况下,我们需要查看一个DLL或EXE中的包含的函数或是依赖的函数之类的信息,可以使用VS自带的工具dumpbin: 可以直接在命令行下输入dumpbin就可以查看他的使用说明,如果未显示,可以先运行VS安装目录下的vcvarsall.bat来设置一下环境变量就可以了. [cpp] view plaincopy Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp. C:/Documents and Sett

WinDBG 技巧:列出模块(DLL/EXE)里面所有的符号(symbol)

想对某个函数下断点,但是记不清楚的函数具体的名字,这个时侯可以使用x命令来列举所有的符号. 命令格式为: x [选项] 模块名字!符号匹配表达式 这里的符号匹配表达式类似dos的文件名匹配表达式,可以用*号和?号做通配符.比如我想列出user32.dll里面所有的以GetWindowT开头的符号,使用命令 0:016>  x user32!GetWindowT*75f50f7b USER32!GetWindowTextA (struct HWND__ *, char *, int)75f4adc

VC++获取当前模块的路径(dll/exe)

一般地,获取当前模块路径都是通过调用 GetModuleFileName() 来获取的. DWORD WINAPI GetModuleFileName( __in HMODULE hModule, __out LPTSTR lpFilename, __in DWORD nSize ); 参数 hModule A handle to the loaded module whose path is being requested. If this parameter is NULL, GetModu

c++ 中的函数查找

template <class T> class visibility { public: void say(double d){}; private: void say(int i){}; void say(T t){}; }; int _tmain(int argc, _TCHAR* argv[]) { visibility<char*> v; v.say(123); // error C2248: 'visibility<T>::say' : cannot acc

python之追溯函数调用及日志详细打印

目录 [TOC] 一.函数调用追溯 1.1 原因 在打印日志时,为实现日志分层打印,将打印日志的语句封装到了print_log_info以及print_log_error中.但是如果在上述函数中直接通过logger.*打印日志,日志中的模块名.行号就会一直打印print_log_info和print_log_error函数中的logger.*中的位置.所以有了追溯函数调用的想法,在打印正常日志时,打印对应模块名以及打印日志语句的行号. 1.2 使用实例 2.2.1 追溯函数调用推导 在一个模块中

DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码: 下面的是dll模块的的, dll的工程文件: [delphi] view plaincopy library DllAPP; uses windows, SysUtils, Classes, DllClass in 'DllClass.pas'; {$R *.res} var GDllServer: TDllServer; functio

在C++中调用DLL中的函数 (3)

1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等,它们都以源代码的形式发布.由于这种复用是“源码级别”的,源代码完全暴露给了程序员,因而称之为“白盒复用”.“白盒复用”的缺点比较多,总结起来有4点. 暴露了源代码:多份拷贝,造成存储浪费: 容易与程序员的“普通”代码发生命名冲突: 更新功能模块比较困难,不利于问题的模块化实现: 实际上,以上4点概