我刚开始尝试反转Windows二进制文件,但偶然发现了Import Address Table。当反转一个特定的DLL时,我遇到了许多thunk函数,这些函数全部都引用了IAT。
根据我在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是否必须独立于位置?我阅读了有关首选二进制基址和整个二进制文件(如果无法匹配)的条件重定位的信息。这仍然正确吗?
我仍然看不到为什么需要我遇到的第二层跳转表。




评论

二进制文件在任何地方都可以使用吗?是x86还是x64代码?

它不是公开可用的。是x64。我尝试重新创建类似的模式,但失败了。显然,这是某种C ++ /。NET的东西,尽管我不确定如何创建它。 DLL实现的GUI绝对是C#/。NET,尽管它似乎也包含一些“常规” C ++代码。我刚刚发现,使用dotPeek
可以完全反编译C#部分。
哦,是C ++ / CLI解释了一些问题。我会调查和更新

#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