├── ShellCode32 ├── shellcode.h ├── ShellCode32.vcxproj.user ├── ShellCode32.vcxproj.filters ├── ShellCode32.sln ├── ShellCode32.cpp └── ShellCode32.vcxproj ├── shellcode64 ├── GetModule.asm ├── shellcode64.h ├── shellcode64.vcxproj.user ├── shellcode64.vcxproj.filters ├── shellcode64.sln ├── shellcode64.cpp └── shellcode64.vcxproj ├── images └── cpp开发shellcode模板 │ ├── image-20231010114027186.png │ ├── image-20231010114101960.png │ ├── image-20231010133731851.png │ ├── image-20231010133759283.png │ └── image-20231010133816209.png └── README.md /ShellCode32/shellcode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/ShellCode32/shellcode.h -------------------------------------------------------------------------------- /shellcode64/GetModule.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/shellcode64/GetModule.asm -------------------------------------------------------------------------------- /shellcode64/shellcode64.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/shellcode64/shellcode64.h -------------------------------------------------------------------------------- /images/cpp开发shellcode模板/image-20231010114027186.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/images/cpp开发shellcode模板/image-20231010114027186.png -------------------------------------------------------------------------------- /images/cpp开发shellcode模板/image-20231010114101960.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/images/cpp开发shellcode模板/image-20231010114101960.png -------------------------------------------------------------------------------- /images/cpp开发shellcode模板/image-20231010133731851.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/images/cpp开发shellcode模板/image-20231010133731851.png -------------------------------------------------------------------------------- /images/cpp开发shellcode模板/image-20231010133759283.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/images/cpp开发shellcode模板/image-20231010133759283.png -------------------------------------------------------------------------------- /images/cpp开发shellcode模板/image-20231010133816209.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clownfive/CppDevShellcode/HEAD/images/cpp开发shellcode模板/image-20231010133816209.png -------------------------------------------------------------------------------- /ShellCode32/ShellCode32.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /shellcode64/shellcode64.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ShellCode32/ShellCode32.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 23 | 24 | 头文件 25 | 26 | 27 | -------------------------------------------------------------------------------- /shellcode64/shellcode64.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 23 | 24 | 源文件 25 | 26 | 27 | 28 | 29 | 头文件 30 | 31 | 32 | -------------------------------------------------------------------------------- /ShellCode32/ShellCode32.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.33529.622 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellCode32", "ShellCode32.vcxproj", "{3E3F5F91-09AE-46BA-967C-C518B71715A9}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Debug|x64.ActiveCfg = Debug|x64 17 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Debug|x64.Build.0 = Debug|x64 18 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Debug|x86.Build.0 = Debug|Win32 20 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Release|x64.ActiveCfg = Release|x64 21 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Release|x64.Build.0 = Release|x64 22 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Release|x86.ActiveCfg = Release|Win32 23 | {3E3F5F91-09AE-46BA-967C-C518B71715A9}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {B8ABB6FC-C1E2-4EFF-84BD-30566F716F26} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /shellcode64/shellcode64.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.33529.622 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shellcode64", "shellcode64.vcxproj", "{89EA323E-821A-4C99-97EB-80A5DE65F2AB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Debug|x64.ActiveCfg = Debug|x64 17 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Debug|x64.Build.0 = Debug|x64 18 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Debug|x86.ActiveCfg = Debug|Win32 19 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Debug|x86.Build.0 = Debug|Win32 20 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Release|x64.ActiveCfg = Release|x64 21 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Release|x64.Build.0 = Release|x64 22 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Release|x86.ActiveCfg = Release|Win32 23 | {89EA323E-821A-4C99-97EB-80A5DE65F2AB}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {6DE21609-A2A0-44FC-BC7E-C4B135FC449C} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /shellcode64/shellcode64.cpp: -------------------------------------------------------------------------------- 1 | #include "shellcode64.h" 2 | 3 | #include 4 | 5 | //这是shellcode的入口函数 6 | void ShellCodeEntry() 7 | { 8 | SCENV env; 9 | InitEnv(&env); 10 | 11 | char sz_hello[] = { 'h','e','l','l','o','\0' }; 12 | env.m_pfnMessageBoxA(NULL, sz_hello, sz_hello, MB_OK); 13 | //代码冲这开始写 14 | 15 | 16 | } 17 | 18 | void InitEnv(PSCENV pEnv) 19 | { 20 | char sz_MessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A','\0' }; 21 | char sz_LoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A','\0' }; 22 | char sz_GetProcAddress[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s','\0' }; 23 | char sz_user32[] = { 'u','s','e','r','3','2','\0' }; 24 | 25 | //拿kernel32的地址 26 | HMODULE hKernel32 = GetModuleKernel(); 27 | pEnv->m_pfnGetProcAddress = (PFN_GetProcAddress)MyGetProcAddress(hKernel32, sz_GetProcAddress); 28 | pEnv->m_pfnLoadLibraryA = (PFN_LoadLibraryA)pEnv->m_pfnGetProcAddress(hKernel32, sz_LoadLibraryA); 29 | 30 | 31 | HMODULE hUser32 = pEnv->m_pfnLoadLibraryA(sz_user32); 32 | pEnv->m_pfnMessageBoxA = (PFN_MessageBoxA)pEnv->m_pfnGetProcAddress(hUser32, sz_MessageBoxA); 33 | 34 | 35 | 36 | } 37 | 38 | int MyStrCmp(char* pDst, char* pSrc) 39 | { 40 | char* pDstTmp = pDst; 41 | char* pSrcTmp = pSrc; 42 | while (*pSrcTmp && *pDstTmp) 43 | { 44 | if (*pSrcTmp != *pDstTmp) 45 | { 46 | return *pDstTmp - *pSrcTmp; 47 | } 48 | pSrcTmp++; 49 | pDstTmp++; 50 | } 51 | 52 | return *pDstTmp - *pSrcTmp; 53 | } 54 | 55 | FARPROC MyGetProcAddress(HMODULE hModule, char* lpProcName) { 56 | IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hModule; 57 | IMAGE_NT_HEADERS64* pNtHeaders = (IMAGE_NT_HEADERS64*)((char*)pDosHeader + pDosHeader->e_lfanew); 58 | 59 | //LPVOID exports1 = (LPVOID)&(pNtHeaders->OptionalHeader.DataDirectory[0]); 60 | //DWORD exports2 = pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress; 61 | 62 | IMAGE_EXPORT_DIRECTORY* pExportDir = (IMAGE_EXPORT_DIRECTORY*)((char*)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 63 | 64 | DWORD* pAddressOfNames = (DWORD*)((char*)pDosHeader + pExportDir->AddressOfNames); 65 | WORD* pAddressOfOrdinals = (WORD*)((char*)pDosHeader + pExportDir->AddressOfNameOrdinals); 66 | DWORD* pAddressOfFunctions = (DWORD*)((char*)pDosHeader + pExportDir->AddressOfFunctions); 67 | 68 | for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) { 69 | LPCSTR pProcName = (LPCSTR)((char*)pDosHeader + pAddressOfNames[i]); 70 | if (MyStrCmp((char*)pProcName, lpProcName) == 0) { 71 | WORD ordinal = pAddressOfOrdinals[i]; 72 | DWORD functionRVA = pAddressOfFunctions[ordinal]; 73 | FARPROC functionPtr = (FARPROC)((char*)hModule + functionRVA); 74 | return functionPtr; 75 | } 76 | } 77 | return NULL; 78 | } -------------------------------------------------------------------------------- /ShellCode32/ShellCode32.cpp: -------------------------------------------------------------------------------- 1 | #include "shellcode.h" 2 | 3 | 4 | //函数入口点 5 | void ShellCodeOEP() 6 | { 7 | SCENV env; 8 | InitEnv(&env); 9 | 10 | char sz_hello[] = { 'h','e','l','l','o','\0' }; 11 | env.m_pfnMessageBoxA(NULL, sz_hello, sz_hello, MB_OK); 12 | 13 | } 14 | 15 | void InitEnv(PSCENV pEnv) 16 | { 17 | char sz_MessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A','\0' }; 18 | char sz_LoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A','\0' }; 19 | char sz_GetProcAddress[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s','\0' }; 20 | char sz_user32[] = { 'u','s','e','r','3','2','\0' }; 21 | 22 | 23 | 24 | //拿kernel32的地址 25 | HMODULE hKernel32 = GetKernel32Base(); 26 | pEnv->m_pfnGetProcAddress = (PFN_GetProcAddress)MyGetProcAddress(hKernel32, sz_GetProcAddress); 27 | pEnv->m_pfnLoadLibraryA = (PFN_LoadLibraryA)pEnv->m_pfnGetProcAddress(hKernel32, sz_LoadLibraryA); 28 | 29 | HMODULE hUser32 = pEnv->m_pfnLoadLibraryA(sz_user32); 30 | pEnv->m_pfnMessageBoxA = (PFN_MessageBoxA)pEnv->m_pfnGetProcAddress(hUser32, sz_MessageBoxA); 31 | 32 | 33 | 34 | } 35 | 36 | //拿kernel32模块基址 37 | HMODULE GetKernel32Base() 38 | { 39 | 40 | HMODULE hKer32 = NULL; 41 | __asm 42 | { 43 | mov eax, fs: [0x18] ; //TEB 44 | mov eax, [eax + 0x30]; //PEB 45 | mov eax, [eax + 0x0C];//_PEB_LDR_DATA 46 | mov eax, [eax + 0x0C]; // _LIST_ENTRY 主模块 47 | mov eax, [eax] 48 | mov eax, [eax] 49 | mov eax, dword ptr[eax + 0x18];// KERNEL32基址 50 | mov hKer32, eax 51 | 52 | } 53 | return hKer32; 54 | } 55 | 56 | int MyStrCmp(char* pDst, char* pSrc) 57 | { 58 | char* pDstTmp = pDst; 59 | char* pSrcTmp = pSrc; 60 | while (*pSrcTmp && *pDstTmp) 61 | { 62 | if (*pSrcTmp != *pDstTmp) 63 | { 64 | return *pDstTmp - *pSrcTmp; 65 | } 66 | pSrcTmp++; 67 | pDstTmp++; 68 | } 69 | 70 | return *pDstTmp - *pSrcTmp; 71 | } 72 | 73 | 74 | FARPROC MyGetProcAddress(HMODULE hDll, char* szFuncName) 75 | { 76 | if (hDll == NULL || szFuncName == NULL) 77 | { 78 | return NULL; 79 | } 80 | 81 | //处理pe头 82 | PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hDll; 83 | PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((int)hDll + (int)pDosHdr->e_lfanew); 84 | PIMAGE_OPTIONAL_HEADER pOptionHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHdr->OptionalHeader; //可选头 85 | 86 | 87 | PIMAGE_DATA_DIRECTORY pExportDir = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT; 88 | 89 | PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)(int)(pOptionHeader->DataDirectory[0].VirtualAddress + (int)hDll); 90 | 91 | 92 | PDWORD pdwAddressofNames = (PDWORD)(pExportTable->AddressOfNames + (int)hDll); //二级名称指针 93 | PWORD pdwAddressofNameOrdinals = (PWORD)(pExportTable->AddressOfNameOrdinals + (int)hDll); 94 | PDWORD pdwAddressOfFunc = (PDWORD)(pExportTable->AddressOfFunctions + (int)hDll); 95 | DWORD dwFuncCount = pExportTable->NumberOfFunctions; 96 | 97 | //名称获取函数地址 98 | for (int i = 0; i < (int)dwFuncCount; i++) 99 | { 100 | //获取名称地址 101 | char* pszName = (char*)(pdwAddressofNames[i] + (int)hDll); 102 | if (MyStrCmp(pszName, szFuncName) == 0) 103 | { 104 | DWORD dwIdx = pdwAddressofNameOrdinals[i]; // + pExportTable->Base 105 | //找到函数地址 106 | DWORD dwFunAddr = pdwAddressOfFunc[dwIdx] + (int)hDll; 107 | return FARPROC(dwFunAddr); 108 | 109 | } 110 | } 111 | return NULL; 112 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CppDevShellcode 2 | 3 | 4 | 5 | ## 前言: 6 | 7 | 网络上推荐开发shellcode是用Clang、或者python开发,有些博客直接用的汇编在写。 8 | 9 | 为了简化开发的难度,并且windows上还是主推Visual Studio写cpp。 10 | 11 | 所以就有了这个使用Visual Studio开发shellcode的项目。 12 | 13 | **开发基础:cpp、win32编程、pe结构、x64/x32汇编** 14 | 15 | 16 | 17 | ## 0x01 开发环境配置 18 | 19 | 1. 保证随机基址开启(VS默认开启随机基址) 20 | 2. Debug改成Release模式 (测试的时候也可以用debug,最后生成的时候改成Release就行) 21 | 3. 修改入口函数(不能使用默认的main函数,vs在调用main函数之前做了很多处理导致代码会出现**绝对地址**) 22 | 4. 关闭GS选项 23 | 5. 关闭优化 24 | 6. 使用静态库 25 | 26 | ### 图文 27 | 28 | 1)修改入口函数(32位) 29 | 30 | ![image-20231010133731851](images/cpp开发shellcode模板/image-20231010133731851.png) 31 | 32 | 2)关闭gs 33 | 34 | ![image-20231010133759283](images/cpp开发shellcode模板/image-20231010133759283.png) 35 | 36 | 3)关闭优化,调成静态库 37 | 38 | ![image-20231010133816209](images/cpp开发shellcode模板/image-20231010133816209.png) 39 | 40 | 41 | 42 | ### 64位环境配置 43 | 44 | 由于微软不给在64位cpp代码中插入汇编指令,并且所有调用约定都是FASTCALL。需要使用联合编译汇编才行 45 | 46 | 1. 新建一个name.asm文件(文件名不能和项目名一样) 47 | 2. 项目属性-》生成依赖项-》生成自定义 ----》吧masm选项勾上 48 | 3. 右键asm文件属性-》项目类型选择asm 49 | 50 | 图文: 51 | 52 | 1)项目生成依赖项 53 | 54 | ![image-20231010114101960](images/cpp开发shellcode模板/image-20231010114101960.png) 55 | 56 | 2)asm属性 57 | 58 | ![image-20231010114027186](images/cpp开发shellcode模板/image-20231010114027186.png) 59 | 60 | ----------------------- 61 | 62 | 63 | 64 | ## 0x02 拿kernel32模块基址 65 | 66 | fs寄存器中保存了tep和peb的地址, 67 | 68 | peb中保存了ldr结构体 69 | 70 | ``` 71 | HMODULE GetKernel32Base() 72 | { 73 | 74 | HMODULE hKer32 = NULL; 75 | __asm 76 | { 77 | mov eax, fs: [0x18] ; //TEB 78 | mov eax, [eax + 0x30]; //PEB 79 | mov eax, [eax + 0x0C];//_PEB_LDR_DATA 80 | mov eax, [eax + 0x0C]; // _LIST_ENTRY 主模块 81 | mov eax, [eax] 82 | mov eax, [eax] 83 | mov eax, dword ptr[eax + 0x18];// KERNEL32基址 84 | mov hKer32, eax 85 | 86 | } 87 | return hKer32; 88 | } 89 | ``` 90 | 91 | 92 | 93 | ## 0x03 自己实现GetProcAddress函数 94 | 95 | 自己实现GetProcAddress函数,去获取kernel32中的 LoadLibraryA 、GetProcAddress等函数地址 96 | 97 | 获取到函数地址之后转成函数指针调用。 98 | 99 | 原理: 100 | 101 | 1. 拿到kernel模块基址就是MZ的地址 102 | 1. 解析pe文件格式 103 | 1. 定位导出表 104 | 1. 找到指定导出表中函数名称 105 | 1. 再去拿指定函数的地址,并且返回 106 | 107 | 这里就不贴代码了,由于是自己实现的函数下文统称MyGetProcAddress。 108 | 109 | **注意:需要解析pe文件所以64位的和32位的MyGetProcAddress不通用。** 110 | 111 | 112 | 113 | ## 0x04 保存函数地址 114 | 115 | shellcode开发不能有绝对地址也就不能使用全局变量,所以需要一个结构体来保存函数指针。 116 | 117 | 函数调用的时候专递结构体指针就能拿到函数地址。 118 | 119 | 这里就新建一个头文件,把结构体和函数声明都放到这个头文件里面去 120 | 121 | ```hpp 122 | //windowsapi 函数指针声明 123 | typedef int (WINAPI* PFN_MessageBoxA)(HWND, LPCSTR, LPCSTR, UINT); 124 | typedef HMODULE(WINAPI* PFN_LoadLibraryA)(LPCSTR); 125 | typedef FARPROC(WINAPI* PFN_GetProcAddress)(HMODULE, LPCSTR); 126 | 127 | //存函数地址的结构体 128 | typedef struct SellcodeEvn 129 | { 130 | PFN_MessageBoxA m_pfnMessageBoxA; 131 | PFN_LoadLibraryA m_pfnLoadLibraryA; 132 | PFN_GetProcAddress m_pfnGetProcAddress; 133 | 134 | 135 | }SCENV, * PSCENV; 136 | 137 | //函数的声明 138 | EXTERN_C HMODULE GetModuleKernel(); 139 | FARPROC MyGetProcAddress(HMODULE hModule, char* lpProcName); 140 | ``` 141 | 142 | 143 | 144 | ## 0x05 拿api函数地址 145 | 146 | 1)MyGetProcAddress函数第一个参数是模块基址,第二个参数是函数名。 147 | 148 | 2)**不能有char*类型的变量**(否则会被放到数据区,产生绝对地址) 149 | 150 | 151 | 152 | ``` 153 | void InitEnv(PSCENV pEnv) 154 | { 155 | char sz_MessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A','\0' }; 156 | char sz_LoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A','\0' }; 157 | char sz_GetProcAddress[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s','\0' }; 158 | char sz_user32[] = { 'u','s','e','r','3','2','\0' }; 159 | 160 | //拿kernel32的地址 161 | HMODULE hKernel32 = GetModuleKernel(); 162 | pEnv->m_pfnGetProcAddress = (PFN_GetProcAddress)MyGetProcAddress(hKernel32, sz_GetProcAddress); 163 | pEnv->m_pfnLoadLibraryA = (PFN_LoadLibraryA)pEnv->m_pfnGetProcAddress(hKernel32, sz_LoadLibraryA); 164 | 165 | HMODULE hUser32 = pEnv->m_pfnLoadLibraryA(sz_user32); 166 | pEnv->m_pfnMessageBoxA = (PFN_MessageBoxA)pEnv->m_pfnGetProcAddress(hUser32, sz_MessageBoxA); 167 | } 168 | ``` 169 | 170 | PS:自己开发一个char* 转char数组的工具,以及api函数转函数指针。 **或者让GPT给你转也行。** 171 | 172 | 173 | 174 | ## 0x06 入口点调用函数完成自己的功能 175 | 176 | 入口函数之前不能放别的函数。第一个函数只能是入口函数。 177 | 178 | ``` 179 | //这是shellcode的入口函数 180 | void ShellCodeOEP() 181 | { 182 | SCENV env; //存放函数地址的结构体 183 | InitEnv(&env); //给结构体赋值函数地址 184 | 185 | //测试代码messageboxa 186 | char sz_hello[] = { 'h','e','l','l','o','\0' }; 187 | env.m_pfnMessageBoxA(NULL, sz_hello, sz_hello, MB_OK); 188 | //代码从这开始写 189 | 190 | 191 | } 192 | ``` 193 | 194 | 这里只做了一个messageboxa,需要什么功能照着模板写就是了 。 195 | 196 | 也可以先生成DEBUG版本的调试一下,无错误再生成Release版本。 197 | 198 | 用2进制编辑器打开生成的pe文件,拷贝.text节区的所有内容即可完成shellcode制作。 199 | 200 | 2进制编辑器 010Editor、winhex都行。 201 | 202 | 203 | 204 | ## 0x07 64位--汇编拿kernel32基址 205 | 206 | 需要联合编译,拿基址的汇编代码只能单独写到.asm 文件里面。联合编译在头文件里面定义函数声明调用。 207 | 208 | 209 | 210 | shellcode.asm 211 | 212 | ```asm 213 | .code 214 | GetModuleKernel proc 215 | xor r8, r8 216 | xor rax, rax 217 | xor r10, r10 218 | add r10, 60h 219 | mov rax, gs:[r10] ;通过GS寄存器获取PEB基址 220 | mov rax, [rax + 18h] ;获取PEB中Ldr数据结构的基址 221 | mov rax, [rax + 10h] ;获取Ldr数据结构的InmemoryOrderModuleList字段的基址 222 | mov rax, [rax] ;获取InmemoryOrderModuleList链表第一个节点 用这个取就是ntdll的基址 223 | mov rax, [rax] ;获取InmemoryOrderModuleList链表第一个节点 用这个就是kernen32的基址 224 | mov rax, [rax + 30h] ;获取节点中BaseAddress字段,既kernel32.dll的基址 225 | ret 226 | GetModuleKernel endp 227 | end 228 | ``` 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | ## 结语 237 | 238 | 有几个开发的注意事项。 239 | 240 | * 声明变量不要给初始值。 241 | * 入口函数在第一个。否则oep会在shellcode中间。 242 | * 存api函数地址不能使用全局变量,可以定义一个结构体来存放。 243 | * MyGetProcAddress 由于要解析pe头,所以32位和64位不通用。 244 | * strcmp、memcpy这种函数得自己实现, 可以去vc++6.0 里面拷贝。 245 | 246 | 生成完shellcode之后吧可执行文件丢到x64dbg里面去,f9运行到OEP往下翻一下,看看地址下面有没有横线。 247 | 248 | 出现横线就代表代码中出现了绝对地址的变量。 249 | 250 | 右键在内存窗口中转到,结合pdb符号文件找出哪个函数中出现的绝对地址。 251 | 252 | 253 | 254 | ## 特别鸣谢: 255 | 256 | wangda:https://github.com/wangda38 257 | 258 | 此项目参照好兄弟提供的upx壳代码shellcode部分二开。 259 | 260 | -------------------------------------------------------------------------------- /ShellCode32/ShellCode32.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {3e3f5f91-09ae-46ba-967c-c518b71715a9} 25 | ShellCode32 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | Disabled 106 | MultiThreaded 107 | false 108 | 109 | 110 | Console 111 | true 112 | true 113 | true 114 | ShellCodeOEP 115 | 116 | 117 | 118 | 119 | Level3 120 | true 121 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 122 | true 123 | 124 | 125 | Console 126 | true 127 | 128 | 129 | 130 | 131 | Level3 132 | true 133 | true 134 | true 135 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 136 | true 137 | MultiThreaded 138 | false 139 | 140 | 141 | Console 142 | true 143 | true 144 | true 145 | ShellCodeOEP 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /shellcode64/shellcode64.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {89ea323e-821a-4c99-97eb-80a5de65f2ab} 25 | shellcode64 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | 77 | 78 | false 79 | 80 | 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | Level3 89 | true 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | true 103 | true 104 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 105 | true 106 | 107 | 108 | Console 109 | true 110 | true 111 | true 112 | 113 | 114 | 115 | 116 | Level3 117 | true 118 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 119 | true 120 | 121 | 122 | Console 123 | true 124 | 125 | 126 | 127 | 128 | Level3 129 | true 130 | true 131 | true 132 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | false 135 | Disabled 136 | MultiThreaded 137 | 138 | 139 | Console 140 | true 141 | true 142 | true 143 | ShellCodeEntry 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | Document 152 | false 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | --------------------------------------------------------------------------------