ShellCode开发
1.基本没人教的花活,网上会有文章,但是不会解释原理。这玩意其实难度不高,就是要注意的东西多。
2.shellcode开发其实有很多办法,纯汇编,C和汇编又或者纯C++。(像我这种纯FW只能纯C++了)
开发PIC shellcode注意事项
1.不能使用全局变量,或者用static修饰的变量·使用API时必须动态调用(GetProAddress)·确保调自定义shellcode入口点
2.·用API之前已经加载了与之对应的DLL
3.·所有字符串都必须要用字符串数组的方式替代
·属性——优化——O1/Ob2/Oi/Os/Oy/GL·
属性——代码生成———MT/GS-/GY·
属性——链接器——/INCREMENTAL:NO·
属性——链接器——调试——否
·属性——链接器——高级——入口点(自定义)
所有字符串都要用类似的格式去定义 unsigned char szUser32[] = { ‘u’,’s’,’e’,’r’,’3’,’2’,’.’,’d’,’l’,’l’,0 };防止破坏堆栈平衡
先看代码吧,代码是删减版只有模板
一个头文件comm.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <windows.h>
typedef FARPROC(WINAPI* FN_GetProcAddress)( _In_ HMODULE hModule, _In_ LPCSTR lpProcName );
typedef HMODULE(WINAPI* FN_LoadLibraryA)( _In_ LPCSTR lpLibFileName );
typedef int(WINAPI* FN_MessageBoxA)( _In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType);
typedef UINT(WINAPI* FN_WinExec)( LPCSTR lpCmdLine, UINT uCmdShow );
typedef HANDLE(WINAPI * FN_CreateFileMappingW)( _In_ HANDLE hFile, _In_opt_ LPSECURITY_ATTRIBUTES lpFileMappingAttributes, _In_ DWORD flProtect, _In_ DWORD dwMaximumSizeHigh, _In_ DWORD dwMaximumSizeLow, _In_opt_ LPCWSTR lpName );
typedef struct tagApiInterface { FN_GetProcAddress pfnGetProcAddress; FN_LoadLibraryA pfnLoadLibrary; FN_MessageBoxA pfnMessageBoxA; FN_WinExec pfnWinExec; FN_CreateFileMappingW pfnCreateFileMappingW; }APIINTERFACE, * PAPIINTERFACE;
|
然后是function.h,一般存放一些自实现的函数,我把我的删掉了
1 2 3 4 5 6 7 8
| #include "comm.h" #include <windows.h> #include <iostream> #include <vector> #include <cstdint> using namespace std;
|
最后是最重要的,注意看注释。
大概的思路:通过PEB(不知道是啥玩意的自己去补基础)去获取Kernel32.dll的地址,从Kernel32.dll中获取导出函数GetProcAddress,再通过GetProcAddress函数获取LoadLibraryA函数。就可以实现从任意DLL中获取任意导出函数进行编程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include "comm.h" #include <winternl.h> #include "function.h"
ULONGLONG GetModuleKernel64() { ULONGLONG dwKernel32Addr = 0;
_TEB* pTeb = NtCurrentTeb(); PULONGLONG pPeb = (PULONGLONG) * (PULONGLONG)((ULONGLONG)pTeb + 0x60); PULONGLONG pLdr = (PULONGLONG) * (PULONGLONG)((ULONGLONG)pPeb + 0x18); PULONGLONG pInLoadOrderModuleList = (PULONGLONG)((ULONGLONG)pLdr + 0x10);
PULONGLONG pModuleExe = (PULONGLONG)*pInLoadOrderModuleList;
PULONGLONG pModuleNtdll = (PULONGLONG)*pModuleExe;
PULONGLONG pModuleKernel32 = (PULONGLONG)*pModuleNtdll;
dwKernel32Addr = pModuleKernel32[6];
return dwKernel32Addr; }
FARPROC getProcAddress(HMODULE hModuleBase) { PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hModuleBase; PIMAGE_NT_HEADERS64 lpNtHeader = (PIMAGE_NT_HEADERS64)((ULONG64)hModuleBase + lpDosHeader->e_lfanew); if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) { return NULL; } if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) { return NULL; } PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((ULONG64)hModuleBase + (ULONG64)lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); PDWORD lpdwFunName = (PDWORD)((ULONG64)hModuleBase + (ULONG64)lpExports->AddressOfNames); PWORD lpword = (PWORD)((ULONG64)hModuleBase + (ULONG64)lpExports->AddressOfNameOrdinals); PDWORD lpdwFunAddr = (PDWORD)((ULONG64)hModuleBase + (ULONG64)lpExports->AddressOfFunctions);
DWORD dwLoop = 0; FARPROC pRet = NULL; for (; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++) { char* pFunName = (char*)(lpdwFunName[dwLoop] + (ULONG64)hModuleBase); if (pFunName[0] == 'G' && pFunName[1] == 'e' && pFunName[2] == 't' && pFunName[3] == 'P' && pFunName[4] == 'r' && pFunName[5] == 'o' && pFunName[6] == 'c' && pFunName[7] == 'A' && pFunName[8] == 'd' && pFunName[9] == 'd' && pFunName[10] == 'r' && pFunName[11] == 'e' && pFunName[12] == 's' && pFunName[13] == 's') { pRet = (FARPROC)(lpdwFunAddr[lpword[dwLoop]] + (ULONG64)hModuleBase); break; } } return pRet; }
void EntryMain() { APIINTERFACE Api;
HMODULE hKernel32 = (HMODULE)GetModuleKernel64();
Api.pfnGetProcAddress = (FN_GetProcAddress)getProcAddress(hKernel32);
char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 }; Api.pfnLoadLibrary = (FN_LoadLibraryA)Api.pfnGetProcAddress(hKernel32, szLoadLibraryA);
|
GinTvT