1. 实验背景与目标这个实验的核心任务是修复一个被破坏的二进制文件phase5.o让它能够正确输出经过加密处理的学号字符串。听起来有点像侦探破案对吧实际上这个过程确实需要像侦探一样仔细观察线索、分析证据。问题的关键在于这个二进制文件的重定位表relocation table中有8个关键条目被人为清零了导致程序无法正确链接和执行。我第一次接触这类问题时也是一头雾水。重定位表是什么为什么它会影响程序的运行经过多次实践后我发现理解重定位表就像是理解城市的地铁线路图 - 它告诉链接器如何把各个分散的代码和数据站点正确连接起来。在这个实验中我们的任务就是修复这张地铁线路图中被擦除的8个关键换乘站信息。2. 理解重定位表的作用2.1 什么是重定位表重定位表.rel.text节是目标文件中一个至关重要的数据结构。它记录了.text节中所有需要被链接器修改的位置。当编译器生成目标文件时它并不知道最终这些代码会被加载到内存的哪个位置所以会留下一些空白支票等待链接器来填写具体的地址值。举个例子就像你写一封信时提到请把礼物送到我家但具体地址要等搬家后才能确定。重定位表就是记录这些待填写地址的地方。2.2 为什么重定位表会影响程序运行在我们的实验场景中phase5.o的.rel.text节中有8个关键条目被清零了。这相当于把信中的8个重要地址信息都擦掉了 - 邮递员链接器自然无法正确投递这些礼物函数调用和数据访问。具体到代码层面这会导致访问TRAN_ARRAY数组时找不到正确地址调用transform_code和encode函数时跳转到错误位置读写CODE和BUF变量时访问错误内存3. 实验准备工作3.1 工具准备要完成这个实验我们需要准备以下工具objdump用于反汇编和查看符号表hexedit直接编辑二进制文件gcc用于链接和测试readelf查看ELF文件结构在Ubuntu上可以通过以下命令安装sudo apt-get install binutils hexedit3.2 分析现有文件首先我们需要仔细分析给出的C代码和phase5.o文件。关键点包括TRAN_ARRAY数组实际符号名为fEgeEFFDICT数组实际符号名为qbivHBBUF和CODE变量transform_code和encode函数使用objdump查看符号表objdump -t phase5.o查看重定位表objdump -r phase5.o4. 定位需要修复的重定位条目4.1 分析C代码与汇编对应关系通过反汇编phase5.o我们可以将汇编代码与C源码对应起来。重点关注以下几个关键位置TRAN_ARRAY访问 在transform_code函数中switch语句访问了TRAN_ARRAY[mode]。这对应汇编中的多个位置需要重定位到fEgeEF符号。函数调用generate_code调用transform_codedo_phase调用encode 这些调用点都需要正确的重定位条目。全局变量访问CODE变量的读写BUF数组的访问FDICT数组的访问4.2 识别被清零的重定位条目通过对比C源码和反汇编代码我们可以找出8个需要修复的重定位位置0x9处TRAN_ARRAY[mode]访问0x3d处TRAN_ARRAY访问case 3分支0x9b处CODE变量访问0xa7处transform_code函数调用0xfb处FDICT数组访问0x102处CODE变量访问0x163处encode函数调用0x16e处BUF数组访问5. 修复重定位表5.1 重定位表结构每个重定位条目由8字节组成前4字节需要重定位的代码位置相对于.text节起始的偏移后4字节重定位类型和符号索引低8位重定位类型01表示PC相对02表示绝对地址高24位符号在符号表中的索引5.2 具体修复步骤使用hexedit打开phase5.o定位到.rel.text节从0x524开始修复0x9处条目偏移量09 00 00 00类型和符号01 00 00 09PC相对符号索引9是fEgeEF修复0x3d处条目偏移量3d 00 00 00类型和符号01 00 00 09同上修复0x9b处条目偏移量9b 00 00 00类型和符号02 00 00 0c绝对地址符号索引12是CODE修复0xa7处条目偏移量a7 00 00 00类型和符号01 00 00 0dPC相对符号索引13是transform_code修复0xfb处条目偏移量fb 00 00 00类型和符号02 00 00 0a绝对地址符号索引10是qbivHB修复0x102处条目偏移量02 01 00 00类型和符号02 00 00 0c绝对地址符号索引12是CODE修复0x163处条目偏移量63 01 00 00类型和符号01 00 00 0fPC相对符号索引15是encode修复0x16e处条目偏移量6e 01 00 00类型和符号02 00 00 0b绝对地址符号索引11是BUF6. 验证修复结果完成所有修改后保存文件并尝试链接运行gcc -o linkbomb main.o phase5.o ./linkbomb如果一切正确程序应该会输出你的加密学号字符串。如果出现错误可以使用objdump再次检查重定位表确认所有条目都已正确修复。7. 常见问题与调试技巧在实际操作中可能会遇到各种问题。以下是我总结的一些常见错误和解决方法段错误 通常是因为某个函数调用的重定位不正确。使用gdb逐步执行程序查看崩溃时的指令地址是否正确。输出乱码 可能是CODE或FDICT变量的重定位不正确导致加密算法使用错误的数据。检查相关重定位条目。链接错误 确认所有需要的符号都在符号表中并且重定位类型PC相对/绝对选择正确。调试时可以结合使用gdb linkbomb layout asm查看程序执行时的实际指令流帮助定位问题。8. 深入理解重定位机制通过这个实验我们不仅学会了如何修复重定位表更重要的是理解了链接器是如何工作的。重定位表实际上是编译器留给链接器的待办事项清单告诉链接器哪些地方需要修改如何修改PC相对还是绝对地址使用哪个符号的值来修改这种机制使得分离编译成为可能 - 我们可以单独编译多个源文件最后由链接器将它们缝合成一个完整的可执行文件。理解这一点对后续学习动态链接、共享库等高级主题至关重要。在实际开发中虽然我们很少需要手动修改重定位表但理解它的原理能帮助我们更好地调试链接错误、理解ABI规范甚至在安全领域分析二进制文件时也会用到这些知识。
Link Lab 实战:解码重定位表,让程序正确输出你的加密学号
1. 实验背景与目标这个实验的核心任务是修复一个被破坏的二进制文件phase5.o让它能够正确输出经过加密处理的学号字符串。听起来有点像侦探破案对吧实际上这个过程确实需要像侦探一样仔细观察线索、分析证据。问题的关键在于这个二进制文件的重定位表relocation table中有8个关键条目被人为清零了导致程序无法正确链接和执行。我第一次接触这类问题时也是一头雾水。重定位表是什么为什么它会影响程序的运行经过多次实践后我发现理解重定位表就像是理解城市的地铁线路图 - 它告诉链接器如何把各个分散的代码和数据站点正确连接起来。在这个实验中我们的任务就是修复这张地铁线路图中被擦除的8个关键换乘站信息。2. 理解重定位表的作用2.1 什么是重定位表重定位表.rel.text节是目标文件中一个至关重要的数据结构。它记录了.text节中所有需要被链接器修改的位置。当编译器生成目标文件时它并不知道最终这些代码会被加载到内存的哪个位置所以会留下一些空白支票等待链接器来填写具体的地址值。举个例子就像你写一封信时提到请把礼物送到我家但具体地址要等搬家后才能确定。重定位表就是记录这些待填写地址的地方。2.2 为什么重定位表会影响程序运行在我们的实验场景中phase5.o的.rel.text节中有8个关键条目被清零了。这相当于把信中的8个重要地址信息都擦掉了 - 邮递员链接器自然无法正确投递这些礼物函数调用和数据访问。具体到代码层面这会导致访问TRAN_ARRAY数组时找不到正确地址调用transform_code和encode函数时跳转到错误位置读写CODE和BUF变量时访问错误内存3. 实验准备工作3.1 工具准备要完成这个实验我们需要准备以下工具objdump用于反汇编和查看符号表hexedit直接编辑二进制文件gcc用于链接和测试readelf查看ELF文件结构在Ubuntu上可以通过以下命令安装sudo apt-get install binutils hexedit3.2 分析现有文件首先我们需要仔细分析给出的C代码和phase5.o文件。关键点包括TRAN_ARRAY数组实际符号名为fEgeEFFDICT数组实际符号名为qbivHBBUF和CODE变量transform_code和encode函数使用objdump查看符号表objdump -t phase5.o查看重定位表objdump -r phase5.o4. 定位需要修复的重定位条目4.1 分析C代码与汇编对应关系通过反汇编phase5.o我们可以将汇编代码与C源码对应起来。重点关注以下几个关键位置TRAN_ARRAY访问 在transform_code函数中switch语句访问了TRAN_ARRAY[mode]。这对应汇编中的多个位置需要重定位到fEgeEF符号。函数调用generate_code调用transform_codedo_phase调用encode 这些调用点都需要正确的重定位条目。全局变量访问CODE变量的读写BUF数组的访问FDICT数组的访问4.2 识别被清零的重定位条目通过对比C源码和反汇编代码我们可以找出8个需要修复的重定位位置0x9处TRAN_ARRAY[mode]访问0x3d处TRAN_ARRAY访问case 3分支0x9b处CODE变量访问0xa7处transform_code函数调用0xfb处FDICT数组访问0x102处CODE变量访问0x163处encode函数调用0x16e处BUF数组访问5. 修复重定位表5.1 重定位表结构每个重定位条目由8字节组成前4字节需要重定位的代码位置相对于.text节起始的偏移后4字节重定位类型和符号索引低8位重定位类型01表示PC相对02表示绝对地址高24位符号在符号表中的索引5.2 具体修复步骤使用hexedit打开phase5.o定位到.rel.text节从0x524开始修复0x9处条目偏移量09 00 00 00类型和符号01 00 00 09PC相对符号索引9是fEgeEF修复0x3d处条目偏移量3d 00 00 00类型和符号01 00 00 09同上修复0x9b处条目偏移量9b 00 00 00类型和符号02 00 00 0c绝对地址符号索引12是CODE修复0xa7处条目偏移量a7 00 00 00类型和符号01 00 00 0dPC相对符号索引13是transform_code修复0xfb处条目偏移量fb 00 00 00类型和符号02 00 00 0a绝对地址符号索引10是qbivHB修复0x102处条目偏移量02 01 00 00类型和符号02 00 00 0c绝对地址符号索引12是CODE修复0x163处条目偏移量63 01 00 00类型和符号01 00 00 0fPC相对符号索引15是encode修复0x16e处条目偏移量6e 01 00 00类型和符号02 00 00 0b绝对地址符号索引11是BUF6. 验证修复结果完成所有修改后保存文件并尝试链接运行gcc -o linkbomb main.o phase5.o ./linkbomb如果一切正确程序应该会输出你的加密学号字符串。如果出现错误可以使用objdump再次检查重定位表确认所有条目都已正确修复。7. 常见问题与调试技巧在实际操作中可能会遇到各种问题。以下是我总结的一些常见错误和解决方法段错误 通常是因为某个函数调用的重定位不正确。使用gdb逐步执行程序查看崩溃时的指令地址是否正确。输出乱码 可能是CODE或FDICT变量的重定位不正确导致加密算法使用错误的数据。检查相关重定位条目。链接错误 确认所有需要的符号都在符号表中并且重定位类型PC相对/绝对选择正确。调试时可以结合使用gdb linkbomb layout asm查看程序执行时的实际指令流帮助定位问题。8. 深入理解重定位机制通过这个实验我们不仅学会了如何修复重定位表更重要的是理解了链接器是如何工作的。重定位表实际上是编译器留给链接器的待办事项清单告诉链接器哪些地方需要修改如何修改PC相对还是绝对地址使用哪个符号的值来修改这种机制使得分离编译成为可能 - 我们可以单独编译多个源文件最后由链接器将它们缝合成一个完整的可执行文件。理解这一点对后续学习动态链接、共享库等高级主题至关重要。在实际开发中虽然我们很少需要手动修改重定位表但理解它的原理能帮助我们更好地调试链接错误、理解ABI规范甚至在安全领域分析二进制文件时也会用到这些知识。