内容简介:版权声明:本文为博主原创,无版权,未经博主允许可以随意转载,无需注明出处,随意修改或保持可作为原创! https://blog.csdn.net/dog250/article/details/89599592
版权声明:本文为博主原创,无版权,未经博主允许可以随意转载,无需注明出处,随意修改或保持可作为原创! https://blog.csdn.net/dog250/article/details/89599592
经理的皮鞋湿了,但是却没有变胖,所以经理的皮鞋是人造革的。
刚刚写了一篇文章:
不依赖OS编译器,不依赖库,用汇编/机器码直接编程: https://blog.csdn.net/dog250/article/details/89500153
展示了一个直接执行二进制指令文件的基本方案,基于 Linux 内核来执行。
值得一提的是,这不是什么特别有技术含量的东西,这只是一个基本功,我在2006年的长春吉林大学边上租住的房子里就玩过此法。那时是用VC 6。
大公司的 程序员 不会屑于写我这些淫巧,即便他们也不一定会,也不一定懂,他们只是太关注业务,也许是真的没时间,也许真的就是不屑,觉得这太简单。但是,我的意思就是,这些东西真的太简单,如果你不懂,那真的不是一个合格的程序员。
本文写一个 解释器 ,载入一个仅包含二进制指令的文件,然后执行,这非常简单。
有两种方法可以简单的改变程序的执行流:
- 通过替换函数调用的返回地址。
这是call指令提供的功能,call指令执行时,会将下一条指令压栈,我们只需要在栈里找到这个位置,将其替换为自己的指令即可。 - 直接通过内联汇编调用jmp指令执行自己的指令。
这个非常直接,超级简单。
首先看第一个方法,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
// 我们想直接执行这段指令,当然,它保存于某个文件,可以从文件里读出到code内存空间。
// char nop[] = {0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x48, 0x31, 0xff, 0x0f, 0x05};
unsigned char *code;
void exec()
{
unsigned long a, *p;
// 替换返回地址,使得exec返回的时候,跳转到我们的代码。
p = (void*)((long)&a + 24);
*p = (unsigned long)code;
}
int main(int argc, char **argv)
{
FILE *fp = NULL;
fp = fopen(argv[1], "r");
// 映射地址空间
code = (unsigned char*)mmap(0, 1024, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
//memcpy(code, nop, sizeof(nop));
// 将指令文件内容读取到code指示的地址空间。
fread(code, 1024, 1, fp);
// 执行之
exec();
printf("end\n");
}
接下来看看直接jmp的方式,依然是一个很简单的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
// 我们想直接执行这段指令,当然,它保存于某个文件,可以从文件里读出到code内存空间。
//char nop[] = {0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x48, 0x31, 0xff, 0x0f, 0x05};
unsigned char *code;
int main(int argc, char **argv)
{
FILE *fp = NULL;
fp = fopen(argv[1], "r");
code = (unsigned char*)mmap(0, 1024, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
// memcpy(code, nop, sizeof(nop));
fread(code, 1024, 1, fp);
asm ( "jmp %0"
:
:"r"(code)
:);
printf("end\n");
}
将上述的代码编译成一个比如a.out的程序,将一个二进制指令文件作为参数执行之,就会看到效果了。
我来准备一个二进制指令文件,以fork炸弹为例:
.global _start _start: mov $57, %rax # fork 炸弹 syscall jmp _start
照常编译:
[root@localhost ~]# as --64 -o forkbomb.o forkbomb.s [root@localhost myflat]# ld -melf_x86_64 -o forkbomb forkbomb.o --oformat=binary
然后将这个forkbomb作为参数执行a.out,试试看。
有人会说这样做没有内核方案直接。确实是的,毕竟我们无法直接在bash的命令提示符里输入forkbomb那般执行,但是想达到这个效果,这也不难啊。
你在命令提示符里输入的任何程序都是通过bash来执行的,我们把上述的a.out整个儿给塞进bash中不就OK了吗?在bash开始fork/exec新进程的时候,自己完成mmap,memcpy的事情,然后要么通过替换函数返回地址后主动return,要么直接内联汇编里jmp,不就OK了么。
非常简单!
请注意,埃里克.雷蒙德有枪!
皮鞋湿,不会胖!但是经理的皮鞋除外。埃里克.雷蒙德也不懂皮鞋,毕竟,第一次穿。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Music Recommendation and Discovery
Òscar Celma / Springer / 2010-9-7 / USD 49.95
With so much more music available these days, traditional ways of finding music have diminished. Today radio shows are often programmed by large corporations that create playlists drawn from a limited......一起来看看 《Music Recommendation and Discovery》 这本书的介绍吧!