⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 5 页
字号:
				while (blockptr->imp_lookup) {
					FreeLibraryByName((LPCHAR)pMod->BasePtr+blockptr->imp_dllname);
					blockptr++;
				}
			}
						FreeModuleMemory(pMod);
		}
		return TRUE;
	} else
		return FALSE;
}

BOOL FreeOneLibrary(PMODULE pMod, BOOL bCallEntry) {
	BOOL retval = FALSE;
	if (!InitBreadcrumbs())
		KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
	else {
		retval = FreeOneLibraryPart2(pMod, bCallEntry);
		FinishBreadcrumbs();
	}
	return retval;
}

// Decrement ref count on library, freeing if needed

void FreeLibraryByName(LPCHAR lpszName) {
	PMODULE pMod;
	LPWSTR pTrav1;
	LPBYTE pTrav2;
	for (pMod = pModList; pMod; pMod = pMod->pMod) {
		for (pTrav1 = pMod->lpszModName, pTrav2 = lpszName; *pTrav1 && (*pTrav1 == (WCHAR)*pTrav2); pTrav1++, pTrav2++)
			;
		if (*pTrav1 == (WCHAR)*pTrav2) {
			FreeOneLibraryPart2(pMod, 1);
			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 32

DWORD 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 ones

BOOL 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 header

DWORD ModuleJit(LPCWSTR, LPWSTR, HANDLE *);
// defined in kmisc.c
extern 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);
	Le

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -