Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建挂起的进程并在恢复之前重写其内存空间_C++_Windows_Assembly_64 Bit - Fatal编程技术网

C++ 创建挂起的进程并在恢复之前重写其内存空间

C++ 创建挂起的进程并在恢复之前重写其内存空间,c++,windows,assembly,64-bit,C++,Windows,Assembly,64 Bit,我正在分析以下代码(见下文): 在挂起状态下创建新进程(Create\u suspended) 使用pZwUnmapViewOfSection()取消映射内存空间 将新的PE映像(存储在程序中)写入内存空间 将RAX设置为流程的入口点 继续创建的进程 我想知道为什么这种方法有效 如果代码将PE映像写入新进程的“内存空间”,则加载程序不会运行以解析导入等,或者在加载程序执行其作业之前,CREATE\u已挂起 此外,EAX(或RAX)在PE可执行文件启动时是否始终保持其入口点 /* Create

我正在分析以下代码(见下文):

  • 在挂起状态下创建新进程(
    Create\u suspended
  • 使用
    pZwUnmapViewOfSection()
    取消映射内存空间
  • 将新的PE映像(存储在程序中)写入内存空间
  • 将RAX设置为流程的入口点
  • 继续创建的进程
我想知道为什么这种方法有效

如果代码将PE映像写入新进程的“内存空间”,则加载程序不会运行以解析导入等,或者在加载程序执行其作业之前,
CREATE\u已挂起

此外,EAX(或RAX)在PE可执行文件启动时是否始终保持其入口点

/* Create suspended process for program (using current module) */
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
if (CreateProcessA(szFileName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi) == FALSE) {
    Debug("[Debug] RunPE(): CreateProcessA(): (%lu)\n", GetLastError());
    return FALSE;
}

/* Get thread context (processor-specific register data) */
context.ContextFlags = CONTEXT_FULL;
if (GetThreadContext(pi.hThread, &context) == FALSE) {
    Debug("[Debug] RunPE(): GetThreadContext()");
}

/* Unmap memory space of program */
pZwUnmapViewOfSection = (PZUVOS)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwUnmapViewOfSection");
pZwUnmapViewOfSection(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase);

/* Allocate virtual memory for program */
lpAddress = VirtualAllocEx(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase, pinh->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (lpAddress == NULL) {
    Debug("[Debug] RunPE(): VirtualAllocEx(): (%lu)\n", GetLastError());
    return FALSE;
}

/* Write COFF, optional and section headers into virtual memory */
if (WriteProcessMemory(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase, fs->pBuffer, pinh->OptionalHeader.SizeOfHeaders, NULL) == FALSE) {
    Debug("[Debug] RunPE(): WriteProcessMemory(): (%lu)\n", GetLastError());
    return FALSE;
}

/* Write sections into virtual memory */
for (int i = 0; i < pinh->FileHeader.NumberOfSections; i++) {
    /* Compute section header of each section */
    pish = (PIMAGE_SECTION_HEADER)((DWORD)fs->pBuffer + pidh->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * i);
    /* Write section into virtual memory */
    WriteProcessMemory(pi.hProcess, (PVOID)(pinh->OptionalHeader.ImageBase + pish->VirtualAddress), (LPVOID)((DWORD)fs->pBuffer + pish->PointerToRawData), pish->SizeOfRawData, NULL);
}

/* Set entry-point as virtual address: address of entry point */
context.Rax = pinh->OptionalHeader.ImageBase + pinh->OptionalHeader.AddressOfEntryPoint;
if (SetThreadContext(pi.hThread, &context) == FALSE) {
    Debug("[Debug]: RunPE(): SetThreadContext(): (%lu)\n", GetLastError());
    return FALSE;
}
/*为程序创建挂起的进程(使用当前模块)*/
memset(&si,0,sizeof(si));
memset(&pi,0,sizeof(pi));
si.cb=sizeof(si);
if(CreateProcessA(szFileName,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi)==FALSE){
调试(“[Debug]RunPE():CreateProcessA():(%lu)\n”,GetLastError());
返回FALSE;
}
/*获取线程上下文(处理器特定寄存器数据)*/
context.ContextFlags=context_FULL;
if(GetThreadContext(pi.hThread,&context)==FALSE){
调试(“[Debug]RunPE():GetThreadContext()”;
}
/*取消映射程序的内存空间*/
pZwUnmapViewOfSection=(PZUVOS)GetProcAddress(GetModuleHandleA(“ntdll.dll”),“ZwUnmapViewOfSection”);
pZwUnmapViewOfSection(pi.hProcess,(PVOID)pinh->OptionalHeader.ImageBase);
/*为程序分配虚拟内存*/
lpAddress=VirtualAllocEx(pi.hProcess,(PVOID)pinh->OptionalHeader.ImageBase,pinh->OptionalHeader.SizeOfImage,MEM|u COMMIT | MEM|u RESERVE,PAGE|u EXECUTE_READWRITE);
if(lpAddress==NULL){
调试(“[Debug]RunPE():VirtualAllocEx():(%lu)\n”,GetLastError());
返回FALSE;
}
/*将COFF、可选和节头写入虚拟内存*/
if(WriteProcessMemory(pi.hProcess,(PVOID)pinh->OptionalHeader.ImageBase,fs->pBuffer,pinh->OptionalHeader.SizeOfHeaders,NULL)=FALSE){
调试(“[Debug]RunPE():WriteProcessMemory():(%lu)\n”,GetLastError());
返回FALSE;
}
/*将节写入虚拟内存*/
对于(int i=0;iFileHeader.NumberOfSections;i++){
/*计算每个节的节头*/
pish=(PIMAGE_SECTION_HEADER)((DWORD)fs->pBuffer+pidh->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i);
/*将节写入虚拟内存*/
写进程内存(pi.hProcess,(PVOID)(pinh->OptionalHeader.ImageBase+pish->VirtualAddress),(LPVOID)(DWORD)fs->pBuffer+pish->PointerToRawData),pish->SizeOfRawData,NULL);
}
/*将入口点设置为虚拟地址:入口点的地址*/
context.Rax=pinh->OptionalHeader.ImageBase+pinh->OptionalHeader.AddressOfEntryPoint;
if(SetThreadContext(pi.hThread,&context)==FALSE){
调试(“[Debug]:RunPE():SetThreadContext():(%lu)\n”,GetLastError());
返回FALSE;
}

pe导入等由ntdll在用户模式下完成。所有这些只有在线程恢复后才能开始执行。进程的入口点将在rcx寄存器中,而不是在rax中。无论如何,这段代码是不正确的,不是所有的功能,特别是异常处理等,都能正常工作,因为代码不在映像中section@RbMm-谢谢!装载机不负责装载进口货物吗?如果没有,PE导入是否可以通过恢复该过程来正常加载?您能否详细说明哪些功能不起作用?为什么异常处理不起作用?重新定位是否正确处理?是的,加载程序加载导入。这将在线程恢复后完成。加载程序将不处理exe的重新定位。现代异常处理将检查异常处理程序是否在映像部分。无论如何,代码是不正确的和功能性的。当您查看
A
api时-无法查看更多all@RbMm-但是复制了整个图像(标题+部分),那么问题出在哪里?为什么代码不起作用?如果不是装载机,谁负责搬迁?