滴水逆向 FileBuffer-ImageBuffer 课后作业

1)- 实现如下功能 

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
BYTE* bufferApply = nullptr;//将磁盘文件复制到内存中后, 使用bufferApply指向该空间
DWORD fileSize = 0;//将磁盘文件复制到内存时使用需要申请空间, 使用fileSize设置申请空间的大小

BYTE* bufferMem = nullptr;//将内存中文件进行拉伸时需要申请新的空间, 使用bufferMem指向该空间
BYTE* bufferNewMem = nullptr;//将内存中拉伸后的文件拉回到新的空间, 使用bufferNewMem指向该空间

WORD section_num = 0;//代表文件中节的个数
LPVOID pFileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
char str[9] = { 0 };//用于存储节表中的节表名称字符串
void LoadToMemory() {
	char* road = "D:\\Ddisk\\goodThing\\fg.exe";//设置文件路径
	FILE *note = NULL;
	fopen_s(&note, road, "rb");//打开文件
	fseek(note, 0, SEEK_END);//将文件指针移到末端
	fileSize = ftell(note);//获取文件指针位置得知文件大小
	fseek(note, 0, SEEK_SET);//将文件指针移到开始位置
	bufferApply = (BYTE*)malloc(fileSize);//根据文件大小分配内存
	fread(bufferApply, 1, fileSize, note);//将文件指针指向的内容读取到内存中
	fclose(note);//关闭文件指针
}
void SetHeader() {//设置各个PE文件头的参数
	pDosHeader = (PIMAGE_DOS_HEADER)bufferApply;
	pNTHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + (DWORD)bufferApply);
	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + 20);
	WORD optional_size = pPEHeader->SizeOfOptionalHeader;
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + optional_size);
	section_num = pPEHeader->NumberOfSections;
}
void ReleaseMem() {
	free(bufferApply);
	free(bufferMem);
	free(bufferNewMem);
}
void File_To_Image() {//将内存中的文件拉伸到新的空间
	bufferMem = (BYTE*)calloc(pOptionHeader->SizeOfImage, sizeof(char));
	memcpy(bufferMem, bufferApply, pOptionHeader->SizeOfHeaders);
	PIMAGE_SECTION_HEADER SectionHeader = pSectionHeader;
	for (int i = 0; i < section_num; i++) {
		memcpy((void*)((DWORD)bufferMem + SectionHeader->VirtualAddress),
			(void*)((DWORD)bufferApply + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData);
		SectionHeader++;
	}
	
}
void Image_To_Mem() {//将内存中的文件拉回到新的空间
	bufferNewMem = (BYTE*)malloc(fileSize);
	memcpy(bufferNewMem, bufferMem, pOptionHeader->SizeOfHeaders);
	PIMAGE_SECTION_HEADER SectionHeader = pSectionHeader;
	for (int i = 0; i < section_num; i++) {
		memcpy((void*)((DWORD)bufferNewMem + SectionHeader->PointerToRawData),
			(void*)((DWORD)bufferMem + SectionHeader->VirtualAddress), SectionHeader->SizeOfRawData);
		SectionHeader++;
	}
}
int main() {
	LoadToMemory();
	SetHeader();
	File_To_Image();
	Image_To_Mem();
	char* road = "D:\\Ddisk\\goodThing\\hello.exe";
	FILE *bomb = NULL;
	fopen_s(&bomb, road, "wb");
	size_t written = fwrite(bufferNewMem, 1, fileSize, bomb);
	fclose(bomb);
	ReleaseMem();
}

2)- 编写一个函数,能够将RVA的值转换成FOA. 

  • RVA (Relative Virtual Address):PE文件加载到内存中时相对于ImageBase的偏移量

  • FOA (File Offset Address):PE 文件中的数据相对于文件开始的偏移量

    #include<stdio.h>
    #include<stdlib.h>
    #include<windows.h>
    BYTE* bufferApply = nullptr;//将磁盘文件复制到内存中后, 使用bufferApply指向该空间
    DWORD fileSize = 0;//将磁盘文件复制到内存时使用需要申请空间, 使用fileSize设置申请空间的大小
    
    WORD section_num = 0;//代表文件中节的个数
    LPVOID pFileBuffer = NULL;
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    void LoadToMemory() {
    	char* road = "D:\\Ddisk\\goodThing\\fg.exe";//设置文件路径
    	FILE *note = NULL;
    	fopen_s(&note, road, "rb");//打开文件
    	fseek(note, 0, SEEK_END);//将文件指针移到末端
    	fileSize = ftell(note);//获取文件指针位置得知文件大小
    	fseek(note, 0, SEEK_SET);//将文件指针移到开始位置
    	bufferApply = (BYTE*)malloc(fileSize);//根据文件大小分配内存
    	fread(bufferApply, 1, fileSize, note);//将文件指针指向的内容读取到内存中
    	fclose(note);//关闭文件指针
    }
    void SetHeader(BYTE* buffer) {//设置各个PE文件头的参数
    	pDosHeader = (PIMAGE_DOS_HEADER)buffer;
    	pNTHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + (DWORD)buffer);
    	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
    	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + 20);
    	WORD optional_size = pPEHeader->SizeOfOptionalHeader;
    	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + optional_size);
    	section_num = pPEHeader->NumberOfSections;
    }
    void ReleaseMem() {
    	free(bufferApply);
    }
    DWORD RVA_To_FOA(BYTE* addr, BYTE* buffer) {
    	BYTE* tem_buffer = (BYTE*)pDosHeader;//存储原来pDosHeader的数据, 因为下面要对数据进行修改
    	SetHeader(buffer);//改变pDosHeader中的数据
    	PIMAGE_SECTION_HEADER SectionHeader = pSectionHeader;
    	DWORD offset = (DWORD)addr - (DWORD)buffer;//得到相对于起始位置的偏移地址
    	for (int i = 0; i < section_num; i++) {//判断地址属于哪个节并做相应转换
    		if (offset > SectionHeader->VirtualAddress &&
    			(offset < (SectionHeader->VirtualAddress+SectionHeader->Misc.VirtualSize) || 
    				offset < (SectionHeader->VirtualAddress+SectionHeader->SizeOfRawData))) {
    			offset = offset - SectionHeader->VirtualAddress;
    			DWORD file_off = (SectionHeader->PointerToRawData) + offset;
    			SetHeader(tem_buffer);
    			return file_off;
    		}
    		SectionHeader++;
    	}
    	SetHeader(tem_buffer);
    	return -1;
    }
    int main() {
    	LoadToMemory();
    	SetHeader(bufferApply);
    	ReleaseMem();
    }

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值