根据我在Linux上的经验,我猜想这有点类似于过程链接表(或者我想是全局偏移表)。
基于此,我认为链接过程是相似的,尽管我似乎找不到详细的信息。任何帮助将不胜感激。
此外,我想知道您是否可以在不运行二进制文件的情况下解决这些问题。特别是因为实际上我正在分析信息以解决这些问题的DLL应该已经可用?
尽管我无法从可用信息中真正理解。完全关闭,这是我正在谈论的示例:
void THUNK_FUN_18002d97a(void)
{
(*_DAT_18005ba68)();
return;
}
地址处的内存(在
.data
部分中):0x18005ba68: 94 00 00 06 00 00 00 00
编辑:
感谢输入。我现在感觉好像误解了IAT的目的。因此,请考虑以下情形:
我们有一个PE可执行文件A,它从DLL B导入符号。在导出目录表中找到。是吗?
在DLL(B)中,我正在调查提到的代码块既不是导入符号也不是导出符号。那么我可能会看到什么?
整个过程必须看起来像这样:
A已执行。搜索并链接所有需要的DLL(在这种情况下这称为绑定?)
这导致B实际加载到某个地址。现在可以解析A中B中的符号(使用导入目录表)。 B是否必须独立于位置?我阅读了有关首选二进制基址和整个二进制文件(如果无法匹配)的条件重定位的信息。这仍然正确吗?
我仍然看不到为什么需要我遇到的第二层跳转表。
#1 楼
第1部分PE导入模块的工作方式与ELF PLT不同。在第一个调用上没有调用动态解析器,但是所有导入指针都在进程启动时提前解析(类似于
LD_BIND_NOW
)。指针被分组在类似GOT的导入地址表(IAT)中,并且带有有关DLL和符号导入的详细信息的元数据存储在由PE标头引用的导入目录中。要恢复符号您需要解析导入目录。有关详细信息,请参见正式的PE格式规范。
PART2
编辑后,似乎您正在处理的是本机代码到托管代码库。生成混合可执行文件:
m.cpp
(托管代码):using namespace System;
void hello()
{
String^ str = "Hello World";
Console::WriteLine(str);
}
n.cpp
(本地代码):void hello();
void main()
{
hello();
}
编译和链接:
cl /c /clr /Zi m.cpp
cl /c /Zi n.cpp
link /debug /out:mixed.exe m.obj n.obj
拆解本机零件(并感谢PDB获得符号)后,我可以观察到以下内容:
.text:00007FF798E81090 main proc near
.text:00007FF798E81090 sub rsp, 28h
.text:00007FF798E81094 call ?hello@@YAXXZ ; hello(void)
.text:00007FF798E81099 xor eax, eax
.text:00007FF798E8109B add rsp, 28h
.text:00007FF798E8109F retn
.text:00007FF798E8109F main endp
进行呼叫之后:
jmp
:.nep:00007FF798ECC000 ?hello@@YAXXZ proc near
.nep:00007FF798ECC000 jmp short loc_7FF798ECC00A
.nep:00007FF798ECC002 ud2
.nep:00007FF798ECC004 jmp cs:__m2mep@?hello@@$$FYAXXZ
.nep:00007FF798ECC00A loc_7FF798ECC00A:
.nep:00007FF798ECC00A jmp cs:__mep@?hello@@$$FYAXXZ
.nep:00007FF798ECC00A ?hello@@YAXXZ endp
值6000001是CLR令牌。高字节字节是令牌种类或元数据表索引,在这种情况下,0x6表示方法。在诸如ILDASM或dnSpy的.NET查看器中查找它,我们可以看到它使用RVA
000010a0
引用托管方法“ hello”。转到该地址,我们将看到:.data:00007FF798EE7000 __m2mep@?hello@@$$FYAXXZ dq 6000001h
.data:00007FF798EE7008 __mep@?hello@@$$FYAXXZ dq 6000001h
作为x64代码没有任何意义,因此这显然是CLI字节码,应使用.net反编译器进行检查。奇怪的是,我尝试过的所有功能似乎都没有显示该功能,但是我设法从ILDASM中获得了IL分解:
IL反汇编以找出托管代码中跳转的目的地。
随机观察:
段
.nep
似乎表示“本机入口点” 令牌名称中的前缀
__mep
可能表示“托管入口点”。评论
谢谢,尽管我现在有些困惑。看一下我的编辑
–milck
12月17日20:12
@milck参见第2部分
–伊戈尔·斯科钦斯基♦
12月19日的1:02
评论
二进制文件在任何地方都可以使用吗?是x86还是x64代码?它不是公开可用的。是x64。我尝试重新创建类似的模式,但失败了。显然,这是某种C ++ /。NET的东西,尽管我不确定如何创建它。 DLL实现的GUI绝对是C#/。NET,尽管它似乎也包含一些“常规” C ++代码。我刚刚发现,使用dotPeek
可以完全反编译C#部分。
哦,是C ++ / CLI解释了一些问题。我会调查和更新