首页
社区
课程
招聘
未解决 [求助]求大神帮忙看一下傀儡进程的问题
2020-6-7 09:19 3574

未解决 [求助]求大神帮忙看一下傀儡进程的问题

2020-6-7 09:19
3574

求大神帮忙看看我这段代码,意在利用傀儡进程加载我自己的程序

typedef long NTSTATUS;

typedef NTSTATUS (__stdcall *pfnZwUnmapViewOfSection)( 


        IN HANDLE ProcessHandle,    // 接收进程句柄
        IN LPVOID BaseAddress       // 接收基地址
        );

pfnZwUnmapViewOfSection ZwUnmapViewOfSection;

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    // TODO: Place code here.
    //加载ZwUnmapViewOfSection函数
    ZwUnmapViewOfSection = (pfnZwUnmapViewOfSection)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwUnmapViewOfSection");
    //读取文件最后一个节的地址

    CHAR szBuf[256] = "c:\\1.exe";
    ifstream infile;
    infile.open(szBuf, ios::in | ios::binary);
    if(!infile.is_open()){
        MessageBox(NULL, "文件打开失败", "信息", MB_OK);
        return 0;
    }
    //读取文件到缓冲区
    infile.seekg(0, ios::end);
    int fileSize = infile.tellg();
    infile.seekg(0, ios::beg);
    PBYTE buffer = new BYTE[fileSize];
    infile.read((char*)buffer, fileSize);
    infile.close();


    //为PE配置指针

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)buffer;
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(buffer + pDosHeader->e_lfanew);
    PIMAGE_SECTION_HEADER pSecHeader = (PIMAGE_SECTION_HEADER)((PBYTE)&pNtHeader->OptionalHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);


    PBYTE pBegin = buffer + pSecHeader[pNtHeader->FileHeader.NumberOfSections-1].PointerToRawData;

    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBegin;
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pBegin + pDos->e_lfanew);
    PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((PBYTE)&pNt->OptionalHeader + pNt->FileHeader.SizeOfOptionalHeader);


    //打开一个进程
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);

    DWORD dwFlag = ::CreateProcess(NULL, szBuf, NULL, NULL, FALSE, CREATE_SUSPENDED,NULL, NULL, &si, &pi);
    if(!dwFlag) {
        MessageBox(NULL, "进程创建失败", "信息", MB_OK);
        return 0;
    }
    //获取进程上下文
    CONTEXT ctx;
    ctx.ContextFlags = CONTEXT_FULL;
    if(!GetThreadContext(pi.hThread, &ctx)){
        MessageBox(NULL, "获取进程上下文失败", "信息", MB_OK);
        return 0;
    }

    //获取进程基址和入口
    DWORD entryPoint = ctx.Eax;
    char* BaseAddress = (char*)ctx.Ebx + 8;

    DWORD ImageBase;
    ReadProcessMemory(pi.hProcess, BaseAddress, &ImageBase, sizeof(DWORD), NULL);   

    ZeroMemory(szBuf,256);
    sprintf(szBuf, "%.8X", ImageBase);
    MessageBox(NULL, szBuf, "ImageBase", MB_OK);

    //卸载原来的镜像地址
    NTSTATUS flag = ZwUnmapViewOfSection(pi.hProcess, (LPVOID)ImageBase);
    if(flag < 0){
        MessageBox(NULL, "卸载原来的镜像地址失败", "信息", MB_OK);
        return 0;
    }


    //重新分配内存空间
    LPVOID newAddress = VirtualAllocEx(pi.hProcess, 
        &pNt->OptionalHeader.ImageBase,
        pNt->OptionalHeader.SizeOfImage,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE); 

    if(newAddress == NULL){
        MessageBox(NULL, "重新分配内存失败", "信息", MB_OK);
        return 0;
    }

