使用C编译器编写shellcode

来源:互联网 发布:程序员 手机壁纸 编辑:程序博客网 时间:2024/05/06 15:33

准备工作

为了确保能生成可用作shellcode这样特定格式的代码,我们需要对Visual Studio做些特殊的配置。下面的各项配置,可能随编译器的变更而变更:

1、使用Release模式。近来编译器的Debug模式可能产生逆序的函数,并且会插入许多与位置相关的调用。

2、禁用优化。编译器会默认优化那些没有使用的函数,而那可能正是我们所需要的。

3、禁用栈缓冲区安全检查(/Gs)。在函数头尾所调用的栈检查函数,存在于二进制文件的某个特定位置,导致输出的函数不能重定位,这对shellcode是无意义的。

 

第一个shellcode

#include <stdio.h> void shell_code(){    for (;;)        ;} void __declspec(naked) END_SHELLCODE(void) {} int main(int argc, char *argv[]){    int sizeofshellcode = (int)END_SHELLCODE - (int)shell_code;     // Show some info about our shellcode buffer    printf("Shellcode starts at %p and is %d bytes long", shell_code. sizeofshellcode);     // Now we can test out the shellcode by calling it from C!    shell_code();     return 0;}

这里所示例的shellcode除了一个无限循环,啥事也没干。不过有一点是比较重要的————放在shell_code函数之后的END_SHELLCODE。有了这个,我们就能通过shell_code函数开头和END_SHELLCODE函数开头间的距离来确定shellcode的长度了。还有,C语言在这里所体现的好处就是我们能够把程序本身当作一段数据来访问,所以如果我们需要把shellcode写到另外一份文件中,仅需简单的调用fwrite(shell_code, sizeofshellcode, 1, filehandle)。

Visual Studio环境中,通过调用shell_code函数,借助IDE的调试技能,就可以很容易的调试shellcode了。

在上面所示的第一个小案例中,shellcode仅用了一个函数,其实我们可以使用许多函数。只是所有的函数需要连续地存放在shell_code函数和END_SHELLCODE函数之间,这是因为当在内部函数间调用时,call指令总是相对的。call指令的意思是“从距这里X字节的地方调用一个函数”。所以如果我们把执行call的代码和被调用的代码都拷贝到其他地方,同时又保证了它们间的相对距离,那么链接时就不会出岔子。

0 0
原创粉丝点击