移动导出表,移动重定位表【滴水逆向三期51笔记+作业源码】(上)

简介: 移动导出表,移动重定位表【滴水逆向三期51笔记+作业源码】

前面章节我们了解了PE文件中的导出表和重定位表,今天我们来学习如何来移动导出表和重定位表。

一.为什么要移动各种表?

首先,这些表都是由编译器生成的,里面存储了非常重要的信息,在程序启动的时候,系统会根据这些表的内容来做一些初始化的工作,比如将用到的dll中的函数地址存储到IAT表(后续我们将会学习)中,为了保护程序,我们可以对exe二进制进行加密操作,但是问题是:各种表的信息,与代码和数据混在一起(存在于各个节中)如果进行加密的话,系统在初始化的时候就会出问题。

学会移动各种表,是对程序加密解密的基础

二.移动导出表

这里给出移动导出表的基本思路,在文章后面会贴出源码

1.首先,我们在文件中新增一个节,我们可以将导出表等信息移动到导出表中

2.将函数地址表移动到新节(也就是AddressOfFunctions所指向的内容)长度:NumberOfFunctions*4注意函数地址表中存储的是函数地址,因为我们没有移动函数,所以我们在移动导出表后无需修正

3.复制函数导出序号表到新节(也就是AddressOfNameOrdinals所指向的内容)长度:NumberOfNames*2注意导出序号表中存储的就是导出序号,移动导出表后无需修正

4.复制函数名称表移动到新节(也就是AddressOfNames所指向的内容)长度:NumberOfNames*4注意函数名称表中存储的是地址,指向函数名称字符串,这里在复制函数名字符串后立即修正函数名称表

5.复制所有函数名字符串长度=字符串长度

6.复杂IMAGE_EXPORT_DIRECTORY结构

7.修复IMAGE_EXPORT_DIRECTORY结构中的AddressOfFunctions,AddressOfOrdinals,AddressOfNames字段

8.修复数据目录表IMAGE_DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_EXPORT]中的VirsualAddress字段,使其指向我们移动后的导出表

三.移动导出表源码

PEFunction.h:
#include <stdio.h>
#include <windows.h>
#include <string.h>
//*************打开文件函数(将文件二进制读取到FileBuffer) ******************
//该函数需要一个char类型的指针,指向想要打开的文件路径
//该函数返回一个char类型的指针,指向FileBuffer
//该函数完成文件的打开,并且将文件的二进制读取到FIleBuffer
//该函数读取完成后会将文件关闭,避免出现误操作
//该函数会通过移动文件指针获取文件大小
//获取的文件大小用于动态申请内存 
//该函数会动态申请内存,用于存放FileBuffer
//***************************************************************************
char* ReadToFileBuffer(char* filename);
//***************************************获取文件大小函数*********************************
//该函数返回文件大小 
//****************************************************************************************
int SizeOfFile(char* filename);
//*****************************获取PE导出表数据函数**************************
//该函数需要一个指针,指向FileBuffer
//该函数在找到导出表之前,需要定义DOS结构指针,标准PE头结构指针和可选PE头指针,以方便找到导出表
//该函数会在控制台输出函数地址表,函数名称表和函数导出序号表 
//***************************************************************************
void ShowExportDirectory(char* FileBuffer);
//*****************************RVA转换为FOA函数******************************
//该函数需要一个指针,指向FileBuffer
//该函数需要一个整数,为要转换的RVA
//该函数返回一个整数,为转换后的FOA地址
//***************************************************************************
int RVAToFOA(IN LPVOID pFileBuffer, IN DWORD dwRva);
//*************************根据函数名称查找函数地址函数**********************
//该函数需要一个指针,指向要打开的文件路径 
//该函数返回一个整数,指向得到的函数地址
//***************************************************************************
void GetAddressOfFunctionByName(char* filename);
//*************************根据函数序号查找函数地址函数**********************
//该函数需要一个指针,指向要打开的文件路径 
//该函数返回一个整数,指向得到的函数地址
//***************************************************************************
void GetAddressOfFunctionByOrdinal(char* filename);
//******************************打印PE重定位表函数***************************
//该函数需要一个指针,指向FIleBuffer
//该函数会在控制台打印出重定位表信息(重定位表偏移,重定位表大小,但不打印重定位表具体项
//***************************************************************************
void ShowBaseRelocation(char* FileBuffer);
//**************************************新增节函数***************************************
//该函数需要一个指针,指向FileBuffer
//该函数需要一个指针,表示FileBuffer大小 
//该函数需要一个字符串,为原文件文件名 
//该函数完成在PE文件中新增一个节
//该函数在新增节之前,PE头部是否足够新增一个节表
//若PE文件头部内存不够新增一个节表,该函数将会提升所有头部,将DOSstob覆盖掉,并且让e_lfanew指向下一个字节 
//该函数会生成一个exe文件,存放于调用该函数的程序源目录下  
//该函数返回一个指针,指向新增节后的FileBuffer 
//****************************************************************************************
char* AddNewSection(char* FileBuffer,int SizeOfFileBuffer);
//*****************************覆盖DOSstob,抬升NT头和原有节表****************************
//该函数需要一个指针,指向需要改动的FileBuffer
//该函数将FileBuffer中的DOSstob覆盖
//该函数将PE头部中,DOS头以后的内容提升到DOSstob的位置 
//抬升成功后会将最后两个节表的数据全初始化为0 
//若头部抬升失败,则返回0 
//若抬升成功,则返回1 
//****************************************************************************************
int UpFile(char* FileBuffer);
//******************************计算文件对齐后的值函数************************************           
//Align:计算对齐后的值         
//参数说明:               
//x  需要进行对齐的值               
//Alignment 对齐大小            
//返回值说明:              
//返回x进行Alignment值对齐后的值                
//****************************************************************************************  
int Align(int x, int Alignment);
//**************************************移动导出表****************************************
//该函数需要一个指针,指向FileBuffer
//该函数需要一个整形参数,表示FileBuffer大小 
//该函数将移动导出表到新节,节名称:.NewSec 
//该函数返回一个指针,指向NewFileBuffer
//****************************************************************************************
char* RemoveExportDirectory(char* FileBuffer,int SizeOfFileBuffer);
main.c:
#include <stdio.h>
int main(int argc, char** argv) {
  char filename1[50];
  char filename2[50];
  printf("******               欢迎使用移动导出表程序               ******\n");
  printf("请输入想要操作的文件路径:");
  scanf("%s",filename1);
  char* FileBuffer=NULL;
  char* NewFileBuffer=NULL;
  int length;
  int* plength=&length; 
  FileBuffer=ReadToFileBuffer(filename1);
  length=SizeOfFile(filename1);
  NewFileBuffer=RemoveExportDirectory(FileBuffer,length);
  printf("请输入您想要保存的文件名称:");
  scanf("%d",filename2);
  FILE* fp;
  if((fp=fopen(filename2,"wb"))==NULL){
    printf("文件新建失败!\n");
    exit(0);
  }else{
    printf("文件新建成功,正在写入数据...\n");
  }
  if(fwrite(NewFileBuffer,length+1000,1,fp)){
    printf("数据写入成功。\n");
  }else{
    printf("数据写入失败!\n");
    exit(0);
  }
  free(FileBuffer);
  free(NewFileBuffer);
  return 0;
}

