移动导出表,移动重定位表【滴水逆向三期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;
}

相关文章
|
Web App开发 XML 安全
ZeroShell防火墙存在远程命令执行漏洞(CVE-2019-12725)
zeroshell防火墙存在远程命令执行漏洞,攻击者可通过特定URL链接对目标进行攻击!!!
2302 1
|
存储 索引
导入表解析,IAT表解析【滴水逆向三期53笔记】
导入表解析,IAT表解析【滴水逆向三期53笔记】
|
Java
BTrace如何使用?
BTrace如何使用?
307 0
|
12月前
|
Unix Linux 虚拟化
VMware Workstation 17.6.2 发布下载,现在完全免费无论个人还是商业用途
VMware Workstation 17.6.2 发布下载,现在完全免费无论个人还是商业用途
51099 16
VMware Workstation 17.6.2 发布下载,现在完全免费无论个人还是商业用途
|
数据可视化 数据管理 项目管理
职场打工人怎么记录日常工作?5款热门工具的优缺点分析
本文介绍了五款高效的工作记录工具,包括板栗看板、Miro、Airtable、Notion 和 Wrike,分别针对任务管理、创意协作、数据库管理、多功能笔记及跨团队协作等不同需求,通过对比它们的使用场景、优缺点及其适用性,帮助读者选择最适合自身需求的工具。
2539 0
职场打工人怎么记录日常工作?5款热门工具的优缺点分析
|
监控 Java 测试技术
性能工具之Java分析工具BTrace入门
【5月更文挑战第25天】性能工具之Java分析工具BTrace入门
370 2
|
关系型数据库 MySQL 数据库
Error: Table ‘bWAPP.users‘ doesn‘t exist
Error: Table ‘bWAPP.users‘ doesn‘t exist
|
缓存 监控 网络协议
面对ARP攻击,怎么做好主机安全,受到ARP攻击有哪些解决方案
ARP攻击的具体原理主要是基于ARP(Address Resolution Protocol,地址解析协议)的漏洞进行欺骗和攻击。ARP协议是TCP/IP协议族中的一个重要协议,用于实现IP地址到MAC地址的映射。然而,由于ARP协议在设计时缺乏必要的安全验证机制,使得攻击者有机会进行欺骗和攻击。
|
存储 编译器
IAT表入门简析【滴水逆向三期52笔记】
IAT表入门简析【滴水逆向三期52笔记】
|
Oracle Java 关系型数据库
Neo4J因为JDK不匹配出现启动问题
这是因为你的电脑没有安装好正确版本的JDK,所以不能正常启动。这里提供一个方案,可能可以解决你的问题。
559 0