//最后一个节的文件装载到内存
    //将信息写入到新的内存中


    PBYTE memBuffer = new BYTE[pNt->OptionalHeader.SizeOfImage];
    ZeroMemory(memBuffer, pNt->OptionalHeader.SizeOfImage);
    memcpy(memBuffer, pBegin, pNt->OptionalHeader.SizeOfHeaders);
    for (UINT i = 0; i < pNt->FileHeader.NumberOfSections; i++) {
        memcpy(memBuffer + pSec[i].VirtualAddress,
            pBegin + pSec[i].PointerToRawData,
            pSec[i].SizeOfRawData);
    }

    WriteProcessMemory(pi.hProcess,
        (LPVOID)pNt->OptionalHeader.ImageBase,
        memBuffer,
        pNt->OptionalHeader.SizeOfImage,
        NULL);

    //写CONTEXT
    DWORD newImageBase = (DWORD)pNt->OptionalHeader.ImageBase;
    ctx.Eax = newImageBase + pNt->OptionalHeader.AddressOfEntryPoint;
    WriteProcessMemory(pi.hProcess, BaseAddress, &newImageBase, 4, NULL);
    SetThreadContext(pi.hThread, &ctx);

    ResumeThread(pi.hThread);
    delete [] buffer;
    return 0;
}

其中 1.exe 是我已经将我自己的代码放到最后一个节中,这段代码运行希望可以把最后一个节的代码提出来并且运行,在WINDOWS Xp系统上可以运行,但是无效果(什么都不显示)
在WIN10 64位系统上会出现内存0x00000005的错误,求大神解答!!!调试了好久都没有调试出问题


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
打赏
分享
最新回复 (7)
雪    币: 30090
活跃值: (2117)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
bestbird 2020-6-7 13:54
2
0
几个要点:
1、不要卸载原来的内存ZwUnmapViewOfSection,否则注入后Ó¦ÓóÌÐòÎÞ·¨Õý³£Æô¶¯(0xc0000005)。
2、替换节的时候要判断是否为0,Win64下很多PE一些节为0.
3、
{$IFDEF WIN64}
  Context.Rcx := THandle(BaseAddress) + NTHeaders.OptionalHeader.AddressOfEntryPoint;
{$ELSE}
  Context.Eax := THandle(BaseAddress) + NTHeaders.OptionalHeader.AddressOfEntryPoint;

雪    币: 248
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
LimitLess 2020-6-7 19:20
3
0
bestbird 几个要点: 1、不要卸载原来的内存ZwUnmapViewOfSection,否则注入后Ó¦ÓóÌÐòÎÞ·¨Õý³£Æô¶¯(0xc0000005)。 2、替换节的时候要判断是否为0,Win64 ...
感谢回复,您说的节为0指的是节表还是说有一个全为0的节呢?
雪    币: 30090
活跃值: (2117)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
bestbird 2020-6-7 23:17
4
0

这个东西好像是很多年前的技术了,翻了一下以前的DEMO,我那个可能不大一样,是整个PE替换的。有些Win64 PE一些节是0字节。附件是编译后的BIN,无码,传上来的意思仅仅是让你确定傀儡进程是否可行而已。

上传的附件:
雪    币: 248
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
LimitLess 2020-6-9 23:02
5
0
bestbird 这个东西好像是很多年前的技术了,翻了一下以前的DEMO,我那个可能不大一样,是整个PE替换的。有些Win64 PE一些节是0字节。附件是编译后的BIN,无码,传上来的意思仅仅是让你确定傀儡进程是否可行 ...
感谢感谢,万分感谢!
雪    币: 248
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
LimitLess 2020-6-9 23:12
6
0
大佬,你的这个是可以用的,代码我检查了好几遍,我的这个就是运行之后没有效果。我编译得到时候是用x86选项编译的。
雪    币: 248
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
LimitLess 2020-6-9 23:13
7
0
bestbird 这个东西好像是很多年前的技术了,翻了一下以前的DEMO,我那个可能不大一样,是整个PE替换的。有些Win64 PE一些节是0字节。附件是编译后的BIN,无码,传上来的意思仅仅是让你确定傀儡进程是否可行 ...
大佬,你的这个是可以用的,代码我检查了好几遍,我的这个就是运行之后没有效果。我编译得到时候是用x86选项编译的。
雪    币: 482
活跃值: (5028)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
梦_魇 2023-7-18 03:11
8
0
我也遇到这问题了  我调试发现是VirtualAllocEx申请不到 pNt->OptionalHeader.ImageBase位置的内存  但是还没找到解决问题的办法  请问楼主是怎么解决的
游客
登录 | 注册 方可回帖
返回