任意代码空白区添加代码

#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
github