📄 loader.c
字号:
return; } }}void KAsciiToUnicode(LPWSTR wchptr, LPBYTE chptr, int maxlen) { while ((maxlen-- > 1) && *chptr) { *wchptr++ = (WCHAR)*chptr++; } *wchptr = 0;}void KUnicodeToAscii(LPCHAR chptr, LPCWSTR wchptr, int maxlen) { while ((maxlen-- > 1) && *wchptr) { *chptr++ = (CHAR)*wchptr++; } *chptr = 0;}// Do imports from an exe/dll#define MAX_DLLNAME_LEN 32DWORD DoImports(e32_lite *eptr, o32_lite *oarry, ulong BaseAddr, ulong BaseAdj) { ulong blocksize; LPDWORD ltptr, atptr; PMODULE pMod; DWORD retval, loop; WCHAR ucptr[MAX_DLLNAME_LEN]; struct ImpHdr *blockptr, *blockstart; struct ImpProc *impptr; if (!(blocksize = eptr->e32_unit[IMP].size)) // No relocations return 0; blockstart = blockptr = (struct ImpHdr *)(BaseAddr+eptr->e32_unit[IMP].rva); while (blockptr->imp_lookup) { KAsciiToUnicode(ucptr,(LPCHAR)BaseAddr+blockptr->imp_dllname,MAX_DLLNAME_LEN); pMod = LoadOneLibraryPart2(ucptr,1,0); if (!pMod) { if (!(retval = GetLastError())) retval = ERROR_OUTOFMEMORY; while (blockstart != blockptr) { FreeLibraryByName((LPBYTE)BaseAddr+blockstart->imp_dllname); blockstart++; } return retval; } DEBUGMSG(ZONE_LOADER1,(TEXT("Doing imports from module %a (pMod %8.8lx)\r\n"), BaseAddr+blockptr->imp_dllname,pMod)); ltptr = (LPDWORD)(BaseAddr+blockptr->imp_lookup); atptr = (LPDWORD)(BaseAddr+blockptr->imp_address); while (*ltptr) { if (*ltptr & 0x80000000) retval = ResolveImpOrd(pMod,*ltptr&0x7fffffff); else { impptr = (struct ImpProc *)((*ltptr&0x7fffffff)+BaseAddr); retval = ResolveImpHintStr(pMod,impptr->ip_hint,(LPBYTE)impptr->ip_name); } if (*atptr != retval) { __try { *atptr = retval; } __except (EXCEPTION_EXECUTE_HANDLER) { // this is the case for the -optidata linker flag, where the idata is in the .rdata // section, and thus read-only o32_lite *dataptr; VirtualFree(atptr,4,MEM_DECOMMIT); for (loop = 0; loop < eptr->e32_objcnt; loop++) { dataptr = &oarry[loop]; if ((dataptr->o32_realaddr <= (DWORD)atptr) && (dataptr->o32_realaddr+dataptr->o32_vsize > (DWORD)atptr)) { dataptr->o32_access = PAGE_EXECUTE_READWRITE; break; } } if (loop == eptr->e32_objcnt) return ERROR_BAD_EXE_FORMAT; *atptr = retval; } } else DEBUGCHK(*atptr == retval); ltptr++; atptr++; } blockptr++; } return 0;}// Adjust permissions on regions, decommitting discardable onesBOOL AdjustRegions(e32_lite *eptr, o32_lite *oarry) { int loop; DWORD oldprot; for (loop = 0; loop < eptr->e32_objcnt; loop++) { if (oarry->o32_flags & IMAGE_SCN_MEM_DISCARDABLE) { VirtualFree((LPVOID)oarry->o32_realaddr,oarry->o32_vsize,MEM_DECOMMIT); oarry->o32_realaddr = 0; } else VirtualProtect((LPVOID)oarry->o32_realaddr,oarry->o32_vsize,oarry->o32_access,&oldprot); oarry++; } return TRUE;}BOOL GetNameFromOE(CEOIDINFO *pceoi, openexe_t *oeptr) { LPWSTR pstr; LPBYTE pbyte; BOOL retval = 1; __try { if (oeptr->filetype == FT_ROMIMAGE) { memcpy(pceoi->infFile.szFileName,L"\\Windows\\",9*sizeof(WCHAR)); pstr = &pceoi->infFile.szFileName[9]; pbyte = oeptr->tocptr->lpszFileName; while (*pbyte) *pstr++ = (WCHAR)*pbyte++; *pstr = 0; } else if (oeptr->bIsOID) { CEGUID sysguid; CREATE_SYSTEMGUID(&sysguid); if (!(CeOidGetInfoEx(&sysguid,oeptr->ceOid,pceoi)) || (pceoi->wObjType != OBJTYPE_FILE)) retval = 0; } else kstrcpyW(pceoi->infFile.szFileName,oeptr->lpName->name); } __except (EXCEPTION_EXECUTE_HANDLER) { retval = 0; } return retval;}BOOL ReopenExe(openexe_t *oeptr, LPCWSTR pExeName, BOOL bAllowPaging) { DWORD bytesread; BY_HANDLE_FILE_INFORMATION bhfi; if (!(oeptr->lpName = AllocName(MAX_PATH))) return 0; if ((oeptr->hf = CreateFileW(pExeName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0)) == INVALID_HANDLE_VALUE) { FreeName(oeptr->lpName); return 0; } oeptr->bIsOID = 1; oeptr->filetype = FT_OBJSTORE; if (GetFileInformationByHandle(oeptr->hf,&bhfi) && (bhfi.dwOID != (ULONG)INVALID_HANDLE_VALUE)) { FreeName(oeptr->lpName); oeptr->ceOid = bhfi.dwOID; } else { LPName pName; oeptr->bIsOID = 0; if (pName = AllocName((strlenW(pExeName)+1)*2)) { FreeName(oeptr->lpName); oeptr->lpName = pName; } kstrcpyW(oeptr->lpName->name,pExeName); } oeptr->pagemode = (bAllowPaging && !(pTOC->ulKernelFlags & KFLAG_DISALLOW_PAGING) && ReadFileWithSeek(oeptr->hf,0,0,0,0,0,0)) ? PM_FULLPAGING : PM_NOPAGING; if ((SetFilePointer(oeptr->hf,0x3c,0,FILE_BEGIN) != 0x3c) || !ReadFile(oeptr->hf,(LPBYTE)&oeptr->offset,4,&bytesread,0) || (bytesread != 4)) { CloseExe(oeptr); return 0; } return 1;}openexe_t globoe;BOOL globpageallowed;HANDLE JitOpenFile(LPCWSTR pName) { CALLBACKINFO cbi; cbi.hProc = ProcArray[0].hProc; cbi.pfn = (FARPROC)ReopenExe; cbi.pvArg0 = (LPVOID)&globoe; if (!PerformCallBack4Int(&cbi,pName,globpageallowed)) return INVALID_HANDLE_VALUE; if (globoe.filetype != FT_OBJSTORE) { CloseExe(&globoe); return INVALID_HANDLE_VALUE; } return globoe.hf;}void JitCloseFile(HANDLE hFile) { DEBUGCHK(globoe.hf == hFile); CloseExe(&globoe);}// Load E32 headerDWORD ModuleJit(LPCWSTR, LPWSTR, HANDLE *);// defined in kmisc.cextern BOOL fJitIsPresent;DWORD LoadE32(openexe_t *oeptr, e32_lite *eptr, DWORD *lpflags, DWORD *lpEntry, BOOL bIgnoreCPU, BOOL bAllowPaging, LPBYTE pbTrustLevel) { e32_exe e32; e32_exe *e32ptr; e32_rom *e32rptr; int bytesread; CEOIDINFO ceoi; CALLBACKINFO cbi;top: if (oeptr->filetype == FT_PPFSFILE) { DEBUGMSG(ZONE_LOADER1,(TEXT("PEBase at %8.8lx\r\n"),oeptr->offset)); if (rlseek(oeptr->hppfs,oeptr->offset,0) != (int)oeptr->offset) return ERROR_BAD_EXE_FORMAT; if (rread(oeptr->hppfs,(LPBYTE)&e32,sizeof(e32_exe)) != sizeof(e32_exe)) return ERROR_BAD_EXE_FORMAT; e32ptr = &e32; } else if (oeptr->filetype == FT_OBJSTORE) { DEBUGMSG(ZONE_LOADER1,(TEXT("PEBase at %8.8lx\r\n"),oeptr->offset)); if (SetFilePointer(oeptr->hf,oeptr->offset,0,FILE_BEGIN) != oeptr->offset) return ERROR_BAD_EXE_FORMAT; if (!ReadFile(oeptr->hf,(LPBYTE)&e32,sizeof(e32_exe),&bytesread,0) || (bytesread != sizeof(e32_exe))) return ERROR_BAD_EXE_FORMAT; e32ptr = &e32; } else { e32rptr = (struct e32_rom *)(oeptr->tocptr->ulE32Offset); eptr->e32_objcnt = e32rptr->e32_objcnt; if (lpflags) *lpflags = e32rptr->e32_imageflags; if (lpEntry) *lpEntry = e32rptr->e32_entryrva; eptr->e32_vbase = e32rptr->e32_vbase; eptr->e32_vsize = e32rptr->e32_vsize; if (e32rptr->e32_subsys == IMAGE_SUBSYSTEM_WINDOWS_CE_GUI) { eptr->e32_cevermajor = (BYTE)e32rptr->e32_subsysmajor; eptr->e32_ceverminor = (BYTE)e32rptr->e32_subsysminor; } else { eptr->e32_cevermajor = 1; eptr->e32_ceverminor = 0; } eptr->e32_stackmax = e32rptr->e32_stackmax; memcpy(&eptr->e32_unit[0],&e32rptr->e32_unit[0], sizeof(struct info)*LITE_EXTRA); eptr->e32_sect14rva = e32rptr->e32_sect14rva; eptr->e32_sect14size = e32rptr->e32_sect14size; return 0; } if (*(LPDWORD)e32ptr->e32_magic != 0x4550) return ERROR_BAD_EXE_FORMAT; if (!bIgnoreCPU && fJitIsPresent && e32ptr->e32_unit[14].rva) { if (GetNameFromOE(&ceoi,oeptr)) { DWORD dwRet; CloseExe(oeptr); globpageallowed = bAllowPaging; dwRet = ModuleJit(ceoi.infFile.szFileName,0,&oeptr->hf); switch (dwRet) { /* We use -1 in the case where ModuleJit is a stub or when the source file is not a CEF file. We want to behave as if the translator was never invoked since URT files will get dealt with in CreateNewProc, long after the CEF translators are done. */ case -1: break; case OEM_CERTIFY_FALSE: return NTE_BAD_SIGNATURE; case OEM_CERTIFY_TRUST: case OEM_CERTIFY_RUN: if (pbTrustLevel) *pbTrustLevel = (BYTE)dwRet; memcpy(oeptr,&globoe,sizeof(openexe_t)); goto top; default: cbi.hProc = ProcArray[0].hProc; cbi.pfn = (FARPROC)ReopenExe; cbi.pvArg0 = (LPVOID)oeptr; if (!PerformCallBack4Int(&cbi,ceoi.infFile.szFileName,bAllowPaging)) return ERROR_BAD_EXE_FORMAT; } } } if (!bIgnoreCPU && !e32ptr->e32_unit[14].rva && (e32ptr->e32_cpu != THISCPUID)) {#if defined(MIPS16SUPPORT) if (e32ptr->e32_cpu != IMAGE_FILE_MACHINE_MIPS16) return ERROR_BAD_EXE_FORMAT;#elif defined(THUMBSUPPORT) if (e32ptr->e32_cpu != IMAGE_FILE_MACHINE_THUMB) return ERROR_BAD_EXE_FORMAT;#else return ERROR_BAD_EXE_FORMAT;#endif } eptr->e32_objcnt = e32ptr->e32_objcnt; if (lpflags) *lpflags = e32ptr->e32_imageflags; if (lpEntry) *lpEntry = e32ptr->e32_entryrva; eptr->e32_vbase = e32ptr->e32_vbase; eptr->e32_vsize = e32ptr->e32_vsize; if (e32ptr->e32_subsys == IMAGE_SUBSYSTEM_WINDOWS_CE_GUI) { eptr->e32_cevermajor = (BYTE)e32ptr->e32_subsysmajor; eptr->e32_ceverminor = (BYTE)e32ptr->e32_subsysminor; } else { eptr->e32_cevermajor = 1; eptr->e32_ceverminor = 0; } if ((eptr->e32_cevermajor > 2) || ((eptr->e32_cevermajor == 2) && (eptr->e32_ceverminor >= 2))) eptr->e32_stackmax = e32ptr->e32_stackmax; else eptr->e32_stackmax = 64*1024; // backward compatibility if ((eptr->e32_cevermajor > CE_VERSION_MAJOR) || ((eptr->e32_cevermajor == CE_VERSION_MAJOR) && (eptr->e32_ceverminor > CE_VERSION_MINOR))) { return ERROR_OLD_WIN_VERSION; } eptr->e32_sect14rva = e32ptr->e32_unit[14].rva; eptr->e32_sect14size = e32ptr->e32_unit[14].size; memcpy(&eptr->e32_unit[0],&e32ptr->e32_unit[0], sizeof(struct info)*LITE_EXTRA); return 0;}BOOL PageInPage(openexe_t *oeptr, LPVOID pMem2, DWORD offset, o32_lite *o32ptr, DWORD size) { DWORD bytesread; BOOL retval = TRUE; DEBUGCHK(PagerCS.OwnerThread == hCurThread); LeaveCriticalSection(&PagerCS); if (oeptr->filetype == FT_PPFSFILE) { if ((o32ptr->o32_psize > offset) && (rreadseek(oeptr->hppfs,pMem2,min(o32ptr->o32_psize - offset,size),o32ptr->o32_dataptr + offset) != (int)min(o32ptr->o32_psize - offset, size))) retval = FALSE; } else if (oeptr->filetype == FT_OBJSTORE) { if ((o32ptr->o32_psize > offset) && (!ReadFileWithSeek(oeptr->hf,pMem2,min(o32ptr->o32_psize - offset,size),&bytesread,0,o32ptr->o32_dataptr + offset,0) || (bytesread != min(o32ptr->o32_psize - offset, size)))) retval = FALSE; } else { retval = FALSE; DEBUGCHK(0); } EnterCriticalSection(&PagerCS); return retval;}int PageInProcess(PPROCESS pProc, DWORD addr) { e32_lite *eptr = &pProc->e32; o32_lite *oarry = pProc->o32_ptr; o32_lite *optr; o32_rom *o32rp; openexe_t *oeptr = &pProc->oe; int loop; LPVOID pMem, pMem2; DWORD low, high, offset, zaddr, prevdw; BOOL retval = 2; MEMORY_BASIC_INFORMATION mbi; addr = addr & ~(PAGE_SIZE-1); zaddr = addr; for (loop = 0; loop < eptr->e32_objcnt; loop++) { optr = &oarry[loop]; low = optr->o32_realaddr; high = ((low + optr->o32_vsize) + (PAGE_SIZE-1))&~(PAGE_SIZE-1); if ((zaddr >= low) && (zaddr < high)) { offset = zaddr - low; if ((oeptr->filetype == FT_PPFSFILE) || (oeptr->filetype == FT_OBJSTORE)) { if (!(pMem = VirtualAlloc((LPVOID)ProcArray[0].dwVMBase,0x10000,MEM_RESERVE,PAGE_NOACCESS))) { DEBUGMSG(ZONE_PAGING,(L" PI: VA1 Failed!\r\n")); break; } pMem2 = ((LPVOID)((DWORD)pMem + ((low+offset)&0xffff))); if (!VirtualAlloc(pMem2,PAGE_SIZE,MEM_COMMIT,PAGE_EXECUTE_READWRITE)) { DEBUGMSG(ZONE_PAGING,(L" PI: VA Failed!\r\n")); VirtualFree(pMem,0,MEM_RELEASE); break; }#ifdef x86 if (offset < 4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -