IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 滴水逆向三期实践15:重定位表修正 -> 正文阅读

[开发工具]滴水逆向三期实践15:重定位表修正

我们知道,重定位表是由于在代码中写入的绝对地址,而 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.dll
	char CopyFilePath[] = "CRACKMEcopy.EXE";	//CRACKMEcopy.EXE       CrackHeadcopy.exe
	LPVOID 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);
	//ImageBase
	printf("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++;
	}
	//修改ImageBase
	pOptionalHeader->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的Rva
		
		printf("第%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 3000
				printf("项:%x   ", *pItem);
				ItemAdd = (*pItem) & 0x0FFF;	//这里取出来的是还没加上重定向块中的VirtualAddress的Rva
				ItemAdd = pRelocationTable->VirtualAddress + ItemAdd;	//到这里才是真正的Rva
				printf("项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是否正常运行就可以了

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-10-30 12:42:51  更:2021-10-30 12:44:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 20:49:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码