PE之添加任意代码到空白区
预备知识
汇编命令 | 硬编码 |
---|---|
call | E8 00 00 00 00 |
jmp | E9 00 00 00 00 |
push | 6A 00 |
需要添加的代码:
6A 00 6A 00 6A 00 6A 00 E8 00 00 00 00 E9 00 00 00 00
//前面四个6A硬编码代表的是传入的参数,E8为Call E9为jmp
//大小为18个字节
1.查找本机MessageBoxA地址
1.打开OD调试工具拖入要添加的exe程序。
注意必须是有user32.dll的exe否则没有MessageA函数地址
2.在命令中输入 : (输入后按下回车键)
bp MessageBoxA
3.点击断点页面即可看到MessageBoxA 的地址
地址=76F81060 模块/标签/异常=<user32.dll.MessageBoxA> 状态=已启用 反汇编=mov edi,edi
开始添加代码
1.查看要添加的文件空白区大小是否足够
使用PETool载入exe 查看pe结构任意节表空白区
空白区还剩下566个字节是够用的。
2.打开16进制编辑器,载入要修改的EXE。找到文件中的大小(对齐后的长度的位置+ 文件中偏移的位置) (1C000 + 1000 = 1d000)
需要添加的代码:
6A 00 6A 00 6A 00 6A 00 E8 00 00 00 00 E9 00 00 00 00
//前面四个6A硬编码代表的是传入的参数,E8为Call E9为jmp
//大小为18个字节
3.在1d000位置上面找任意一段空白区添加上代码 (最好是添加到 空白区开始预留一行的位置,便于以后再添加更多代码节约空间)
往上翻以后发现这个区段从1cab0开始就已经是空白区了那就添加到1cab0这个位置吧
计算E8跳转的地址
公式:
真正要跳转的地址 = E8这条指令的下一行地址 + x(E8后面跟的值)
x = 真正要跳转的地址 - E8这条指令的下一行的地址
要跳转的地方 = E8当前的地址 + 5 + x
x = 要跳转的地址 - (E8的地址 + 5)(上面三行可以不用管,重点看这行就行)
这里我们要跳转的地址为MessageBoxA的地址在上面已经教大家查找过了:
MessageBoxA的地址(要跳转的地址) = 76F81060 (内存中的地址)
(E8的地址 + 5) = 1cabd (文件中的地址)
(E8的地址 + 5) 即 E8下一行的地址,如图:
由于 1cabd 是文件中的地址,还要进行一次转换,变成内存中的地址。
即 1cabd + ImageBase (1cabd + 00400000)= 41cabd
x = 76F81060 - 41cabd = 76B6 45A3
E8 A3 45 B6 76
//内存中字节是大端存储的,所以是倒序。
修改OEP (程序入口的点)
原始入口点为:
BE 93 01
要修改的入口点为:
01 CA B0
写入到文件用大端存储 :B0 CA 01
修改前为:
修改后为:
修改完成后保存文件,双击exe测试是否修改正确如图:
但是此时不会转到正确的软件界面。因为我们还没有计算E9该跳转的位置。
x = 01 93 BE +(400000) - 41cac2
x = 4193be - 41cac2 = FFFFC8FC
//原始入口点(在内存中开始的位置)减去跳转的下一行地址
E8 FC C8 BF FF
//内存中字节是大端存储的,所以是倒序。
完成后效果演示:
实例代码
#define MessageBoxAToState 0x75031060
char INFILEPATH[] = "D:\\PETool 1.0.0.5.exe";
char OUTFILEPATH[] = "D:\\PETool 1.0.0.5(1).exe";
const char SHELLCODE[] = { 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00,
0xE8, 0x00, 0x00, 0x00, 0x00,
0xE9, 0x00, 0x00, 0x00, 0x00 };
//**************************************************************************
//AddImageBufferToShellCode:将FileBuffer中添加恶意代码
//参数说明:
//pFileBuffer FileBuffer指针
//pNewBuffer NewBuffer指针
//pShellCode ShellCode指针
//返回值说明:
//读取失败返回false 否则返回true
//**************************************************************************
BOOL AddFileBufferToShellCode(IN OUT LPVOID pFileBuffer, IN const char* pShellCode, IN size_t ShellCodeSize)
{
//DOC头
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
//NT头
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
//标准PE头
PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
//可选PE头
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
//节表解析
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
//计算空间是否足够
DWORD whiteSpaceSize = 0;
for (int i = 0; i < pPEHeader->NumberOfSections; i++)
{
//计算对其前的长度和对其后的长度,判断空白区域是否足够
whiteSpaceSize = pSectionHeader->SizeOfRawData - pSectionHeader->Misc.VirtualSize;
if (sizeof(*pShellCode) + 16 < whiteSpaceSize)
{
printf("%s: %d %s %d \n", "节表", i, "空白区域剩余:", whiteSpaceSize);
//开始添加ShellCode
char* pShellCodeAddress = (char*)pFileBuffer;
pShellCodeAddress = pShellCodeAddress + (pSectionHeader->Misc.VirtualSize + pSectionHeader->VirtualAddress) + 22;
memcpy(pShellCodeAddress, pShellCode, ShellCodeSize);
//AddCharacterCompressionToMemory(pShellCode, shellCodeSize, pShellCodeBuffer); //如果是字符串用这个
//计算E8 x = 要跳转的地址 - (E8的地址 + 5)
int e8CallAddress = MessageBoxAToState - ((int)(pShellCodeAddress + 0xd) - (int)pFileBuffer + pOptionHeader->ImageBase);
*(int*)(pShellCodeAddress + 0x9) = e8CallAddress;
//计算E9 x = 要跳转的地址 - (E8的地址 + 5)
int e9CallAddress = (pOptionHeader->AddressOfEntryPoint + pOptionHeader->ImageBase) - ((int)(pShellCodeAddress + 0x12 - (int)pFileBuffer) + pOptionHeader->ImageBase);
*(int*)(pShellCodeAddress + 0xe) = e9CallAddress;
//修改OEP
pOptionHeader->AddressOfEntryPoint = (pShellCodeAddress - (char*)pFileBuffer);
pShellCodeAddress = nullptr;
return true;
}
else
{
printf("%s: %d %s \n", "节表", i, "空白区域不足!");
}
pSectionHeader++;
}
return false;
}
实例代码测试图
开源地址:
源代码: https://github.com/vShellCode/Analysis-of-PE-structure
觉得不错请给个star!