移动导出表,移动重定位表【滴水逆向三期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 | 备选工具 )
16193 0
【Windows 逆向】OD 调试器工具 ( 推荐汉化版的 OD 调试工具 | 吾爱破解专用版Ollydbg | 备选工具 )
|
存储 索引
导入表解析,IAT表解析【滴水逆向三期53笔记】
导入表解析,IAT表解析【滴水逆向三期53笔记】
|
数据采集 存储 监控
抖音直播间采集提取工具,直播间匿名截流获客软件,Python开发【仅供学习】
这是一套基于Python开发的抖音直播间数据采集与分析系统,包含观众信息获取、弹幕监控及数据存储等功能。代码采用requests、websockets和sqlite3等...
|
Kubernetes 持续交付 开发者
使用 Docker 和 Kubernetes 实现持续集成和持续部署(CI/CD)
使用 Docker 和 Kubernetes 实现持续集成和持续部署,可以为开发团队带来更高效、稳定的交付流程。这种自动化的部署方式能够显著提高交付速度、降低发布风险,并为应用的扩展和管理提供了强大的工具。然而,构建一个完善的 CI/CD 环境需要根据团队的需求和实际情况进行调整和优化。
3135 1
使用 Docker 和 Kubernetes 实现持续集成和持续部署(CI/CD)
汇编指令学习(AND,OR,XOR,NOT)
汇编指令学习(AND,OR,XOR,NOT)
789 0
|
存储 安全 算法
深入理解Shellcode混淆加密技术
深入理解Shellcode混淆加密技术
1344 0
|
存储 安全 算法
[读书][笔记]WINDOWS PE权威指南《三》PE的原理和基础 之 第三章 PE文件头
WINDOWS PE权威指南《三》PE的原理和基础 之 第三章 PE文件头
922 0
[读书][笔记]WINDOWS PE权威指南《三》PE的原理和基础 之 第三章 PE文件头
|
存储 C语言
PE导出表,C语言打印导出表信息【滴水逆向三期49笔记+作业】(下)
PE导出表,C语言打印导出表信息【滴水逆向三期49笔记+作业】
|
存储 编译器
IAT表入门简析【滴水逆向三期52笔记】
IAT表入门简析【滴水逆向三期52笔记】
新增节添加代码【滴水逆向三期46笔记】
新增节添加代码【滴水逆向三期46笔记】