相关文章
|
Windows
【Windows 逆向】OD 调试器工具 ( 推荐汉化版的 OD 调试工具 | 吾爱破解专用版Ollydbg | 备选工具 )
【Windows 逆向】OD 调试器工具 ( 推荐汉化版的 OD 调试工具 | 吾爱破解专用版Ollydbg | 备选工具 )
12029 0
【Windows 逆向】OD 调试器工具 ( 推荐汉化版的 OD 调试工具 | 吾爱破解专用版Ollydbg | 备选工具 )
|
存储 索引
导入表解析,IAT表解析【滴水逆向三期53笔记】
导入表解析,IAT表解析【滴水逆向三期53笔记】
|
11月前
|
Unix Linux 虚拟化
VMware Workstation 17.6.2 发布下载,现在完全免费无论个人还是商业用途
VMware Workstation 17.6.2 发布下载,现在完全免费无论个人还是商业用途
49424 16
VMware Workstation 17.6.2 发布下载,现在完全免费无论个人还是商业用途
|
12月前
|
数据可视化 数据管理 项目管理
职场打工人怎么记录日常工作?5款热门工具的优缺点分析
本文介绍了五款高效的工作记录工具,包括板栗看板、Miro、Airtable、Notion 和 Wrike,分别针对任务管理、创意协作、数据库管理、多功能笔记及跨团队协作等不同需求,通过对比它们的使用场景、优缺点及其适用性,帮助读者选择最适合自身需求的工具。
2212 0
职场打工人怎么记录日常工作?5款热门工具的优缺点分析
|
安全 Linux 测试技术
|
安全 Linux 网络安全
【答案】2023年国赛信息安全管理与评估正式赛答案-模块2
【答案】2023年国赛信息安全管理与评估正式赛答案-模块2
【答案】2023年国赛信息安全管理与评估正式赛答案-模块2
|
存储 资源调度 大数据
云计算在大数据分析中的弹性资源调度策略
云计算在大数据分析中的弹性资源调度策略
|
存储 编译器
IAT表入门简析【滴水逆向三期52笔记】
IAT表入门简析【滴水逆向三期52笔记】
|
NoSQL Linux 程序员
Linux | 调试器GDB的详细教程【纯命令行调试】-2
Linux | 调试器GDB的详细教程【纯命令行调试】
358 0
|
关系型数据库 MySQL 数据库
【报错】DVWA遇到Could not connect to the database service. Please check the config file. Database Error
【报错】DVWA遇到Could not connect to the database service. Please check the config file. Database Error
2269 0