2010-06-20 50 views
2

我的功能:運行從內存下的過程/ C++

 /* 
--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_ 
runPE(
dosheader ptr, 
ntheader ptr, 
sectionheader ptr, 
ptr to exebuffer, 
DWORD SizeOfImage(Alignment fixed)) 
_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_--_-- 
*/ 

int runPE2(IMAGE_DOS_HEADER* pDOS,IMAGE_NT_HEADERS * pNT,IMAGE_SECTION_HEADER * pSection,char* pData,DWORD szImage) 
{ 
    STARTUPINFO si = {0}; 
    PROCESS_INFORMATION pi; 
    CONTEXT ctx; 

    if(CreateProcess(NULL,szFileName,NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si,&pi)) 
    { 
     ctx.ContextFlags = CONTEXT_FULL; 
     if(!GetThreadContext(pi.hThread,&ctx)) 
     { 
      MessageBoxA(0,"GetThreadContext Error!","Error",0); 
     } 
     DWORD dwImagebase = NULL; 
     DWORD dwBytesRead = NULL; 
     DWORD dwByteswritten = NULL; 
     DWORD dwOldProtection = NULL; 

     if(!ReadProcessMemory(pi.hProcess,(LPVOID)(ctx.Ebx + 8),&dwImagebase,sizeof(DWORD),&dwBytesRead)) 
     { 
      MessageBoxA(0,"RPM Error!","Error",0); 
     } 
     VirtualProtect(&pNT->OptionalHeader.ImageBase,sizeof(DWORD),PAGE_READWRITE,&dwOldProtection); 
     pNT->OptionalHeader.ImageBase = dwImagebase; 
     VirtualProtect(&pNT->OptionalHeader.ImageBase,sizeof(DWORD),dwOldProtection,&dwOldProtection); 


     UnmapViewOfSection_ pZwUnmapViewOfSection = (UnmapViewOfSection_)GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwUnmapViewOfSection"); 

     if(pZwUnmapViewOfSection(pi.hProcess, (LPVOID)dwImagebase) != 0) 
     { 
      MessageBoxA(0,"Unmaping Error!","Error",0); 
     } 

     void* newBase = VirtualAllocEx(pi.hProcess, (LPVOID)pNT->OptionalHeader.ImageBase,szImage, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
     if(!newBase) 
     { 
      MessageBoxA(0,"Allocting Error!","Error",0); 
     } 

     if(!WriteProcessMemory(pi.hProcess,(LPVOID)(ctx.Ebx + 8),newBase, sizeof(DWORD), &dwByteswritten)) 
     { 
      MessageBoxA(0,"WPM Imagebase Error!","Error",0); 
     } 

     if(!WriteProcessMemory(pi.hProcess,newBase,pData,pNT->OptionalHeader.SizeOfHeaders, &dwByteswritten)) 
     { 
      MessageBoxA(0,"WPM SizeOfHeaders Error!","Error",0); 
     } 

     for(int i = 0; i < pNT->FileHeader.NumberOfSections; i++) 
     { 
      pSection = (PIMAGE_SECTION_HEADER)((char*)(pData + pDOS->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * i)); 
      if(!WriteProcessMemory(pi.hProcess,(char*)(pNT->OptionalHeader.ImageBase + pSection->VirtualAddress),(char*)(pData + pSection->PointerToRawData),pSection->SizeOfRawData, &dwByteswritten)) 
      { 
       MessageBoxA(0,"WPM in LOOP Error!","Error",0); 
      } 
     } 

     ctx.Eax = (DWORD)newBase + pNT->OptionalHeader.AddressOfEntryPoint;  // eax holds new entry point 

     if(!SetThreadContext(pi.hThread,&ctx)) 
     { 
      MessageBoxA(0,"SetThreadContext Error!","Error",0); 
     } 

     if(!ResumeThread(pi.hThread)) 
     { 
      MessageBoxA(0,"ResumeThread Error!","Error",0); 
     } 

     CloseHandle(pi.hThread); 
     CloseHandle(pi.hProcess); 

     TerminateProcess(pi.hProcess,0); 

     return 1; 
    } 
    return -1; 
} 

ResumeThread後,我得到的錯誤是「應用程序無法正常啓動(0000005)

感謝您閱讀希望有人會幫

信息: OS:Win7的 編譯器VC++ 2010 目標應用;簡單的 「Hello World」 應用程序; Win32控制檯

+0

請修復您的縮進,您需要在源代碼框中的所有內容前面有四個空格。這是不可能的,因爲它是現在。 – 2010-06-20 18:53:10

+0

你從'ResumeThread'得到一個錯誤,或者在它返回之後?您可能在線程運行之前調用'TerminateThread'確實很快。 – 2010-06-20 18:57:27

+0

我在調試器中調試它,所以我不打電話給TerminateProcess – Simon 2010-06-20 19:04:19

回答

1

檢查VirtualProtect功能。似乎它已經失敗了。調用GetLastError()。我認爲這應該是值0x1e7。在「.text」部分查看您的基地址和地址。我通過手動處理導入表完成了這項工作。只需一個簡單的PE解析器和GetProcAddress函數即可。之後,您需要計算您的過程基地址並應用存儲在「.reloc」部分中的重定位。