我们知道,重定位表是由于在代码中写入的绝对地址,而 DLL 不能按照设想的 ImageBase 作起始加载位置去了别的地方占坑,那么需要根据重定位表记录的这些绝对地址在内存中的位置(RVA),逐一去到这些位置修复绝对地址,而产生的表。

表中记录的是代码中 绝对地址 所在的RVA,需要根据偏移去到这个RVA修改掉这四字节的绝对地址

所以我们修改 DLL 的 ImageBase 来模拟这个过程, 相当于模拟 DLL 加载时 占不住原来的 ImageBase 的情况,所以只能在操作系统安排的其他位置加载,这个被安排的位置就相当于我们修改的 ImageBase

然后根据这个新占坑位置和原来 ImageBase 之间的增量来进行重定位表修正,然后存盘.看DLL是否可以使用.

注意 块中的数据项前4位为 0x3 ,才可以修改。 并且 这些绝对地址所在的 RVA 是在 数据项前4位为 0x3 的前提下,取后12位 + 块头部的 VirtualAddress 得到真正的 RVA 的

上述过程理解不透彻没关系,看代码可以彻底纠正理解。代码中也有更详细的说明

#include "Currency.h"
#include "windows.h"
#include "stdio.h"VOID h3263()        //修改ImageBase值,再修改重定位表,使得修改后的文件仍然好使
{char FilePath[] = "CRACKME.EXE";    //CRACKME.EXE        CrackHead.exe     Dll1.dll     R.DLL   LoadDll.dllchar CopyFilePath[] = "CRACKMEcopy.EXE";  //CRACKMEcopy.EXE       CrackHeadcopy.exeLPVOID pFileBuffer = NULL;                //会被函数改变的 函数输出之一LPVOID* ppFileBuffer = &pFileBuffer;   //传进函数的形参int SizeOfFileBuffer;PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;PIMAGE_BASE_RELOCATION pRelocationTable = NULL;DWORD nameFOA = NULL;DWORD AddressOfNamesFOA = NULL;//增量int increment = 0x100000;SizeOfFileBuffer = ReadPEFile(FilePath, ppFileBuffer); //pFileBuffer即指向已装载到内存中的exe首部/*pFileBuffer = *ppFileBuffer;*/if (!SizeOfFileBuffer){printf("文件读取失败\n");return;}//Dos头pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;   // 强转 DOS_HEADER 结构体指针//可选PE头     简化后的处理pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileBuffer + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);//ImageBaseprintf("ImageBase:%x", pOptionalHeader->ImageBase);//重定向表pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RVA2FOA(pFileBuffer, pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress));printf("RelocationTable VirtualAddress:%x\n", pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);if (!pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress){printf("该文件没有重定向表!\n");return;}int i = 1;while (pRelocationTable->VirtualAddress && pRelocationTable->SizeOfBlock){printf("第%d个块VirtualAddress:%x\n", i, pRelocationTable->VirtualAddress);printf("第%d个块SizeOfBlock:%x\n", i, pRelocationTable->SizeOfBlock);printf("第%d个块项数:%d\n", i, (pRelocationTable->SizeOfBlock - 8) / 2);pRelocationTable = (PIMAGE_BASE_RELOCATION)(pRelocationTable->SizeOfBlock + (DWORD)pRelocationTable);i++;}//修改ImageBasepOptionalHeader->ImageBase = pOptionalHeader->ImageBase + increment;printf("ImageBase:%x", pOptionalHeader->ImageBase);//修改重定位表中的值并输出i = 1;PWORD pItem;        //重定向表块中的项指针,2字节不断移动int NumberOfItems;   //重定向表一块中的项数int ItemAdd;        //重定向表一项中表示的地址变量,后续会不断变换为Rva FOA//这里pRelocationTable已经是当前绝对地址了pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RVA2FOA(pFileBuffer, pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress));printf("RelocationTable VirtualAddress:%x\n", pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);while (pRelocationTable->VirtualAddress && pRelocationTable->SizeOfBlock){//pRelocationTable->VirtualAddress += increment;printf("第%d个块VirtualAddress:%x\n", i, pRelocationTable->VirtualAddress);printf("第%d个块SizeOfBlock:%x\n", i, pRelocationTable->SizeOfBlock);NumberOfItems = (pRelocationTable->SizeOfBlock - 8) / 2;pItem = (PWORD)((DWORD)pRelocationTable + 8);    //这里取出来的是还没加上重定向块中的VirtualAddress的Rvaprintf("第%d个块项数:%d\n", i, NumberOfItems);for (int j = 0; j < NumberOfItems; j++){//按位与      1234123456789012     //1234123456789012//if (((*pItem) & 0b1111000000000000) == 0b0011000000000000)if (((*pItem) & 0xF000) == 0x3000)      //这里的3可以用IMAGE_REL_BASED_HIGHLOW代替,不过需要移位而不是与{   //F000 3000printf("项:%x   ", *pItem);ItemAdd = (*pItem) & 0x0FFF;    //这里取出来的是还没加上重定向块中的VirtualAddress的RvaItemAdd = pRelocationTable->VirtualAddress + ItemAdd; //到这里才是真正的Rvaprintf("项Rva:%x\n", ItemAdd);ItemAdd = (DWORD)pFileBuffer + RVA2FOA(pFileBuffer, ItemAdd); //变为FOA再变为绝对地址才能找到真正的值*((PDWORD)ItemAdd) += increment;            //修复这个值}pItem++;}pRelocationTable = (PIMAGE_BASE_RELOCATION)(pRelocationTable->SizeOfBlock + (DWORD)pRelocationTable);i++;}//保存文件MemeryToFile(pFileBuffer, SizeOfFileBuffer , CopyFilePath);free(pFileBuffer);
}

