曾经,程序的自动改写是每个黑客必备的知识,因为这样可以有效的节约内存,下面是在现代的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$
上代码:
效果如下:
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$
程序自身对自身的指令进行修改,有点黑客帝国的味道,不是么 ;p
阅读(147) | 评论(0) | 转发(0) |
<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
列一下环境:
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$
上代码:
- /*
- * 文件名: self-modification.c
- * 备注: 一个可以修改自身代码的小程序 ;p
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/mman.h>
- void func (void);
- int main
- (int argc, char *argv[]) {
-
- int count = 0;
- for (count = 0; count < 3; ++count) {
- printf ("第<%d>次执行函数func:\n", count+1);
- func ();
- }
- return 0;
- }
- void func
- (void) {
- __asm__ __volatile__ (
- "slot:\n"
- "nop\nnop\n" /* 这两个nop 指令用来为下面的自动改写留出位置 */
- "after_slot:\n"
- );
- puts ("\t你只能在第<1>次执行函数func 的时候看到这条消息\n"
- "\t\t——因为程序对自身的代码进行了修改。\n");
-
- /* 将函数func 的堆栈属性设置为可读写、可执行 */
- int pagesize = (int)sysconf (_SC_PAGESIZE);
- char *p = (char *)((int)func & ~(pagesize - 1));
- mprotect (p, pagesize * 10, PROT_READ | PROT_WRITE | PROT_EXEC);
-
- /* 进行自我改写 */
- __asm__ __volatile__ (
- ".byte 0xe8, 0, 0, 0, 0\n" /* 0xe8 是call 指令,把popl 指令当作函数调用 */
- "popl %%eax\n" /* popl 出栈的是popl 指令自身的地址 */
- "addl $20, %%eax\n" /* 定位到第二个puts 函数 */
- "subl $after_slot, %%eax\n"/* 得到第二个puts 函数相对于after_slot 标签的偏移 */
- "shl $8, %%eax\n" /* 这里是little endian 系统 */
- "movb $0xeb, %%al\n" /* 0xeb 是jmp 指令,%ax 里现在是 <jmp 偏移 >*/
- "movw %%ax, slot" /* 填充先前两个nop 指令预留出的空间 */
- :
- :
- : "eax"
- );
- puts ("\t这条消息应该在每次调用函数func 的时候都被输出到stdout。\n");
-
- return;
- }
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$
程序自身对自身的指令进行修改,有点黑客帝国的味道,不是么 ;p
相关热门文章
给主人留下些什么吧!~~
评论热议