• Day 3 学习代码注入技术


       劳逸结合,今天不做题。通过《逆向工程核心原理》学习一下代码注入技术。
       书中将代码注入与DLL注入做了区分。虽然二者都是通过创建远程线程来实现代码的运行,不同之处在于代码注入是只将程序指令与数据写入其他进程,而DLL注入是将整个DLL文件加载到目标进程内。从注入的代码量来看,代码注入更少。
        由于代码注入是将指令写入到其他进程中去,在执行时,需考虑到函数和参数的地址。这无形中增加了实现的复杂程度。同时,对于一些需要动态加密的代码更是如此。相反,DLL注入技术可以将全部的指令和数据在DLL中实现。
       下面,参照书中的示例,练习一下代码注入,进一步地,自己写一段加壳的代码,注入到远程进程中执行。
       第一步 按照书中的代码,实现弹窗口。      
    

    0x1 启动VS2019,创建空的一个控制台项目
    在这里插入图片描述
    生成x86平台的Release版可执行程序。
    在这里插入图片描述

        0x2 使用OllyDbg打开该程序。
       书中将EIP重定位到代码段起始地址,用OD尝试了一下,在保存时,总是失败。在代码段原来的入口附近,任意选择一个地址,直接输入汇编语句:
       push ebp
       mov ebp,esp
       mov esi,DWORD TPR SS:[EBP+8]
       push 6c6c
       push 642E3233
       push 72657375    ' 压入user32.dll
       push esp
       calll dword ptr ds:[esi]
       push 41786f
       push 42656761
       push 7373654d ‘压入MessageBoxA
       push esp
       push eax
       call dword ptr ds:[esi+4]   ’ GetProcAddress(),得到MessageBoxA的地址
       push 0
       call address1
       .......
       此处输入ascii:ReverseCore结尾添加\x00
       ...... 
       address1: call address2
       ......
       此处输入ascii:www.reversecore.com
       ......
      address2: push 0
      call eax
      xor eax,eax
      mov esp,ebp
      pop ebp
      retn
    

    此处有一个技巧:在call address1 指令执行时,会将下一个地址(ReverseCore字符串的地址)作为下一条指令的地址(函数返回地址)压入栈,实际上是将MessageBoxA的第三个参数压入了栈。
    由于此处的函数实际上并不是真正的函数,不会返回这个地址执行。它将在下一条之指令处继续跳转(即address1出的指令:call address2)。这条指令同样将下一个地址作为“返回地址”压入栈,实际是将MessageBoxA的第二个参数(www.reversecore.com)压入栈,然后在address2处执行push 0 ,将MessageBoxA的第一个参数压入栈,此时,eax是MessageBoxA函数的地址。
    0x3 在数据窗口中找到刚才输入汇编代码的区域,将十六进制数据复制到文本编辑器,转换为C语言数组格式
    在这里插入图片描述

    0x4 新建一个控制台项目,参考书中代码完成代码注入功能。

    #include 
    char shellcode[] = {
    	0x55,0x8B,0xEC,0x8B,0x75,0x08,0x68,0x6C,0x6C,0x00,
    	0x00,0x68,0x33,0x32,0x2E,0x64,0x68,0x75,0x73,0x65,
    	0x72,0x54,0xFF,0x16,0x68,0x6F,0x78,0x41,0x00,0x68,
    	0x61,0x67,0x65,0x42,0x68,0x4D,0x65,0x73,0x73,0x54,
    	0x50,0xFF,0x56,0x04,0x6A,0x00,0xE8,0x0c,0x00,0x00,
    	0x00,0x52,0x65,0x76,0x65,0x72,0x73,0x65,0x43,0x6F,
    	0x72,0x65,0x00,0xE8,0x14,0x00,0x00,0x00,0x77,0x77,
    	0x77,0x2E,0x72,0x65,0x76,0x65,0x72,0x73,0x65,0x63,
    	0x6F,0x72,0x65,0x2E,0x63,0x6F,0x6D,0x00,0x6A,0x00,
    	0xFF,0xD0,0x33,0xC0,0x8B,0xE5,0x5D,0xC3
    	};
    typedef struct _THREAD_PARAM {
    		FARPROC pFunc[2];
    }THREAD_PARAM,*PTHREAD_PARAM;
    BOOL InjectCode(DWORD dwPID)
    {
        HMODULE hMod = NULL;
        THREAD_PARAM param = { 0, };
        HANDLE hProcess = NULL;
        HANDLE hThread = NULL;
        LPVOID pRemoteBuf[2] = { 0, };
    
        hMod = GetModuleHandleA("kernel32.dll");
    param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
    param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
    pRemoteBuf[0] = VirtualAllocEx(hProcess, NULL, sizeof(THREAD_PARAM), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, pRemoteBuf[0], (LPVOID)¶m, sizeof(THREAD_PARAM), NULL);
    pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, pRemoteBuf[1], (LPVOID)&shellcode, sizeof(shellcode), NULL);
    hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1], pRemoteBuf[0], 0, NULL);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return TRUE;
    }
    
    int main(int argc,char* argv[])
    {
        DWORD dwPID = 0;
        dwPID = atoi(argv[1]);
        if (InjectCode(dwPID))
            printf("OK!\n");
        else
            printf("Failed!\n");
        getchar();
        return 0;
    }
    

    0x5 生成解决方案 经测试,该程序在32位的Windows 7 系统下可以执行,在64位的Windows 10系统下不能完成注入执行。64位程序函数的参数不通过栈传递,而是通过rcx,rdx,r8和r9寄存器。
    在这里插入图片描述

  • 相关阅读:
    04【Redis的持久化机制】
    QTableView右键显示菜单
    CC++ socket网络编程扫盲篇
    详解Spring Boot中@value的使用方式
    docker入门级详解
    研发效能DevOps: Ubuntu 部署 JFrog 制品库
    Dell EMC DMX4-950硬盘故障和电池故障更换
    mysql改造oracle,以及项目改造
    Java:ArrayList源码解析
    Swift data范围截取问题
  • 原文地址:https://blog.csdn.net/neuisf/article/details/127082384