滴水逆向 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();
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/651908.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netty 应用与原理

更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 Java IO 模型 本篇示例代码仓库&#xff1a;learn-netty 基础概念 在 I/O 操作中有这么两组概念&#xff0c;其中同步/异步 要和线程中的同步线程/异步线程要区分开&#xff0c;这里指的是同步IO / 异步IO…

ChuanhuChatGPT集成百川大模型

搭建步骤&#xff1a; 拷贝本地模型&#xff0c;把下载好的Baichuan2-7B-Chat拷贝到models目录下 修改modules\models\base_model.py文件&#xff0c;class ModelType增加Baichuan Baichuan 16 elif "baichuan" in model_name_lower: model_type ModelType.Ba…

MySQL双层游标嵌套循环方法

文章目录 1、需求描述2、思路3、创建存储过程 1、需求描述 1、在项目中&#xff0c;需要将A表中主键id&#xff0c;逐个取出&#xff0c;作为条件&#xff0c;在B表中去逐一查询&#xff0c;将B表查询到的结果集&#xff08;A表B表关系&#xff1a;一对多&#xff09;&#xf…

upload-labs通关

前记&#xff1a; 在这里面我们使用一句话木马时使用php里的一个函数phpinfo&#xff08;&#xff09;&#xff0c;该函数能显示出网页具体的php版本和有关的信息。 pass-01&#xff08;js前端验证&#xff09; 方法1&#xff1a;禁用js/删除js验证 1.禁用js 按f12&#xff…

MySQL/MariaDB 如何查看当前的用户

MySQL 的所有数据库用户信息是存储在 user 数据表中的。 可以在登录成功数据后运行 SQL&#xff1a; MariaDB [(none)]> select user,host from user;就可以查看到数据中的所有用户信息。 MariaDB [(none)]> select user,host from user; ERROR 1046 (3D000): No databa…

笔记:编写程序,分别采用面向对象和 pyplot 快捷函数的方式绘制正弦曲线 和余弦曲线。 提示:使用 sin()或 cos()函数生成正弦值或余弦值。

文章目录 前言一、面向对象和 pyplot 快捷函数的方式是什么&#xff1f;二、编写代码面向对象的方法&#xff1a;使用 pyplot 快捷函数的方法&#xff1a; 总结 前言 本文将探讨如何使用编程语言编写程序&#xff0c;通过两种不同的方法绘制正弦曲线和余弦曲线。我们将分别采用…

美国洛杉矶站群服务器如何提高网站排名?

美国洛杉矶站群服务器怎么样?美国洛杉矶站群服务器如何提高网站排名?Rak部落小编为您整理发布美国洛杉矶站群服务器如何提高网站排名? 美国洛杉矶站群服务器可以通过以下几种方式帮助提高网站排名&#xff1a; - **提升网站性能**&#xff1a;美国站群服务器通常配备高速CPU…

cocos-lua资源管理

本文介绍cocos-lua项目的资源管理和工作流&#xff0c;适用人群包括初学者和有经验开发者&#xff0c;故读者可根据自己的需要有选择性的查阅自己需要的内容 一.简单案例解析 下文通过介绍一个简单demo&#xff0c;介绍合图和资源目录结构 1.1 运行效果 1.2 ccs结构 1.3 目录…

Kotlin基础​​

数据类型 定义变量 var表示定义变量&#xff0c;可以自动推导变量类型&#xff0c;所以Int可以不用写。 定义常量 条件语句 if表达式可以返回值&#xff0c;该值一般写在if里的最后一行 类似switch的用法 区间 循环 a是标签&#xff0c;可以直接break到标签的位置&#xf…

【HarmonyOS】Stage 模型 - 基本概念

一、项目结构 如图1所示&#xff1a; 图1 从项目结构来看&#xff0c;这个应用的内部包含了一个子模块叫 entry&#xff0c;模块是应用的基本功能单元&#xff0c;它里面包含源代码、资源、配置文件等。 像这样的模块在应用内部可以创建很多。但模块整体来讲就分成两大类&am…

Docker基本操作 Linux里边操作

docker镜像操作命令: docker images:查看所有镜像; docker rmi:删除镜像 后边可以跟镜像的名字或者id指定要删除的镜像&#xff1b; docker pull:拉取镜像&#xff1b; docker push:推送镜像到服务&#xff1b; docker save :打包镜像 后边有用法; docker load:加载镜像&…

Centos/linux根目录扩容、分区、挂载。LVM、物理卷、逻辑卷

前言    &#xff08;空格&#xff09; &#xff1a;分区挂载和扩容是两码事 每个Linux使用者在安装Linux时都会遇到这样的困境&#xff1a;在为系统分区时&#xff0c;如何精确评估和分配各个硬盘分区的容量&#xff0c;因为系统管理员不但要考虑到当前某个分区需要的容量&a…