#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include <stdlib.h>
#include <malloc.h>
#include<windows.h>
#include<memory.h>
int shellcodelength = 0x12;
char* MessageBoxAddress = (char* )&MessageBoxA;
char shellcode[] = {
0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00,//push 0 0 0 0
0xE8,0x00,0x00,0x00,0x00,//call MessageBox
0xE9,0x00,0x00,0x00,0x00//JMP OEP,程序入口点
};//18个字节
int GetFileszie(FILE* fptr);
char* ReadFilea(const char* Filepath);
char* FileToImage() {
char* pFileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;//DOS头
PIMAGE_NT_HEADERS pNTHeader = NULL;//NT头
PIMAGE_FILE_HEADER pPEHeader = NULL;//PE头
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;//可选PE头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头
pFileBuffer = ReadFilea("D:\\ipmsg\\IPMsg_2_1.exe");
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)(pFileBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(pFileBuffer + pDosHeader->e_lfanew + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileBuffer + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
char* fptr = (pFileBuffer + (pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader);
pSectionHeader = PIMAGE_SECTION_HEADER(fptr);
char* pImageBuffer = NULL;
pImageBuffer = (char*)malloc(pOptionHeader->SizeOfImage);
if(!pImageBuffer)
printf("申请空间失败!\n");
//申请空间的大小为SizeOfImage
memset(pImageBuffer, 0, pOptionHeader->SizeOfImage);
//一定要初始化
memcpy(pImageBuffer, pFileBuffer, pOptionHeader->SizeOfHeaders);
//头部信息可以先直接全部复制
//注意复制的大小为SizeOfHeaders
for(size_t i = 0; i<pPEHeader->NumberOfSections; i++) {//size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数
memcpy((void*)(pImageBuffer + pSectionHeader->VirtualAddress), (void*)(pFileBuffer + pSectionHeader->PointerToRawData), pSectionHeader->SizeOfRawData);
//将FileBuffer中从第一个节点开始,把SizeOfRawData大的节点复制到pImageBuffer+VirtualAddress处
pSectionHeader++;
}
//复制节点(拉伸)
//拉伸后存盘
FILE* nFp;
nFp = fopen("D:\\ipmsg\\IPMsg_new2_1.exe", "wb");//复制到指定位置
fwrite(pImageBuffer, pOptionHeader->SizeOfImage, 1, nFp);
fclose(nFp);
free(pFileBuffer); pFileBuffer = NULL;
return pImageBuffer;
}
void ImageToFile(char* pImageBuffer) {
PIMAGE_DOS_HEADER pDosHeader = NULL;//DOS头
PIMAGE_NT_HEADERS pNTHeader = NULL;//NT头
PIMAGE_FILE_HEADER pPEHeader = NULL;//PE头
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;//可选PE头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)(pImageBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(pImageBuffer + pDosHeader->e_lfanew + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(pImageBuffer + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
char* fptr = (pImageBuffer + (pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader);
pSectionHeader = PIMAGE_SECTION_HEADER(fptr);
int sum = 0;
for(size_t i=0; i<pPEHeader->NumberOfSections; i++) {
sum += pSectionHeader->PointerToRawData;
pSectionHeader++;
}
//还原后存盘
char* NewFileBuffer = NULL;
NewFileBuffer = (char*)malloc(pOptionHeader->SizeOfHeaders + sum);
if(!NewFileBuffer)
printf("申请空间失败!\n");
memset(NewFileBuffer, 0, pOptionHeader->SizeOfHeaders + sum);
//不要忘记初始化
memcpy(NewFileBuffer, pImageBuffer, pOptionHeader->SizeOfHeaders + sum);
//头部还是保持不变
fptr = (pImageBuffer + (pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader);
pSectionHeader = PIMAGE_SECTION_HEADER(fptr);
//重新指向第一个节点
for(size_t i = 0; i < pPEHeader->NumberOfSections; i++) {
memcpy((void*)(NewFileBuffer + pSectionHeader->PointerToRawData), (void*)(pImageBuffer + pSectionHeader->VirtualAddress), pSectionHeader->SizeOfRawData);
//将pImageBuffer的第一个节点开始(pImageBuffer+VirtualAddress),把SizeOfRawData大的节点复制到NewFileBuffer+PointerToRawData
pSectionHeader++;
}
FILE* nFp1;
nFp1 = fopen("D:\\ipmsg\\IPMsg_2.exe", "wb");
fwrite(NewFileBuffer, pOptionHeader->SizeOfHeaders + sum, 1, nFp1);
fclose(nFp1);
free(NewFileBuffer); NewFileBuffer = NULL;
}
char* ReadFilea(const char *Filepath ){
FILE* fptr = NULL;
fptr = fopen(Filepath,"rb");
if(!fptr) {
printf("打开失败");
return NULL;
}
int filesize = 0;
filesize = GetFileszie(fptr);
if (filesize == 0) {
printf("获取文件大小失败");
return NULL;
}
char* FileBuffer = (char*)malloc(filesize);
if(!FileBuffer) {
printf("开辟空间失败");
return NULL;
}
size_t n=fread(FileBuffer, 1, filesize, fptr);//将文件内容读到内存中
if(!n) {
printf("读取数据失败");
free(FileBuffer);
FileBuffer = NULL;
fclose(fptr);
return NULL;
}
fclose(fptr);
return FileBuffer;
}
int GetFileszie(FILE* fptr) {
int num = 0;
fseek(fptr, 0, SEEK_END);
num = ftell(fptr);
fseek(fptr, 0, SEEK_SET);
return num;
}
bool Addshellcode() {
PIMAGE_DOS_HEADER pDosHeader = NULL;//DOS头
PIMAGE_NT_HEADERS pNTHeader = NULL;//NT头
PIMAGE_FILE_HEADER pPEHeader = NULL;//PE头
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;//可选PE头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头
char* pFileBuffer = NULL;
char* pImageBuffer = NULL;
pFileBuffer = ReadFilea("D:\\ipmsg\\IPMsg_2_1.exe");//读取PE到内存中
pImageBuffer = FileToImage();
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)(pImageBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(pImageBuffer + pDosHeader->e_lfanew + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(pImageBuffer + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
char* fptr = (pImageBuffer + (pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader);
pSectionHeader = PIMAGE_SECTION_HEADER(fptr);
if(!pFileBuffer) {
printf("读取失败\n");
return FALSE;
}
if(*(short*)pImageBuffer != IMAGE_DOS_SIGNATURE) {
printf("不是有效的MZ标志\n");
free(pImageBuffer);
free(pFileBuffer);
return FALSE;
}
if(*(int*)(pImageBuffer + (pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) {
printf("不是有效的PE标志\n");
free(pImageBuffer);
free(pFileBuffer);
return FALSE;
}
int unuseSpace = pSectionHeader->SizeOfRawData - pSectionHeader->Misc.VirtualSize;
if(unuseSpace < shellcodelength) {
printf("内存大小不够添加指定代码\n");
free(pImageBuffer);
free(pFileBuffer);
return FALSE;
}
PBYTE codeoffset = NULL;
//shellcode插入点
codeoffset = (PBYTE)(pImageBuffer + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize);
memcpy(codeoffset,shellcode,shellcodelength);
DWORD calladdr = (uintptr_t)MessageBoxAddress - (uintptr_t)(pOptionHeader->ImageBase + (codeoffset + 0xD - (uintptr_t)pImageBuffer));
memcpy((LPVOID)((uintptr_t)codeoffset + 9), &calladdr, 4);
DWORD jmpaddr = (uintptr_t)(pOptionHeader->ImageBase + pOptionHeader->AddressOfEntryPoint) - (uintptr_t)(pOptionHeader->ImageBase + (codeoffset + 0x12 - (uintptr_t)pImageBuffer));
memcpy((LPVOID)((uintptr_t)codeoffset + 0xE), &jmpaddr, 4);
//修改OEP
pOptionHeader->AddressOfEntryPoint = (uintptr_t)(codeoffset - (uintptr_t)pImageBuffer);
ImageToFile(pImageBuffer);
free(pImageBuffer); pImageBuffer = NULL;
free(pFileBuffer); pFileBuffer = NULL;
printf("插入shellcode成功!\n");
return true;
}
int main() {
Addshellcode();
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1666739907@qq.com