├── 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 | 
31 |
32 | 2)关闭gs
33 |
34 | 
35 |
36 | 3)关闭优化,调成静态库
37 |
38 | 
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 | 
55 |
56 | 2)asm属性
57 |
58 | 
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 |
--------------------------------------------------------------------------------