ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

逆向核心基础:ELF与PE文件格式结构解析与地址换算实战

逆向核心基础:ELF与PE文件格式结构解析与地址换算实战 搞逆向的几乎天天跟两种文件格式打交道ELF和PE。ELF是Unix/Linux、Android生态里的标准可执行文件格式PE是Windows生态里的标准可执行文件格式。逆向工程里大部分样本分析、病毒查杀、漏洞研究、游戏修改本质上都是从“认出这个文件是什么格式”开始的。这篇文章我把ELF和PE这两套结构从里到外拆一遍包括头部字段、节区、段、重定位、导入导出、地址换算、加壳识别这些核心知识点结合我做分析时的日常思路帮你把这根线彻底理顺。不管你是刚开始学逆向还是已经被IDA、Ghidra里的地址搞晕过这篇应该都能给你补上关键的那一块拼图。1. 先把这个道理想明白ELF和PE到底是什么为什么逆向必学1.1 两者的“出身”与生态位ELFExecutable and Linkable Format是System V制定的可执行文件格式标准1995年左右定稿Linux内核一出生就把ELF作为主力格式后来FreeBSD、Android、大量IoT固件也都用ELF。你在Linux下随手编译出来的a.out、Ubuntu里的深度学习框架、安卓App里的native库格式内核全是ELF。它设计的初衷是既要方便编译器、链接器做静态处理又要让操作系统加载器能高效地把程序映射进内存所以格外强调“Section”和“Segment”两种视角并存。PEPortable Executable的源头是Windows NT团队他们从UNIX的COFF格式改造而来所以今天你在PE里的节表、符号、调试信息上还能看到COFF的影子。PE的扩展名覆盖了.exe、.dll、.sys、.ocx、.scr等等只要在Windows下运行的二进制基本全是PE。很多恶意样本、外挂注入的DLL、驱动级Rootkit也都是PE格式。为什么逆向必学这两种格式因为你在IDA或者Ghidra里看到的一切都不是凭空出现的函数地址来自文件头里的入口点、节区基址导入表决定反汇编时哪些调用会被识别成APIASLR、PIE、重定位表决定你动态调试时的断点应该下在哪一个地址上。文件格式是“地基”地基没打牢后面全是空中楼阁。1.2 “PE”这个词的三个含义别搞混在逆向工程语境里PE是Portable Executable指文件格式。但网上搜“PE”很容易搜到“微PE工具箱”“PE启动盘”“U盘装系统”这些内容那个PE是Windows Preinstallation Environment预安装环境两者除了缩写相同没有任何关系。运营商设备里的“PE”又指Provider Edge这是网络设备的边缘节点概念跟文件格式更是八竿子打不着。这也算逆向初学者最常见的检索障碍想搜PE文件格式解析结果前面几页全是启动盘制作教程。我的经验是搜索时直接带“Portable Executable”“PE格式”“PE结构”这类限定词或者搜“CFF Explorer”“PE-bear”这些工具名出来的结果会更干净。理解了这个歧义后面看到“微PE重装系统点Windows安装器还是点CGI备份还原”这类问题就知道那是另一个完全不同的技术方向了。1.3 这两种文件格式对逆向工作意味着什么先盘一下实际工作中面对的样本分布Windows平台的恶意软件90%以上是PELinux平台的挖矿木马、僵尸网络脚本落地的二进制基本都是ELF安卓App里要逆向的核心逻辑往往集中在lib目录下的.so文件也就是ARM/ARM64架构的ELF。做固件分析的时候很多引导程序、modem固件、路由器固件里的可执行文件也是ELF。换句话说两种格式你都得会看偏科会很难受。更重要的是理解了这两种格式你才能明白为什么同一段代码在不同平台表现完全不同。比如Windows可执行文件的地址基准是“ImageBase RVA”而ELF的地址既可以用虚拟地址VMA表达在链接阶段又可以用Section Offset来表达Windows里导入API靠PE导入表Linux里导入外部函数靠动态符号表加PLT/GOT。这些差异都不只是理论题而是每次调试时你眼里看到的地址对不对得上、要不要加基址之类的实际问题。2. ELF文件结构、Section与Segment、地址计算一网打尽2.1 ELF文件头从魔数到入口点ELF文件头是所有解析的起点固定长度32位ELF是52字节64位ELF是64字节。文件最开头是魔数0x7F 45 4C 46十六进制写出来就是7F 45 4C 46ASCII对应“.”“E”“L”“F”。这个魔数不能改改了加载器直接不认。紧跟着是几个关键字节EI_CLASS表示位数132位264位EI_DATA表示字节序1小端2大端EI_OSABI表示操作系统ABI0System V3Linux等。核心字段里e_type表示文件类型1是ET_REL可重定位文件也就是.o目标文件2是ET_EXEC可执行文件3是ET_DYN共享对象或PIE可执行文件4是ET_CORE核心转储。e_machine表示目标架构常见的有0x03x86、0x3Ex86-64、0x28ARM、0xB7AArch64。e_entry是程序入口点的虚拟地址它对逆向分析至关重要IDA和Ghidra加载后默认都会定位到这里。想看这些信息Linux下最直接的工具是readelfreadelf -h ./sample输出里会清楚列出Class、Type、Machine、Entry point address这些字段。很多刚入门的朋友喜欢一上来就反汇编我建议先养成看文件头的习惯几秒钟就能确认自己面对的是一个什么架构、什么类型的文件后面所有分析决策都依赖这个基础。2.2 链接视角的Section与加载视角的SegmentELF最容易被忽视、也最需要理解清楚的一点是它同时用“节”Section和“段”Segment描述同一个文件。节是链接器视角编译、链接时按节来组织代码和数据段是加载器视角运行时按段把文件映射进内存。使用readelf -S查看节表使用readelf -l查看程序头段表。常见节包括.text代码、.rodata只读数据、.data已初始化全局变量、.bss未初始化全局变量文件里不占空间但内存里占用、.plt和.got动态链接用的跳转桩和全局偏移表、.dynsym和.dynstr动态符号表及其字符串表、.symtab和.strtab全量符号表及其字符串表、.dynamic动态链接信息。程序头里最重要的段类型是PT_LOAD它描述哪个范围的字节应该被读入内存、映射在哪个虚拟地址、内存中映射多大。注意一个关键区别p_filesz是文件里占用的字节数p_memsz是内存中占用的字节数。对于.bss节它在文件里几乎没有东西但映射到内存后大小可观所以p_memsz会比p_filesz大加载器会把多出来的部分清零。逆向时如果遇到一个变量看起来在文件里找不到先想想它是不是落在.bss里。链接视角和加载视角不一致是新手经常想不通的问题。我打个比方Section像是书稿的章节划分编辑链接器按章节来组织内容Segment像是实际印刷和发行的装订方式读者操作系统只需按照装订线翻阅。同一本书可以有章节结构也可以有物理上的装订结构两者都合理只是服务的目标不同。2.3 动态链接的PLT/GOT与重定位在Linux和Android上外部函数调用并不是像Windows那样直接查一个导入表列表就行而是通过PLT和GOT协作完成。PLT是过程链接表GOT是全局偏移表。调用一个外部函数比如libc里的printf时流程是这样的代码先跳到PLT桩PLT桩再跳到GOT里保存的实际函数地址。第一次调用时GOT里还没有真实地址PLT会把控制权交给动态链接器解析链接器计算好真实地址后写回GOT后续调用直接跳转。这个机制对逆向的影响非常大。你在IDA里看到的对导出函数的调用往往是call一个PLT地址真正的函数代码在libc那边你单步跟进去可能就进了动态链接器的解析流程。而且GOT在运行时是会被改写的这就牵扯出RELRO技术Partial RELRO下.got.plt依然可写Full RELRO会把整个GOT映射成只读。很多Hook方案利用GOT改写成做函数劫持逆向时如果你在调试器里改了GOT发现不生效先检查是不是Full RELRO。此外还要了解重定位。可重定位文件ET_REL里的符号地址都是待定的需要链接器重定位共享库和PIE程序也有重定位动态链接器在加载时处理。x86-64常见重定位类型有R_X86_64_JUMP_SLOTPLT跳转项、R_X86_64_GLOB_DAT全局符号地址、R_X86_64_RELATIVE加基址修正。逆向一个.o文件时你会发现很多地址都是0这不代表文件坏了而是这些地址等着被链接器填进去。2.4 ELF的实操工具与地址换算逆向ELF时我常用的命令组合是file ./sample readelf -h ./sample readelf -S ./sample readelf -l ./sample readelf -d ./sample objdump -d ./sample strings -n 8 ./samplereadelf -d查看动态段能确认依赖了哪些共享库、是否有.init_array构造函数表、程序是不是PIE。strings配合-n参数能过滤掉太短的乱码字符串快速定位可疑路径、URL、命令字符串。ELF的地址换算也比PE灵活一些。静态分析时节头里sh_addr是节在虚拟地址空间中的地址sh_offset是节在文件中的偏移。如果某个虚拟地址落在节区间内文件偏移就是“VA - sh_addr sh_offset”。但要注意有PIE和ASLR的可执行文件运行时基址会随机化你在Ghidra里看到的地址可能是基址为0的模块偏移也可能是固定基址下的绝对地址具体取决于加载器设置。对比之下Windows的PE在文件里通常是固定ImageBase加RVA的表达加载失败后才由重定位表修正。010 Editor的ELF模板是我强烈建议用的工具它把整个文件头、节表、程序头、符号表挨个字段解析出来点击字段就能跳转到对应文件位置比纯命令行直观太多。Ghidra的导入也可以用默认的ELF loader基本不需要额外设置但要注意加载对话框里显示的基址如果显示是0x100000这类值反汇编代码的绝对地址会整体偏移。2.5 一个真实场景Android里的.so与“找不到xweb elf”安卓App里的.so本质上就是ELF文件只是架构变成了ARM/ARM64少数是x86/x86-64。国内很多App的核心逻辑都放在native层逆向时第一刀就是拆lib目录下的.so。微信浏览器内核xweb也是这个路数它基于Chromium相关组件会打包成一系列.so文件。平时会看到“微信 找不到xweb elf”这类问题这个报错通常是App在启动时按既定路径去找xweb的.so结果找不到或加载失败。排查方向不外乎对应的.so文件是否真的存在于data目录或apk包内进程位数和.so架构是否匹配64位进程加载不了32位so路径是不是被重定向so是否被安全模块或系统OTA误删。从逆向工程角度看这个场景给我们一个很好的提醒ELF文件名是可以随便改的但格式内核改不了。看到libxxx.so先不要默认它就是普通动态库用readelf确认架构、类型、动态依赖再决定用IDA还是Ghidra加载能省不少白折腾的时间。3. PE文件MZ头、NT头、节表与导入导出表3.1 从DOS头到PE签名兼容性的历史账PE文件最开头是DOS头以“MZ”两个字符开头0x5A 0x4D这个标志来自MS-DOS时代的Mark Zbikowski。所有Windows可执行文件都带这个DOS头哪怕它根本不打算在DOS下运行。DOS头最后一个重要的字段是e_lfanew一个4字节偏移指向真正的PE头起始位置通常这个偏移是0x80或0x100附近。顺着e_lfanew找到的地方是4个字节的PE签名“PE\0\0”。看到这个签名才能确认这是一个PE文件。再往后是IMAGE_FILE_HEADER里面有Machine字段0x014C是32位x860x8664是x640xAA64是ARM64、NumberOfSections节的数量、TimeDateStamp编译器生成时间戳、SizeOfOptionalHeader、Characteristics0x0002表示可执行0x2000表示DLL。紧接着是IMAGE_OPTIONAL_HEADER这里的信息对逆向更关键。Magic字段区分32位和64位0x10B是PE320x20B是PE32。AddressOfEntryPoint是入口点RVAImageBase是首选加载基址32位默认0x40000064位默认0x140000000SectionAlignment和FileAlignment分别是内存和文件中的对齐粒度。最后还有16项数据目录索引0是导出表1是导入表4是证书表5是重定位表6是调试信息13是延迟导入表。3.2 节表与对齐为什么文件里搜不到内存地址PE文件抬头区之后是节表每项40字节记录一个节的信息包括节名、虚拟大小VirtualSize、虚拟地址VirtualAddress、文件大小SizeOfRawData、文件偏移PointerToRawData、节属性Characteristics。常见的节有.text代码、.data已初始化数据、.rdata只读数据导入导出表也常放这里、.rsrc资源图标、版本信息、对话框、.pdata异常处理x64必备。对齐是这个环节最磨人的问题。内存中SectionAlignment通常是0x1000一页4KB文件中FileAlignment通常是0x200512字节或0x1000。因为两种对齐粒度不同一个节在内存里的起始地址和它在文件里的偏移不是简单相等的关系。这导致一个非常常见的困惑在调试器里看到某个API字符串位于内存地址0x402100你用十六进制编辑器打开exe去搜40 21 00这一串根本搜不到因为你没有把RVA转换成文件偏移。转文件偏移的方法先确定RVA落在哪个节的VirtualAddress到VirtualAddressVirtualSize区间内然后用公式“文件偏移 RVA - 节.VirtualAddress 节.PointerToRawData”。这个计算在CFF Explorer、PE-bear里都有现成的工具也有loadpe这种老牌工具手动算一遍反而能加深理解。逆向分析PE时我建议直接看节表里VirtualAddress和PointerToRawData两列心里先有个映射关系再去看地址。3.3 RVA、虚拟地址与文件偏移的换算PE体系里三个地址概念必须先理清。RVA相对虚拟地址是相对ImageBase的偏移VA虚拟地址是运行时CPU看到的绝对地址等于ImageBase加RVA文件偏移是文件里真实的位置。IDA里显示的地址通常是VA而导入表、导出表里记录的字段都是RVA十六进制编辑器里搜的是文件偏移三者在不同场景下各自出场你不换算就会错位。举个实际例子x64程序的ImageBase是0x140000000导入表里某个DLL名的RVA是0x2A210那么它在内存里的VA就是0x14002A210。假设这个RVA落在.rdata节节的VirtualAddress是0x2A000PointerToRawData是0x200文件偏移就是0x2A210 - 0x2A000 0x200 0x410。这个计算不用背公式关键是理解三个坐标系的关系ImageBase是内存坐标系的原点RVA是相对原点的偏移文件偏移是磁盘坐标系的位置。为什么PE的加载器能做到这一点因为Windows加载PE时会申请一块连续的虚拟内存把各个节按SectionAlignment对齐依次放进去文件头与节在磁盘上的位置虽然不连续但内存里的布局是连续的这就是为什么加载器只需要按节表逐个映射就能工作。3.4 导入表与导出表逆向的第一张地图导入表Import Table描述一个PE文件依赖哪些DLL、调用其中的哪些函数这是逆向静态分析的第一张地图。每个被依赖的DLL对应一个IMAGE_IMPORT_DESCRIPTOR里面有个Name字段指向DLL名字符串OriginalFirstThunk指向导入名称表INTFirstThunk指向导入地址表IAT。在磁盘上INT和IAT通常指向同一个数组加载时加载器把每个函数的真实地址填入IAT动态调试时你看到的IAT里就是真实函数地址。导出表Export Table是DLL对外暴露函数的清单。核心结构包含AddressOfFunctionsEAT函数地址表、AddressOfNamesENT函数名字表、AddressOfNameOrdinalsEOT名称到序号映射表。恶意样本为了增加分析难度有时会把导出函数从名字表里摘掉只保留序号导出。你在IDA里看到DllCanUnloadNow这种系统DLL的导出是正常的但如果一个样本的导出表里只有序号没有任何可读名字就得提高警惕了。延迟导入Delay Import是另一个坑。加壳程序或特定编译器会使用延迟加载DLL第一次调用某函数时才真正加载。静态分析时如果导入表看起来很干净但程序实际运行时又确实调用了很多API那很可能就是用延迟导入藏了真实依赖。用CFF Explorer打开数据目录里的Delay Import目录就能看到这部分内容。3.5 数字证书与加壳PE分析里的两座大山PE文件还有一个容易被忽略的区域证书表。数据目录第4项Security指向文件末尾的数字签名证书数据。带签名的程序文件尾部会有一大段WIN_CERTIFICATE结构。修改过这类程序之后证书不会自动失效但它还在那里导致文件大小、文件尾部数据完整性检查出现各种怪异行为。逆向分析时如果发现文件末尾莫名其妙多出一大段无法解释的数据先看看是不是证书表。加壳检测更是PE逆向里绕不开的一步。常见的壳包括UPX、VMProtect、Themida、ASPack、Enigma等壳会压缩或加密原始代码修改入口点隐藏真实导入表。我的常规流程是先扔进DIEDetect It Easy看编译器指纹和壳类型再看节表有没有UPX0、UPX1、.vmp0、.themida这种特征明显的节名接着算熵值正常程序的节区熵值一般不高加密或压缩后的节熵值会接近7.2以上最后看入口点是否指向不正常的节。这一套组合拳下来大多数壳都能被快速识别。另外一个实用的细节很多时候编译器版本、SDK版本会影响你的分析预期。TimeDateStamp虽然是时间戳但可以被伪造而且很多加壳工具会故意篡改它不能完全当真。看机器类型和子系统值更可靠Subsystem是2表示GUI程序是3表示控制台程序。忘了这茬的朋友经常在控制台程序里等半天看不到输出窗口或者反过来在GUI程序里开了控制台调试却什么都没有。4. 对照表与跨平台实操一个样本拿到手怎么快速判断和处理4.1 ELF与PE核心特征对照两种格式说到底是各自平台的“操作系统说明书”我整理了一张对照表把它复制到笔记里遇到问题时查起来比翻书快。维度ELFPE常见扩展名.o、.so、.elf、无扩展名.exe、.dll、.sys、.ocx文件魔数0x7F 45 4C 467F E L F0x4D 5AMZ再加PE\0\0签名架构字段e_machineMachine入口点e_entry虚拟地址AddressOfEntryPointRVA组织单位Section Segment双视角Section为主地址基准VMA节地址ImageBase RVA代码节.text.text数据节.data / .rodata / .bss.data / .rdata / .bss外部函数动态符号表 PLT/GOT导入表 IAT对外函数动态符号表导出表EAT/ENT/EOT重定位REL/RELA段.reloc节调试信息DWARF.debug_*CodeView / PDB典型加壳UPXELFUPX、VMProtect、Themida动态调试gdb / lldbx64dbg / WinDbg / ollydbg这张表里最值得反复咀嚼的是“地址基准”和“外部函数”两行。ELF更倾向用一个动态符号表全局描述符号PE则把导入导出固化在专门的表结构里。你在Windows下习惯了看“导入表”里有GetProcAddress在Linux下就得习惯去.dynsym里翻函数名在GOT处下断点监控外部函数调用。4.2 快速识别file、魔数、熵值、加壳检测拿到一个未知样本时我有一套固定的快速识别流程不建议跳过任何一步第一步用file命令看类型。Windows下没有file可以装Git Bash或WSL也可以用DIE直接识别。file unknown_sample输出里如果是“ELF 64-bit LSB shared object, x86-64”或“PE32 executable (GUI) x86-64”基本类型就定了。注意file的结果可以被人为伪造但魔数通常不会变所以第二步要用十六进制编辑器或010 Editor看头部。第二步打开文件头确认魔数。ELF是7F 45 4C 46PE是4D 5A开头并在e_lfanew指向的位置找到50 45 00 00PE\0\0。这一步能避免把伪装成图片的实际PE样本当垃圾文件也能避免把纯文本脚本当二进制分析。第三步用DIE或readelf确认架构、位数、编译器特征。DIE对PE极其好用能识别出MSVC、MinGW、Delphi、C#等不同工具链的特征还能给出壳的线索。对ELF则主要依赖readelf -h和自己积累的节表特征。第四步算熵值和看节区异常。010 Editor自带分析工具或者用Python的pefile库也能快速算。熵值超过7.0的节大概率加密或压缩过。同时看节表里有没有奇怪的节名、异常大的VirtualSize或SizeOfRawData。4.3 静态分析的标准流程以Ghidra/010 Editor为例静态分析的标准流程可以归纳为识别、看头、查表、定入口、找引用、看动态。识别和看头上面已经说了。查表阶段对ELF用readelf -S和-d对PE用CFF Explorer或PE-bear看导入表、导出表、重定位表、资源段。导入表的丰富程度决定了你接下来的方向一个正常的程序导入几十个系统API这些都是你推测功能的线索一个加壳的程序导入表可能只有寥寥几个API那基本可以断定它在加载后会动态解析真实API你需要考虑脱壳或动态调试。定入口阶段ELF看e_entryPE看AddressOfEntryPoint。IDA和Ghidra会自动定位但你要学会自己看入口点落在哪个节。正常MSVC程序入口通常指向.text节里的某个startup函数正常GCC Linux程序入口指向_start。如果入口点在.rdata或者指向一个加密的节加壳嫌疑非常大。找引用阶段一般会在反汇编视图里找字符串交叉引用。ELF程序里字符串常量多数在.rodataPE里在.rdata。IDA按X找交叉引用Ghidra右键References即可。字符串交叉引用会直接带你到关键函数然后是关键API调用一套下来基本能拼出样本的粗略功能画像。动态分析阶段ELF用gdbPE用x64dbg。动态分析的核心是确认基址、看真实导入解析结果、在加密函数下断。很多静态看不到的字符串等程序解密后在内存里就显现了。4.4 动态调试中的基址与ASLR问题动态调试里最容易翻车的就是基址不一致。静态分析时IDA加载ELF默认基址可能是0x100000PE默认基址可能是0x140000000但实际运行时ASLR、PIE、系统配置等因素会让模块加载到完全不同的地址调试器里看到的入口点地址和IDA里对不上于是很多人就慌了。我的习惯是不管什么平台先问自己三个问题这个程序是不是PIE或者启用了ASLR当前模块在调试器里的实际加载基址是多少静态反汇编给出的地址是否要加基址修正对PEx64dbg的模块窗口直接显示加载基址对ELFgdb里info proc mappings或info files能查到映射基址。确认完毕再下断点。RELRO和GOT在ELF动态调试里也是一个常见困惑点。有些朋友想在GOT处下硬件断点监控某个外部函数的解析但GOT可能在映射后是只读的断点打不上去。这时候要么在PLT桩下断点要么在调用点下断点总之理解GOT的可写性是被RELRO策略决定的动态调试就会顺畅很多。5. 常见问题排查与经验心得5.1 高频问题速查表我做逆向这几年把朋友和学员问得最多的问题整理成了速查表遇到类似场景直接按表排查。问题现象原因解决办法文件里搜字符串搜不到调试器里却能看到搜的是VA或RVA没转文件偏移RVA减节VirtualAddress加PointerToRawDataELF的调用全是call某个PLT地址看不到真实函数PLT/GOT动态解析机制正常现象看导入表确认目标符号或单步跟进GOTgdb里断点地址和IDA里的地址完全对不上PIE/ASLR导致基址偏移用info proc mappings查基址再加偏移PE导入表看起来只有几个API运行时却调用一堆壳隐藏了导入或使用延迟导入查Delay Import目录或动态调试观察IAT加壳检测扫不出来但熵值奇高自制壳或未公开加密壳结合入口点、节区、动态行为综合判断微信提示找不到xweb elfso缺失、架构不匹配、路径被改、文件被删检查lib目录、ABI目录、data目录完整性ELF被strip后看不到函数名全量符号表被移除依赖动态符号或Ghidra自动分析识别函数调试修改GOT不生效Full RELRO使GOT只读改用PLT Hook或修改代码段这张表背后都有一个共同逻辑不要只看一个现象而是先判断你面对的文件属于哪种格式、哪个加载状态、哪种保护机制再决定排查方向。5.2 我踩过的几个坑第一个坑是魔数迷信。有段时间我只认file命令的判定结果后来一个伪装成JPEG的恶意样本让我在DIE里打开才发现其实是PE因为file只看文件内容但图片头后面完全可以藏一个完整的MZ结构。从此我养成习惯任何样本都先看头部前两行十六进制再听file的结论。第二个坑是地址基准错乱。有一次分析一个Linux控制台程序静态看它在Ghidra里调用了另一个函数结果gdb里在这个地址下断点完全不触发折腾了半小时才发现程序是PIE实际基址比Ghidra默认基址高了一大截。那次之后我每次新建Ghidra项目都会先确认文件类型是ET_EXEC还是ET_DYN是ET_DYN的话直接在加载选项里把基址设为0让所有地址保持在偏移态。第三个坑是PE文件末尾的证书表。分析一个加了签名的正规商业软件时我把文件末尾的大段二进制当成了隐藏数据花时间反推它的结构最后才发现那只是Authenticode证书区。所以现在观察PE文件尾部数据我一定先看数据目录第4项的证书表偏移和大小排除掉这个区域再判断是不是隐藏代码。5.3 工具清单以及我个人的一个小习惯工具方面ELF我常用readelf、objdump、Ghidra、010 Editor配合gdb做动态调试偶尔用radare2或rizin处理路径深、文件名奇怪的样本。PE我常用DIE做快速识别、CFF Explorer或PE-bear看结构、x64dbg做动态调试Python的pefile库也特别香批量分析恶意样本时直接写脚本导出导入表、节表、重定位信息效率比一个个鼠标点高得多。最后分享一个我个人坚持了很长时间的小习惯每分析一个样本不管结论多简单我都会写五行的分析记录第一行文件类型和架构第二行入口点和基址第三行关键导入导出或动态符号第四行加壳和保护机制第五行最终结论。时间久了这相当于攒了一本自己的“文件格式经验库”。逆向工程的学习绕不开这两个格式与其东一榔头西一棒子地搜教程不如拿一个自己编译的hello world、一个系统自带的小程序用这篇文章里的命令逐个字段对照着看一遍把文件头、节表、入口点、导入导出这些概念在自己脑海里建立真实的图景。这一步走扎实了后面不管是恶意样本分析、漏洞研究还是游戏逆向都会顺很多。
返回列表