以下是程序输出结果:

ImageBase:400000RelocationTable VirtualAddress:5000
第1个块VirtualAddress:1000
第1个块SizeOfBlock:dc
第1个块项数:106
ImageBase:500000RelocationTable VirtualAddress:5000
第1个块VirtualAddress:1000
第1个块SizeOfBlock:dc
第1个块项数:106
项:3008   项Rva:1008
项:300f   项Rva:100f
项:301f   项Rva:101f
项:3033   项Rva:1033
项:303d   项Rva:103d
项:3046   项Rva:1046
项:304b   项Rva:104b
项:3058   项Rva:1058
项:3069   项Rva:1069
项:306f   项Rva:106f
项:3079   项Rva:1079
项:307d   项Rva:107d
项:3083   项Rva:1083
项:3087   项Rva:1087
项:308c   项Rva:108c
项:3099   项Rva:1099
项:30b8   项Rva:10b8
项:30bd   项Rva:10bd
项:30c9   项Rva:10c9
项:30d1   项Rva:10d1
项:30dc   项Rva:10dc
项:30f8   项Rva:10f8
项:3108   项Rva:1108
项:3112   项Rva:1112
项:311f   项Rva:111f
项:3029   项Rva:1029
项:302d   项Rva:102d
项:31f0   项Rva:11f0
项:320c   项Rva:120c
项:31f8   项Rva:11f8
项:31fe   项Rva:11fe
项:3214   项Rva:1214
项:321a   项Rva:121a
项:3229   项Rva:1229
项:3234   项Rva:1234
项:32b8   项Rva:12b8
项:32d8   项Rva:12d8
项:3350   项Rva:1350
项:3355   项Rva:1355
项:336c   项Rva:136c
项:3371   项Rva:1371
项:33b0   项Rva:13b0
项:33b5   项Rva:13b5
项:3400   项Rva:1400
项:3406   项Rva:1406
项:340c   项Rva:140c
项:3412   项Rva:1412
项:3418   项Rva:1418
项:341e   项Rva:141e
项:3424   项Rva:1424
项:342a   项Rva:142a
项:3430   项Rva:1430
项:3436   项Rva:1436
项:343c   项Rva:143c
项:3442   项Rva:1442
项:3448   项Rva:1448
项:344e   项Rva:144e
项:3454   项Rva:1454
项:345a   项Rva:145a
项:3460   项Rva:1460
项:3466   项Rva:1466
项:346c   项Rva:146c
项:3472   项Rva:1472
项:3478   项Rva:1478
项:347e   项Rva:147e
项:3484   项Rva:1484
项:348a   项Rva:148a
项:3490   项Rva:1490
项:3496   项Rva:1496
项:349c   项Rva:149c
项:34a2   项Rva:14a2
项:34a8   项Rva:14a8
项:34ae   项Rva:14ae
项:34b4   项Rva:14b4
项:34ba   项Rva:14ba
项:34c0   项Rva:14c0
项:34c6   项Rva:14c6
项:34cc   项Rva:14cc
项:34d2   项Rva:14d2
项:34d8   项Rva:14d8
项:34de   项Rva:14de
项:34e4   项Rva:14e4
项:34ea   项Rva:14ea
项:34f0   项Rva:14f0
项:34f6   项Rva:14f6
项:34fc   项Rva:14fc
项:3502   项Rva:1502
项:3508   项Rva:1508
项:350e   项Rva:150e
项:3514   项Rva:1514
项:351a   项Rva:151a
项:3520   项Rva:1520
项:3526   项Rva:1526
项:352c   项Rva:152c
项:3532   项Rva:1532
项:3538   项Rva:1538
项:353e   项Rva:153e
项:3544   项Rva:1544
项:354a   项Rva:154a
项:3550   项Rva:1550
项:3556   项Rva:1556
项:355c   项Rva:155c
项:3562   项Rva:1562
项:3568   项Rva:1568
项:356e   项Rva:156e
success

如果用的是 dll,把新生成的 dll 用另一个工程调用一次,验证是否正确

这里用的是exe,跑完程序后点击下新exe是否正常运行就可以了

