首页
社区
课程
招聘
未解决 [求助]傀儡进程问题
发表于: 2020-7-24 09:45 1910

未解决 [求助]傀儡进程问题

2020-7-24 09:45
1910

我写了一个傀儡进程的代码,但是以不同的exe创建进程时,有时能跑起来,有时程序就直接运行错误了,是哪里有问题啊?

 

代码:

// 傀儡进程.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include "pe.h"
#include <Windows.h>
#include <stdio.h>


int main(int argc, char* argv[])
{


    typedef unsigned long(__stdcall *pfZwUnmapViewOfSection)(unsigned long, unsigned long);


    char pszError[256] = {0};


    char* ShowName = (char*)"d:/3.exe";
    char* RealName = (char*)"d:/1.exe";
    DWORD dwCode = 0;


//这里少了6条代码,老是提示携带了那个啥。
//就是定义了一个卸载函数指针,上下文变量,和创建进程需要的两个结构体
//并且初始化了必要参数





    //挂起方式创建进程
    //1是正常
    if (!CreateProcessA(ShowName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {

        sprintf(pszError, "错误码:%x", GetLastError());
        MessageBoxA(0, "创建进程失败了。", pszError, MB_OK);
        return 1;
    }

    //获取context
    if (!GetThreadContext(pi.hThread, &context)) {

        sprintf(pszError, "错误码:%x", GetLastError());
        MessageBoxA(0, "获取线程上下文错误。", pszError, MB_OK);
        return 1;
    }


    //读取原进程ImageBase

    DWORD dwImageBase = 0;
    ReadProcessMemory(pi.hProcess, (LPCVOID)(context.Ebx + 8), &dwImageBase, 4, NULL);


    //获取卸载函数,卸载外壳
    HMODULE m = LoadLibrary(TEXT("ntdll.dll"));
    if (m == NULL) {

        sprintf(pszError, "错误码:%x", GetLastError());
        MessageBoxA(0, "加载DLL失败。", pszError, MB_OK);
        return 1;
    }

    ZwUnmapViewOfSection = (pfZwUnmapViewOfSection)GetProcAddress(m, "ZwUnmapViewOfSection");
    //0是正常
    dwCode = ZwUnmapViewOfSection((DWORD)pi.hProcess, dwImageBase);


    LPVOID pFileBuff = LoadFileBuff(RealName);
    LPVOID pImageBuff = CopyFileBuffToImageBuff(pFileBuff);

    DWORD ImageBase = GetImageBase(pFileBuff);
    DWORD SizeOfImage = GetSizeOfImage(pFileBuff);
    DWORD OEP = GetOEP(pFileBuff);



    LPVOID pAllocAdd = NULL;
    for (DWORD i = 0x0;; i += 0x10000) {

        pAllocAdd = VirtualAllocEx(pi.hProcess, (LPVOID)(ImageBase + i), SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (pAllocAdd) {
            break;
        }

    }

    if ((DWORD)pAllocAdd != ImageBase) {
        //修复重定位表。
        RepairReloc(pFileBuff, (DWORD)pAllocAdd);
        ImageBase = (DWORD)pAllocAdd;

    }



    //复制到新创建的进程
    //1是正常
    if (!WriteProcessMemory(pi.hProcess, pAllocAdd, pImageBuff, SizeOfImage, NULL)) {

        sprintf(pszError, "错误码:%x", GetLastError());
        MessageBoxA(0, "写入ImageBuff失败", pszError, MB_OK);
        return 1;
    }


    //更改入口点和镜像基址
    context.Eax = ImageBase + OEP;
    //1是正常
    if (!WriteProcessMemory(pi.hProcess, (LPVOID)(context.Ebx + 8), &ImageBase, 4, NULL)) {

        sprintf(pszError, "错误码:%x", GetLastError());
        MessageBoxA(0, "写入ImageBase失败", pszError, MB_OK);
        return 1;
    }

    if (!SetThreadContext(pi.hThread, &context)) {

        sprintf(pszError, "错误码:%x", GetLastError());
        MessageBoxA(0, "写入eax失败", pszError, MB_OK);
        return 1;
    }


    //恢复进程
    ResumeThread(pi.hThread);

    dwCode = GetLastError();
    printf("主进程\n");
    //getchar();


    return 0;



}

pe.cpp

#include <Windows.h>
#include <string.h>
#include <stdio.h>
#include <CommCtrl.h>
#include "pe.h"

LPVOID LoadFileBuff(char* FileName) {
    FILE* pFile;
    DWORD FileSize;

    fopen_s(&pFile, FileName, "rb");
    fseek(pFile, 0, SEEK_END);
    FileSize = ftell(pFile);
    fseek(pFile, 0, SEEK_SET);

    LPVOID pFileBuff = malloc(FileSize);
    memset(pFileBuff, 0, FileSize);
    fread(pFileBuff, FileSize, 1, pFile);
    return pFileBuff;

}



//获取文件大小
DWORD GetFileSize(LPVOID pFileBuff) {
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuff + pDOSHeader->e_lfanew);
    PIMAGE_FILE_HEADER    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
    PIMAGE_OPTIONAL_HEADER pOPEHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionsHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOPEHeader + pFileHeader->SizeOfOptionalHeader);

    DWORD FileSize = (pSectionsHeader + pFileHeader->NumberOfSections - 1)->SizeOfRawData;
    return FileSize;

}


DWORD RVAToFOA(LPVOID pFileBuff, DWORD RVA) {
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuff + pDOSHeader->e_lfanew);
    PIMAGE_FILE_HEADER    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
    PIMAGE_OPTIONAL_HEADER pOPEHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionsHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOPEHeader + pFileHeader->SizeOfOptionalHeader);
    PIMAGE_DATA_DIRECTORY pDataDirectory = (PIMAGE_DATA_DIRECTORY)(pOPEHeader->DataDirectory);

    DWORD NumbersOfSection = pFileHeader->NumberOfSections;
    DWORD FOA = 0;

    if (RVA < pSectionsHeader->VirtualAddress) {
        return RVA;
    }

    if (RVA < (pSectionsHeader + NumbersOfSection - 1)->VirtualAddress) {
        for (int i = 0; i < (NumbersOfSection - 1); i++) {
            if ((pSectionsHeader + i)->VirtualAddress <= RVA && RVA < (pSectionsHeader + i + 1)->VirtualAddress) {

                FOA = (pSectionsHeader + i)->PointerToRawData + (RVA - (pSectionsHeader + i)->VirtualAddress);
                break;
            }
        }
    }
    else {
        FOA = (pSectionsHeader + NumbersOfSection - 1)->PointerToRawData + (RVA - (pSectionsHeader + NumbersOfSection - 1)->VirtualAddress);
    }


    return FOA;

}




