-
-
未解决 [求助]傀儡进程问题
-
发表于: 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
被白小笑笑笑编辑
,原因:
赞赏
看原图
赞赏
雪币:
留言: