我们编写一个最简单的shellcode加载工具,应用于将本地的shellcode文件执行起来。
shellcode加载器基本功能:
- 通过传入的参数,读取shellcode文件内容;
- 申请与shellcode文件大小相同的内存空间;
- 修改申请的内存,使其具备可读可写可执行的属性;
- 将shellcode文件内容读取到该内存;
- 调用shellcode执行(跳转到该内存首地址并执行)。
#include <stdio.h>
#include <windows.h>
int main(int argc, char* argv[])
{
// 程序运行时必须传入一个目标shellcode文件路径的参数
if (argc == 2)
{
// 读取传入的shellcode文件路径
HANDLE hSCFile = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hSCFile == INVALID_HANDLE_VALUE)
{
return 0;
}
DWORD dwHighSize = 0;
// 获取shellcode文件大小
DWORD dwFileSize = GetFileSize(hSCFile, &dwHighSize);
DWORD flOldProtect;
DWORD dwAlreadyRead = 0;
DWORD dwReadSum = 0;
// 分配堆空间
LPVOID g_pShellcode = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwFileSize);
// 将分配的内存设置为可读可写可执行的属性
VirtualProtect(g_pShellcode, dwFileSize, PAGE_EXECUTE_READWRITE, &flOldProtect);
// 读取shellcode文件内存到内存空间
ReadFile(hSCFile, (char*)g_pShellcode, dwFileSize, &dwAlreadyRead, NULL);
CloseHandle(hSCFile);
/* 以下方式调用shellcode用仅支持x86版本
_asm
{
pushad
call g_pShellcode
popad
}
*/
/* 以下方式调用shellcode能够x86和x64通用 */
typedef void (*FN_Shellcode)();
FN_Shellcode fn_Shellcode = (FN_Shellcode)g_pShellcode;
// 执行shellcode
fn_Shellcode();
puts("the shellcode operation is successful!");
system("pause");
}
else
{
puts("e.g: TestShellcode.exe <shellcode file path>");
system("pause");
}
}
两种运行方式:
-
直接将目标shellcode文件拖到加载器exe中执行:
-
通过cmd命令行方式:
如果有任何问题,可以在我们的知识社群中提问和沟通交流:
一个人走得再快,不如一群人走得更远!🤜🤛