//拉伸,返回ImageBuff
LPVOID CopyFileBuffToImageBuff(LPVOID pFileBuff) {
    LPVOID pImageBuff = NULL;
    DWORD FileSize;
    DWORD NumberOfSections;
    LPVOID src;
    LPVOID dst;

    //获取DOS 、NT、FIle、Optional Pe、节表地址
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuff + pDOSHeader->e_lfanew);
    PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
    PIMAGE_OPTIONAL_HEADER pOPEHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((DWORD)pOPEHeader + pFileHeader->SizeOfOptionalHeader);

    //申请内存
    FileSize = pOPEHeader->SizeOfImage;
    pImageBuff = malloc(FileSize);
    memset(pImageBuff, 0, FileSize);

    //复制各种头
    memcpy(pImageBuff, pFileBuff, pOPEHeader->SizeOfHeaders);

    //复制节区
    NumberOfSections = pFileHeader->NumberOfSections;
    for (int i = 0; i < NumberOfSections; i++) {
        src = (LPVOID)((DWORD)pFileBuff + (pSection + i)->PointerToRawData);
        dst = (LPVOID)((DWORD)pImageBuff + (pSection + i)->VirtualAddress);
        memcpy(dst, src, (pSection + i)->SizeOfRawData);
    }
    return pImageBuff;
}


DWORD GetImageBase(LPVOID pFileBuff) {
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuff + pDOSHeader->e_lfanew);
    PIMAGE_FILE_HEADER    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
    PIMAGE_OPTIONAL_HEADER pOPEHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);

    return pOPEHeader->ImageBase;
}


DWORD GetSizeOfImage(LPVOID pFileBuff) {
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuff + pDOSHeader->e_lfanew);
    PIMAGE_FILE_HEADER    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
    PIMAGE_OPTIONAL_HEADER pOPEHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionsHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOPEHeader + pFileHeader->SizeOfOptionalHeader);

    return pOPEHeader->SizeOfImage;
}


