当我们使用import时,我们需要准确地指示模块名和函数名。我们不能使用复杂的算法。也适用于
执行
GetModuleHandle
我们可以用
NULL
用于获取用于创建调用进程的文件的句柄(.exe文件)。但万一
LoadLibraryExW
不能使用0或空字符串(
L""
执行
. 当加载程序加载我们的模块时,他从
IMAGE_IMPORT_DESCRIPTOR
并尝试先通过低级别、私有、核心找到或加载具有此名称的模块
加载库EXW
. 这里需要确切的名字。或负载故障。因此,如果我们在构建时不知道exe名称,请使用导入-这里不是解决方案
可能的变量-在运行时自己解析函数指针。在这里我们可以得到exe
HMODULE
GetModuleHandle(0)
. 如果需要的话我们不仅可以在搜索功能
执行
但在别的地方。可以实现任何搜索算法。
void WINAPI fn(int i);
我们可以声明指向这个函数的指针并在运行时解析它
void (WINAPI *fn)(int);
*(void**)&fn = GetProcAddress(GetModuleHandleW(0), "fn");
说上
DLL_PROCESS_ATTACH
一个稍微不同的解决方案(尽管在二进制级别上它是完全等效的)声明函数
__declspec(dllimport)
属性。这是给你的
CL.EXE
(更被称为
MSVC公司
)仅编译器。所以
__declspec(dllimport) void fn(int i);
在这种情况下
氯
__FUNCDNAME__
姓名。所以事实上和第一个变量一样,当我们自己声明指针时。只是语法和。。符号名称。它看起来像
__imp_?fn2@@YAXH@Z
不是的有效名称
信用证++
-我们不能直接给它赋值
. 即使我们用
extern "C"
@
符号(非法用于
)为了
__stdcall
和
__fastcall
功能,用于
. 不同平台的名称也不同(
x86个
,
等)。对于访问这些名称-需要或使用外部
asm公司
文件(用于asm)
?
和
符号(名称有效)或使用
/alternatename
链接器选项-用于为此类名称和访问符号设置别名。说喜欢
__pragma(comment(linker, "/alternatename:__imp_?fn@@YAXH@Z=__imp_fn"))
初始化通过
*(void**)&__imp_fn = GetProcAddress(GetModuleHandle(0), "fn");
另一种选择使用
__declspec(dllimport)
__imp___FUNCDNAME__
(如
__进口?fn2@@YAXH@Z
)已定义(即使我们没有这样的库,我们也可以自己轻松地创建它(所有需要的都是空实现的正确函数声明)。在我们将这样的import lib添加到链接器input-add之后
/DELAYLOAD:dllname
dllname
-导入库中的确切名称。感觉到这个
执行
fn
). 对于我们需要的负载
implement
extern "C" FARPROC WINAPI __delayLoadHelper2(
PCImgDelayDescr pidd,
FARPROC * ppfnIATEntry
);
delayimp.lib
delayimp.lib
delayLoadHelper2
并付诸实施。但是,我们必须自定义这个过程(默认实现(look in
/include/DelayHlp.cpp
LoadLibraryExA
具有
__pfnDliNotifyHook2
:
例如:
FARPROC WINAPI MyDliHook(
unsigned dliNotify,
PDelayLoadInfo pdli
)
{
switch (dliNotify)
{
case dliNotePreLoadLibrary:
if (!strcmp(pdli->szDll, "unique_exe_alias"))
{
return (FARPROC)GetModuleHandle(0);
}
}
return 0;
}
const PfnDliHook __pfnDliNotifyHook2 = MyDliHook;
dliNotePreLoadLibrary
通知,而不是默认值
LoadLibraryEx(dli.szDll, NULL, 0);
使用
GetModuleHandle(0);
执行
.
执行
名称,未知,但exe的唯一标记(别名)