滴水逆向三期实践15:重定位表修正相关推荐

  1. 滴水逆向三期实践16:IAT表和导入表

    IAT表 在我们调用 dll 函数的时候,发现代码中的汇编,是通过间接寻址的.也就是不直接 call 函数地址,而是通过一个中间地址再跳转的. 比如调用MessageBox这类系统函数的时候(这也是个 ...

  2. 滴水逆向三期实践1:PE头字段解析,附PE结构下载

    视频资源详见网盘搜索 或 在线的B站滴水逆向三期 其课件也能在CSDN或百度搜索到,以下部分为课件内容摘要,部分为自己的理解 最后附上详细注释的自写代码 PE(Portable Executable) ...

  3. 滴水逆向三期实践10:动态链接库

    使用静态链接生成的可执行文件体积较大,造成浪费 我们常用的printf.memcpy.strcpy等就来自这种静态库 有维护性问题.不方便修改库中实现,修改后所有使用静态库的都要重新链接一遍 因为静态 ...

  4. 滴水逆向三期实践6:扩大节

    扩大节: 1.拉伸到内存(只是逻辑上,实际代码操作并不需要这一步),需要注入的代码为 ShellCode 2.分配一块新的空间:SizeOfImage + sizeof ( ShellCode) 3. ...

  5. 操作系统是如何使用重定位表的

    一.重定位表的结构 重定位表是数据目录中第6项,它的结构如图示: 重定位表由多个块(block)组成,每个块内部由三部分组成--VirtualAddress.SizeOfBlock 和若干个2字节偏移 ...

  6. IAT表入门简析【滴水逆向三期52笔记】

    在讲IAT表之前,我们来回忆一下之前学习的知识: 如果我们将函数写在程序的源文件中,那么该函数就会被编译器直接编译到程序的二进制文件中,在程序调用该函数的时候,E8后跟的地址是直接写死的,程序直接在e ...

  7. 写一个PE的壳_Part 2:ASLR+修复输入表(IAT)+重定位表支持(.reloc)

    系列汇总 写一个PE的壳_Part 1:加载PE文件到内存 写一个PE的壳_Part 2:ASLR+修复输入表(IAT)+重定位表支持(.reloc) 写一个PE的壳_Part 3:Section里实 ...

  8. 滴水逆向三期 win10 ASLR UnmapViewOfSection傀儡进程 加密壳项目

    特意加了一个win10标题, 碰到0xc0000005的朋友就不要再浪费时间了, 我在这个问题上花了整整一天 网上全是xp的代码, 搜到了了几个win10的也是同样的错误没法解决, 唯一一个有用的答案 ...

  9. elf文件中代码段有绝对地址但重定位表中无.text.rel

    阅读<程序员的自我修改>第三章 中关于ELF 文件结构描述 关于重定位表 P79时候产生的问题. 文章中说只要有绝对地址的段,就会有重定位.但是readelf -S helloWorld. ...

最新文章

  1. python中最常用的映射类型_什么是python中唯一的映射类型
  2. 12.6 Nginx安装 12.7 默认虚拟主机 12.8 Nginx用户认证 12.9 Nginx
  3. 使用python开发网页游戏_如何用python开发游戏
  4. Nginx的rewrite案例之目录合并
  5. 计算机事业单位专技岗考什么区别,事业单位管理岗和专技岗的区别(从待遇等角度)...
  6. leetcode152. 乘积最大子数组
  7. Java并发编程之AbstractQueuedSynchronizer(AQS)源码解析
  8. Python数模笔记-模拟退火算法(3)整数规划问题
  9. axios vue 回调函数_VUE使用axios调用后台API接口的方法
  10. scala读取数据从文件或者其他url中
  11. vs2015编译ffmpeg
  12. Linux成长之路-基础篇(2)
  13. C语言实例(六)创建各类三角形
  14. 两阶段网络DEA及其计算
  15. 有哪些国外常用的论文网站
  16. 李岩 太极计算机,《高中体育游戏300例》李岩_孔网
  17. new Date()时间不是当前时间问题的解决方法
  18. JSP 和 JavaBean 来实现一个简易计算器
  19. virtualbox 虚拟机 win7 激活后开机黑屏,只有横杠
  20. APP运营推广不简单 这些数据指标一定要看!

热门文章

  1. 怎么防止别人盗用计算机,如何防止别人盗用我的无线网络
  2. spuer和this关键字
  3. 联想Y460屏幕自动变暗解决
  4. python docx 添加浮空图片
  5. 万豪国际上海第50家酒店--上海东方美谷JW万豪酒店开业
  6. 状态栏、标题栏、导航栏的了解
  7. JS-01-在HTML中嵌入JavaScript代码的三种方式
  8. 免流量惠生活360手机浏览器6.9.9.2评测
  9. 从《黑神话:悟空》的爆火,浅谈当前游戏从业者面临的机遇与挑战
  10. 小红书是失控了,还是故意在收割...