主页 > 编程资料 > Delphi >
发布时间:2015-09-22 作者:网络 阅读:159次

上次写了一个直接将配置文件添加到对应的位置上的方法.好处就在于木马端不用写专门的代码再来提取配置文件,这样很自然的就节省了木马的体积.坏处就在于那种方法只能给未加壳的程序修改配置.这样每次都得带上个FSG(说明一下,FSG对于这种体积小的木马压缩强度是最大的,是我的最爱)跑.更甚的是FSG给程序加壳的时候还会有进度提示,这样给那些居心不良想破解你程序的人来说无疑是提供了一个机会.只要随便用ollydbg类工具给你来一中断,连脱壳都免了. 

下面的程序不是木马,只是演示这种实现方法.同样分为两部分:配置器和木马.

配置器代码:


程序代码
{该函数是给配置文件加密用的,采用的是xor加密方式,你可以改成你喜欢的加密方式.
当然,这部分绝对可以省略不要.但如果你往木马中写的配置信息涉及到你的敏感资料,
例如往QQ木马尾部写"邮箱"? "邮箱密码"? 那样人家拿Windows记事本一看,明文记录.
有了这部分就不会出现这种情况,xor虽然简单,但对付菜鸟足亦.需要提醒的一点是,这
里不管你用什么加密方式.木马运行后在内存中一定是解密的,用WinHex类工具一查内存
还是可以查到你的资料.所以尽量避免填写敏感资料,例如QQ木马改用ASP接口,这样它
查到的也是没用的一个网址而已.
}

function EncryptSettings(Str : String): String;
var
X, Y : Integer;
A : Byte;
Key:string;
begin
Key:='Fi7ke'; //这个是加密钥匙,你可以随便设置,但解密钥匙要一样,不然解不了密
Y := 1;
for X := 1 to Length(Str) do
begin
A := (ord(Str[X]) and $0f) xor (ord(Key[Y]) and $0f);
Str[X] := char((ord(Str[X]) and $f0) + A);
Inc(Y);
If Y > length(Key) then Y := 1;
end;
Result := Str;
end;

{这一个部分就是正式将数据添加到木马尾部了.本程序上所用到的控件有:
Edit1 ~ Edit5 , 一个Button
}

procedure TForm1.Button1Click(Sender: TObject);
var
f: file;
str: array[1..255] of char;
Each_size: array[1..1] of char;
HostName: string;
len, I: integer;
begin

HostName := EncryptSettings(edit1.Text+'>'+edit2.Text+'>'+edit3.Text+'>'+edit4.Text+'>'+edit5.Text+'>');
//将所有数据都加在一起,并用 > 号来阁开区分,最后用上面的函数加密后付值给变量HostName.

AssignFile(f, 'du.exe'); //打开同目录下的du.exe,准备修改 (这里假设du.exe是木马程序)
Reset(f, 1);

seek(f, filesize(f)); //上次是将指针移动到指定位置,这次是将指针移动到文件末尾
for i := 1 to 255 do str := char(0); //循环写入所有的配置数据
for i := 1 to length(str) do str := HostName;
BlockWrite(f, str, length(HostName));
Each_size[1] := char(length(HostName)); //计算出配置数据的长度

blockwrite(f, Each_size, 1); //写入配置文件的长度到末尾,否则文件改变了长度没变会出错
CloseFile(f); //最后别忘了关闭

end;


OK.一个配置器就这样写好了,是不是很Very Easy?


木马端代码:


程序代码
program du;

uses Windows; //写木马程序最好只包含这个单元,该单元主要包含一些木马用到的API的定义

var
f: file;
each_size: array[1..2] of char;
str: array[1..255] of char;
Setstr, ok1, ok2, ok3, ok4, ok5: string;
len, i: integer;
good: array[0..255] of string;


{
这个不用多说了吧?Delphi的标准函数,剔除空格用的.是我为了节约木马体积
从SysUtils单元中提取出来的.这里废话几句,其实这是犯了Delphi的大忌.SysUtils,
System,SysInit同为Delphi的基石.上面我虽然只定义了Windows单元,但编译器
会自动加入System,SysInit单元.而这几个单元包含了Delphi中的几乎所有异常
处理.是需要互相调用的,这里因为节约体积,我们才强制Kill掉了SysUtils单元,
平时可是切忌,切忌~~
}

function Trim(const S: string): string;
var
I, L: Integer;
begin
L := Length(S);
I := 1;
while (I <= L) and (S[I] <= ' ') do Inc(I);
if I > L then Result := '' else
begin
while S[L] <= ' ' do Dec(L);
Result := Copy(S, I, L - I + 1);
end;
end;

{配置器里有Xor加密函数,这里肯定就是Xor解密函数}

function DecryptSettings(Str : String): String;
var
X, Y : Integer;
A : Byte;
Key:string;
begin
Key:='Fi7ke'; //注意了,这里要和加密钥匙一样.
Y := 1;
for X := 1 to Length(Str) do
begin
A := (ord(Str[X]) and $0f) xor (ord(Key[Y]) and $0f);
Str[X] := char((ord(Str[X]) and $f0) + A);
Inc(Y);
If Y > length(Key) then Y := 1;
end;
Result := Str;
end;

{正式开始了......}

begin
FileMode := 0; //设置文件模式,否则会不允许修改
assignfile(f, paramstr(0)); //打开自己
Reset(f, 1);
seek(f, filesize(f) - 1); //移动到末尾-1,因为最后一个字节记录的是配置长度,不是配置数据
BlockRead(f, each_size, 1); //读出长度
len := 0;
for i := 1 to 2 do len := len + ord(each_size); //计算总长度
seek(f, filesize(f) - 1 - len); //将指针移动到配置数据开始的地方
for i := 1 to 255 do str := ' ';
blockread(f, str, len); //读出所有配置数据
setstr := (trim(DecryptSettings(str))); //将配置数据解密后付值给SetStr变量
CloseFile(f); //关闭

{
还记得我们在写配置器的时候每个数据中都用>符号阁开了吗?就是做这个用的,下面是以>符号为间隔又将所有数据全部分开还原,这部分很简单,如果你看得有困难,我建议你回去重读Delphi语法基础.
}

ok1 := Trim(Copy(setstr, 0, Pos('>', setstr) - 1));
Delete(setstr, 1, Pos('>', setstr));
ok2 := Trim(Copy(setstr, 0, Pos('>', setstr) - 1));
Delete(setstr, 1, Pos('>', setstr));
ok3 := Trim(Copy(setstr, 0, Pos('>', setstr) - 1));
Delete(setstr, 1, Pos('>', setstr));
ok4 := Trim(Copy(setstr, 0, Pos('>', setstr) - 1));
Delete(setstr, 1, Pos('>', setstr));
ok5 := Trim(Copy(setstr, 0, Pos('>', setstr) - 1));
Delete(setstr, 1, Pos('>', setstr));
{
最后弹出提示框,可以让你更直观.
}
Messagebox(0,pchar(ok1+#13+#10+ok2+#13+#10+ok3+#13+#10+ok4+#13+#10+ok5),'读取的数据', MB_OK);
end. 

关键字词: