-
-
在高级语言中隐藏Call指令
-
发表于:
2005-3-21 16:56
12429
-
今天写壳的时候想到了一种不需要手动修改直接编译就隐藏了call指令的方法,和大家一起分享。先还是说说手动隐藏call的简单方法。(我习惯用Delphi所以文中是delphi代码)
我在网吧,电脑没有带出来,所以即想即写,有什么错误的地方还望指出来。
手动隐藏方法:
比如我们定义这样的一个过程。
procedure test;
begin
end;
然后在另外一个过程中调用,
begin
test;
end;
一般编译后我们就会看到相应的
00000001 call XXXXXXXX (00000001和XXXXXXXX都是假设的地址)
我们最常用的隐藏方法就是把代码写成这样
begin
test;
asm DB $90,$90,$90,$90,$90,$90 end;
end;
我们需要利用6个nop来为以后的隐藏做准备。
然后等编译后会出现这样的代码
00000001 call XXXXXXXX
00000006 nop
00000007 nop
00000008 nop
00000009 nop
00000010 nop
00000011 nop
然后我们手工需要做的是修改这段代码成如下
00000001 push 00000012
00000006 push XXXXXXXX
00000011 ret
这样代码长度刚好一样
这样就达到了隐藏效果,但是这样每次都要手工修改麻烦,下面看另外一种隐藏方法
自动隐藏:
在上面我们看到了手动隐藏的方法,下面来看自动隐藏方法,同样以test过程为例。
我们都知道这样的一种获取eip的方法
00000001 call 00000006
00000006 pop eax
在看看这段代码的机器码
00000001 FF00000000
00000006 58
{机器吗可能有错误记性不好}
那么我们定义两个变量
var
TestEip:cardinal;
TestPoi:pointer;
先不要问用来做什么,马上就清楚拉。
我们现在把调用代码改以下
begin
Asm
DB $FF,$00,$00,$00,$00,$58;
Add Eax,$20;{这里要看,这个$20是这段代码的大小,反正要让Eax刚好只向Ret后一句的地址}
mov TestEip,eax;
end;
TestPoi:=@Test;
asm
Push TestEip;
Push TestPoi;
ret
end;
然后编译,怎么样?call指令是不是不见了?
但是这样有一个麻烦,那就是万一Test带参数怎么办?
比如:
procedure test(a,b,c:cardinal);
begin
end;
那么我们也可以这样调用
begin
Asm
DB $FF,$00,$00,$00,$00,$58;
Add Eax,$2F;{这里要看,这个$20是这段代码的大小,反正要让Eax刚好只向Ret后一句的地址}
mov TestEip,eax;
mov eax,参数1;
mov ecx,参数2;
mov edx,参数3;
end;
TestPoi:=@Test;
asm
mov eax,testeip;
Push TestEip;
Push TestPoi;
ret
end;
只写这么多拉。没有什么技术含量。有什么更好的方法拿出来大家分享一下呀。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!