C# GetProcAddress中的常量句柄(新的IntPtr(0xac8),“SomeFoo”),它是如何实现的?

C# GetProcAddress中的常量句柄(新的IntPtr(0xac8),“SomeFoo”),它是如何实现的?,c#,winapi,C#,Winapi,当反转程序时,代码c: IntPtr address = GetProcAddress(new IntPtr(0xac8), "SomeFoo"); 如果我理解正确的话,这个句柄通常来自 HMODULE WINAPI LoadLibrary(_In_ LPCTSTR lpFileName); 或者,例如,从 HMODULE WINAPI GetModuleHandle(_In_opt_ LPCTSTR lpModuleName); 这个句柄是动态的,不会两次指向同一个地址 问题是:在

当反转程序时,代码c:

 IntPtr address = GetProcAddress(new IntPtr(0xac8), "SomeFoo");
如果我理解正确的话,这个句柄通常来自

HMODULE WINAPI LoadLibrary(_In_  LPCTSTR lpFileName);
或者,例如,从

HMODULE WINAPI GetModuleHandle(_In_opt_  LPCTSTR lpModuleName);
这个句柄是动态的,不会两次指向同一个地址

问题是:在什么情况下可以使用硬编码句柄

UPD:这是不可能的,这个把戏是可行的,在通常的方式。看起来这个调用被内核驱动程序钩住了,这个地址0xac8只是这个驱动程序识别我的程序调用的一个键

问题是:在什么情况下可以使用硬编码句柄

首先,假设正常使用,没有我能想到的情况。当然,没有一个模块句柄可以有值0xac8,因为模块句柄是一个地址。并且该地址是系统保留的区域的一部分,并且对于访问该地址的内存总是无效的

所以,如果是这样的话,那么我相信你对这个调用进行了错误的反向工程

另一方面,也许你的反向工程是正确的。在这种情况下,我们不是在谈论正常使用。因此,当传递这样一个模块句柄时,该进程可能钩住了LoadLibrary以执行一些特殊行为。但在这一点上,我们只能猜测


顺便说一句,你也说过,这个句柄是动态的,永远不会指向同一个地址两次。嗯,完全有可能在同一地址重复加载模块。模块具有首选加载地址,如果可能的话,系统会尝试通过在每个加载模块的进程中以相同的地址加载模块来降低物理内存成本。但是,您不能在编译时假设将使用什么地址。

好吧,我唯一能100%确定的是我已经正确地回响了这个调用。idc.i4 2760 newobj System.void System.IntPtr::.ctorSystem.Int32 ldstr SomeFoo call System.IntPtr…GetProcAddressSystem.IntPtr,System.string但是,您不能在编译时假定将使用什么地址。但就是这样,我想知道这是怎么回事?可以在指定的地址上加载库吗?好的,如果可以,那么您可以用IntPtr address=IntPtr.Zero;!!!这是为了什么?我要叫这个福,不是为了逃避,这是个小玩笑。您的代码总是返回IntPtr.Zero。这里从来没有一个模块。我可能想到的唯一原因是,它们假定系统库(例如内核32)有一个固定地址。这是真的,但在地址空间随机化之前非常脆弱。现在它只是错了。它可能是在首选地址加载的专有DLL,但它不可移植,而且非常脆弱,毕竟基址只是一个提示,而不是一个规则。保护与许可证相关的东西是一个相当幼稚的代码,还是仅仅是一个狂欢之夜的结果?@Adriano该地址在第一页。那里从来没有模块。这里什么都没有。当然这也是为了保护,看起来这个库加载了父进程,并且这个代码在父进程地址空间中执行。我只是想了解它是如何工作的,而且它确实是工作的。@user“父进程”这个术语没有真正的意义。实际上只有执行代码的进程,然后是外部进程。GetProcAddress接受仅在此过程中有意义的模块句柄。@DavidHeffernan,除非-BASE用于链接器,但……我甚至不知道是否可以要求将image BASE放在第一页。