PE学习1 - 手动空白区添加代码

一、系统环境

Parallels虚拟机
Windows 10系统
Visual studio 2019

本篇文章相关知识需要了解PE结构,不清楚请自行百度。

二、实验获取相关数据

1. MessageBox数据

获取本机MessageBox地址,创建程序:

#include <windows.h>

int main(int argc, char* argv[])
{
	MessageBox(0, 0, 0, 0);
	return 0;
}

转到汇编:
PE学习1 - 手动空白区添加代码

单步调试,进入到MessageBox函数,记录MessageBox地址7691F3B0

PE学习1 - 手动空白区添加代码

也可以使用OD工具来找MessageBox地址。

注意,每个电脑中MessageBox的地址是不一样的。

2. 收集函数数据

代码如下:

#include "stdafx.h"
#include <windows.h>

int Funtion(){
	return 1;
}

int main(int argc, char* argv[])
{
	Funtion();
	return 0;
}

转到汇编,单步调试:

PE学习1 - 手动空白区添加代码
PE学习1 - 手动空白区添加代码
PE学习1 - 手动空白区添加代码

如上图,获取到E8和E9指令的数据。

至此,我们可以确定调用MessageBox的硬编码如下,共18个字节。

6A 00 6A 00 6A 00 6A 00
E8 00 00 00 00 
E9 00 00 00 00

三、修改EXE文件

二进制软件打开exe文件,把上一步中18个字节写到文件中。

我电脑环境是Mac,使用010Editor,第一次打开exe文件时会提示是否安装PE插件,用起来很方便。

使用010Editor获取的PE结构相关数据:

入口点:1000h
内存基址:400000h

.text区块:
内存偏移:1000h
文件偏移:400h

.text区块足够放18个字节数据,我这里选择把硬编码放到.text区块中,放在了0x5A0位置上。

PE学习1 - 手动空白区添加代码

下面开始修复程序入口、E8和E9的地址值。

三、修复地址

1. 修复OEP

把程序入口改成我们增加的代码的位置。PE中入口地址是程序在内存中的偏移地址。

新入口地址 = 0x5A0 - 0x400(文件偏移) + 0x1000(内存偏移) = 0x11A0

2. 修复E8和E9的值

E8和E9调用地址 = 跳转的目标地址 - (指令地址 + 指令长度)

这里的“指令地址”是指exe执行后在内存中的地址。

0x5A0在内存中的地址: 0x5A0 - 0x400(文件偏移) + 0x1000(内存偏移) + 0x400000(基址) = 0x4011A0

根据上面的公式:
E8地址 = MessageBox的地址 - (E8地址 + E8指令长度) = 0x7691F3B0 - (0x4011A8 + 5)= 0x7651E203。得到E8跳转地址:E8 03 e2 51 76

E9需要跳转到原来的程序入口:
E9地址 = 原来的OEP地址 - (E9当前地址 + 5) = 0x401000 - (0x4011AD + 5)= 0xFFFFFE4E

E9跳转地址:E9 4E FE FF FF

四、修改exe文件

使用010Editor修改上面步骤中计算的值。保存文件,执行exe,会看到消息提示框。

手动很麻烦,下一篇介绍如何用程序实现。

上一篇:pe | 导出表 | 确定依赖模块


下一篇:电脑重装系统