DWORD GetOEP(LPVOID pFileBuff) {
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuff + pDOSHeader->e_lfanew);
    PIMAGE_FILE_HEADER    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
    PIMAGE_OPTIONAL_HEADER pOPEHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionsHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOPEHeader + pFileHeader->SizeOfOptionalHeader);

    return pOPEHeader->AddressOfEntryPoint;
}


void RepairReloc(LPVOID pFileBuff, DWORD newImageBase) {
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuff + pDOSHeader->e_lfanew);
    PIMAGE_FILE_HEADER    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
    PIMAGE_OPTIONAL_HEADER pOPEHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionsHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOPEHeader + pFileHeader->SizeOfOptionalHeader);
    PIMAGE_DATA_DIRECTORY pDataDirectory = (PIMAGE_DATA_DIRECTORY)(pOPEHeader->DataDirectory);
    PDWORD pRelocationTab = (PDWORD)((DWORD)pFileBuff + RVAToFOA(pFileBuff, (pDataDirectory + IMAGE_DIRECTORY_ENTRY_BASERELOC)->VirtualAddress));

    //没有重定位表
    if (pRelocationTab == pFileBuff) {
        return;
    }

    DWORD OldImageBase = pOPEHeader->ImageBase;
    DWORD Offset = 0;
    DWORD RelocationTabSize = (pDataDirectory + IMAGE_DIRECTORY_ENTRY_BASERELOC)->Size;
    DWORD AddrNum = 0;
    PWORD pAddr;

    if (RelocationTabSize) {
        while (RelocationTabSize) {
            //判断重定向表是否已经结束  ?结束条件有问题。最后指向的地址并不是 8个字节的0
            //if (*pRelocation == 0 && *(pRelocation + 1) == 0) {
            //    break;
            //}

            AddrNum = (*(pRelocationTab + 1) - 8) / 2;
            pAddr = (PWORD)((DWORD)pRelocationTab + 8);
            for (int i = 0; i < AddrNum; i++) {

                //printf("地址:%x  属性:%d\n", *pRelocationTab + ((*(pAddr + i)) & 0x0FFF), *(pAddr + i) >> 12);
                if (*(pAddr + i) >> 12 == 3) {
                    //rva
                    Offset = *pRelocationTab + ((*(pAddr + i)) & 0x0FFF);
                    //要修改的地址
                    *((PDWORD)((DWORD)pFileBuff + RVAToFOA(pFileBuff, Offset))) = *((PDWORD)((DWORD)pFileBuff + RVAToFOA(pFileBuff, Offset))) - OldImageBase + newImageBase;
                }
            }

            RelocationTabSize -= *(pRelocationTab + 1);
            //指向下一个重定向块
            pRelocationTab = (PDWORD)((DWORD)pRelocationTab + *(pRelocationTab + 1));


        }
    }
    else {

        while (true) {
            //判断重定向表是否已经结束  ?结束条件有问题。最后指向的地址并不是 8个字节的0
            if (*pRelocationTab == 0 && *(pRelocationTab + 1) == 0) {
                break;
            }

            AddrNum = (*(pRelocationTab + 1) - 8) / 2;
            pAddr = (PWORD)((DWORD)pRelocationTab + 8);
            for (int i = 0; i < AddrNum; i++) {

                //printf("地址:%x  属性:%d\n", *pRelocationTab + ((*(pAddr + i)) & 0x0FFF), *(pAddr + i) >> 12);
                if (*(pAddr + i) >> 12 == 3) {
                    //rva
                    Offset = *pRelocationTab + ((*(pAddr + i)) & 0x0FFF);
                    //要修改的地址
                    *((PDWORD)((DWORD)pFileBuff + RVAToFOA(pFileBuff, Offset))) = *((PDWORD)((DWORD)pFileBuff + RVAToFOA(pFileBuff, Offset))) - OldImageBase + newImageBase;
                }
            }

            //指向下一个重定向块
            pRelocationTab = (PDWORD)((DWORD)pRelocationTab + *(pRelocationTab + 1));
        }
    }


}

以3.exe文件创建程序,启动失败。
图片描述

 

以1.exe文件创建程序,启动成功。
图片描述

 

3.exe是从一个网站工具里面复制出来的notepad.exe
1.exe是一个小葵编码工具。
这是什么问题啊?


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-7-24 09:46 被白小笑笑笑编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//