程序的自动改写

曾经,程序的自动改写是每个黑客必备的知识,因为这样可以有效的节约内存,下面是在现代的GNU/Linux 操作系统上实现的程序自我改写。
列一下环境:
speller@SHELL-LAB:~/code/c$ egrep "model name" /proc/cpuinfo | uniq -c
      2 model name      : Pentium(R) Dual-Core  CPU      E6300  @ 2.80GHz
speller@SHELL-LAB:~/code/c$ uname -sr
Linux 2.6.35.10-smp
speller@SHELL-LAB:~/code/c$ gcc --version | grep GCC
gcc (GCC) 4.4.4
speller@SHELL-LAB:~/code/c$


上代码:

  1. /*
  2.  * 文件名: self-modification.c
  3.  * 备注: 一个可以修改自身代码的小程序 ;p
  4.  */
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <sys/mman.h>
  8. void func (void);
  9. int main
  10. (int argc, char *argv[]) {
  11.     
  12.     int count = 0;

  13.     for (count = 0; count < 3; ++count) {
  14.         printf ("第<%d>次执行函数func:/n", count+1);
  15.         func ();
  16.     }
  17.     return 0;
  18. }
  19. void func
  20. (void) {
  21.     __asm__ __volatile__ (
  22.         "slot:/n"
  23.         "nop/nnop/n" /* 这两个nop 指令用来为下面的自动改写留出位置 */
  24.         "after_slot:/n"
  25.     );
  26.     puts ("/t你只能在第<1>次执行函数func 的时候看到这条消息/n"
  27.           "/t/t——因为程序对自身的代码进行了修改。/n");
  28.     
  29.     /* 将函数func 的堆栈属性设置为可读写、可执行 */
  30.     int pagesize = (int)sysconf (_SC_PAGESIZE);
  31.     char *p = (char *)((int)func & ~(pagesize - 1));
  32.     mprotect (p, pagesize * 10, PROT_READ | PROT_WRITE | PROT_EXEC);
  33.     
  34.     /* 进行自我改写 */
  35.     __asm__ __volatile__ (
  36.         ".byte 0xe8, 0, 0, 0, 0/n"     /* 0xe8 是call 指令,把popl 指令当作函数调用 */
  37.         "popl %%eax/n"                /* popl 出栈的是popl 指令自身的地址 */
  38.         "addl $20, %%eax/n"         /* 定位到第二个puts 函数 */
  39.         "subl $after_slot, %%eax/n"/* 得到第二个puts 函数相对于after_slot 标签的偏移 */
  40.         "shl $8, %%eax/n"             /* 这里是little endian 系统 */
  41.         "movb $0xeb, %%al/n"      /* 0xeb 是jmp 指令,%ax 里现在是 <jmp 偏移 >*/
  42.         "movw %%ax, slot"           /* 填充先前两个nop 指令预留出的空间 */
  43.         :
  44.         :
  45.         : "eax"
  46.     );

  47.     puts ("/t这条消息应该在每次调用函数func 的时候都被输出到stdout。/n");
  48.     
  49.     return;
  50. }

效果如下:
speller@SHELL-LAB:~/code/c$ gcc -o self-modification self-modification.c
speller@SHELL-LAB:~/code/c$ ./self-modification
第<1>次执行函数func:
        你只能在第<1>次执行函数func 的时候看到这条消息
                ——因为程序对自身的代码进行了修改。

        这条消息应该在每次调用函数func 的时候都被输出到stdout。

第<2>次执行函数func:
        这条消息应该在每次调用函数func 的时候都被输出到stdout。

第<3>次执行函数func:
        这条消息应该在每次调用函数func 的时候都被输出到stdout。

speller@SHELL-LAB:~/code/c$


程序自身对自身的指令进行修改,有点黑客帝国的味道,不是么

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值