📄 loader.c
字号:
case IMAGE_REL_BASED_LOW: // Low - (16-bit) relocate high part too. if (MatchedReflo) { FixupValue = (DWORD)(long)((*FixupAddressHi) << 16) + *(LPWORD)FixupAddress + offset; *FixupAddressHi = (short)((FixupValue + 0x8000) >> 16); MatchedReflo = FALSE; } else FixupValue = *(short *)FixupAddress + offset; *(LPWORD)FixupAddress = (WORD)(FixupValue & 0xffff); break; case IMAGE_REL_BASED_HIGHLOW: // Word - (32-bits) relocate the entire address. if ((DWORD)FixupAddress & 0x3) *(UNALIGNED DWORD *)FixupAddress += (DWORD)offset; else *FixupAddress += (DWORD)offset; break; case IMAGE_REL_BASED_HIGHADJ: // 32 bit relocation of 16 bit high word, sign extended DEBUGMSG(ZONE_LOADER2,(TEXT("Grabbing extra data %8.8lx\r\n"),*(currptr+1))); *(LPWORD)FixupAddress += (WORD)((*(short *)(++currptr)+offset+0x8000)>>16); break; case IMAGE_REL_BASED_MIPS_JMPADDR: // jump to 26 bit target (shifted left 2) FixupValue = ((*FixupAddress)&0x03ffffff) + (offset>>2); *FixupAddress = (*FixupAddress & 0xfc000000) | (FixupValue & 0x03ffffff); break;#if defined(MIPS16SUPPORT) case IMAGE_REL_BASED_MIPS_JMPADDR16: // MIPS16 jal/jalx to 26 bit target (shifted left 2) FixupValue = (*(LPWORD)FixupAddress) & 0x03ff; FixupValue = (((FixupValue >> 5) | ((FixupValue & 0x1f) << 5)) << 16) | *((LPWORD)FixupAddress+1); FixupValue += offset >> 2; *((LPWORD)FixupAddress+1) = (WORD)(FixupValue & 0xffff); FixupValue = (FixupValue >> 16) & 0x3ff; *(LPWORD)FixupAddress = (WORD) ((*(LPWORD)FixupAddress & 0x1c00) | (FixupValue >> 5) | ((FixupValue & 0x1f) << 5)); break;#endif default : DEBUGMSG(ZONE_LOADER1,(TEXT("Not doing fixup type %d\r\n"),*currptr>>12)); DEBUGCHK(0); break; } DEBUGMSG(ZONE_LOADER2,(TEXT("reloc complete, new op %8.8lx\r\n"),*FixupAddress)); currptr++; } blockptr = (struct info *)(((ulong)blockptr)+blockptr->size); } return TRUE;}DWORD ResolveImpOrd(PMODULE pMod, DWORD ord);DWORD ResolveImpStr(PMODULE pMod, LPCSTR str);DWORD ResolveImpHintStr(PMODULE pMod, DWORD hint, LPCHAR str);#define MAX_AFE_FILESIZE 32DWORD Katoi(LPCHAR str) { DWORD retval = 0; while (*str) { retval = retval * 10 + (*str-'0'); str++; } return retval;}// Get address from export entryDWORD AddrFromEat(PMODULE pMod, DWORD eat) { WCHAR filename[MAX_AFE_FILESIZE]; PMODULE pMod2; LPCHAR str; int loop; if ((eat < pMod->e32.e32_unit[EXP].rva) || (eat >= pMod->e32.e32_unit[EXP].rva + pMod->e32.e32_unit[EXP].size)) return eat+ (pMod->DbgFlags & DBG_IS_DEBUGGER ? (DWORD)pMod->BasePtr : ZeroPtr(pMod->BasePtr)); else { str = (LPCHAR)(eat + (ulong)pMod->BasePtr); for (loop = 0; loop < MAX_AFE_FILESIZE-1; loop++) if ((filename[loop] = (WCHAR)*str++) == (WCHAR)'.') break; filename[loop] = 0; if (!(pMod2 = LoadOneLibraryPart2(filename,1,0))) return 0; if (*str == '#') return ResolveImpOrd(pMod2,Katoi(str)); else return ResolveImpStr(pMod2,str); }}// Get address from ordinalDWORD ResolveImpOrd(PMODULE pMod, DWORD ord) { struct ExpHdr *expptr; LPDWORD eatptr; DWORD hint; DWORD retval; if (!pMod->e32.e32_unit[EXP].rva) return 0; expptr = (struct ExpHdr *)((ulong)pMod->BasePtr+pMod->e32.e32_unit[EXP].rva); eatptr = (LPDWORD)(expptr->exp_eat + (ulong)pMod->BasePtr); hint = ord - expptr->exp_ordbase; retval = (hint >= expptr->exp_eatcnt ? 0 : AddrFromEat(pMod,eatptr[hint]));// ERRORMSG(!retval,(TEXT("Can't find ordinal %d in module %s\r\n"),ord,pMod->lpszModName)); return retval;}// Get address from stringDWORD ResolveImpStr(PMODULE pMod, LPCSTR str) { struct ExpHdr *expptr; LPCHAR *nameptr; LPDWORD eatptr; LPWORD ordptr; DWORD retval; ulong loop; if (!pMod->e32.e32_unit[EXP].rva) return 0; expptr = (struct ExpHdr *)((ulong)pMod->BasePtr+pMod->e32.e32_unit[EXP].rva); nameptr = (LPCHAR *)(expptr->exp_name + (ulong)pMod->BasePtr); eatptr = (LPDWORD)(expptr->exp_eat + (ulong)pMod->BasePtr); ordptr = (LPWORD)(expptr->exp_ordinal + (ulong)pMod->BasePtr); for (loop = 0; loop < expptr->exp_namecnt; loop++) if (!strcmp(str,nameptr[loop]+(ulong)pMod->BasePtr)) break; if (loop == expptr->exp_namecnt) retval = 0; else retval = (loop >= expptr->exp_eatcnt ? 0 : AddrFromEat(pMod,eatptr[ordptr[loop]]));// ERRORMSG(!retval,(TEXT("Can't find import %a in module %s\r\n"),str,pMod->lpszModName)); return retval;}// Get address from hint and stringDWORD ResolveImpHintStr(PMODULE pMod, DWORD hint, LPCHAR str) { struct ExpHdr *expptr; LPCHAR *nameptr; LPDWORD eatptr; LPWORD ordptr; DWORD retval; if (!pMod->e32.e32_unit[EXP].rva) return 0; expptr = (struct ExpHdr *)((ulong)pMod->BasePtr+pMod->e32.e32_unit[EXP].rva); nameptr = (LPCHAR *)(expptr->exp_name + (ulong)pMod->BasePtr); eatptr = (LPDWORD)(expptr->exp_eat + (ulong)pMod->BasePtr); ordptr = (LPWORD)(expptr->exp_ordinal + (ulong)pMod->BasePtr); if ((hint >= expptr->exp_namecnt) || (strcmp(str,nameptr[hint] + (ulong)pMod->BasePtr))) retval = ResolveImpStr(pMod,str); else retval = AddrFromEat(pMod,eatptr[ordptr[hint]]);// ERRORMSG(!retval,(TEXT("Can't find import %a (hint %d) in %s\r\n"),str,hint,pMod->lpszModName)); return retval;}// Increment process reference count to module, return old countWORD IncRefCount(PMODULE pMod) { if (!(pMod->inuse & (1<<pCurProc->procnum))) { pMod->inuse |= (1<<pCurProc->procnum); pMod->calledfunc &= ~(1<<pCurProc->procnum); } return pMod->refcnt[pCurProc->procnum]++;}// Decrement process reference count to module, return new countWORD DecRefCount(PMODULE pMod) { if (!(--pMod->refcnt[pCurProc->procnum])) pMod->inuse &= ~(1<<pCurProc->procnum); return pMod->refcnt[pCurProc->procnum];}typedef BOOL (*entry_t)(HANDLE,DWORD,LPVOID);typedef BOOL (*comentry_t)(HANDLE,DWORD,LPVOID,LPVOID,DWORD,DWORD);// Remove module from linked listvoid UnlinkModule(PMODULE pMod) { PMODULE ptr1, ptr2; EnterCriticalSection(&ModListcs); if (pModList == pMod) pModList = pMod->pMod; else if (pModList) { ptr1 = pModList; ptr2 = pModList->pMod; while (ptr2 && (ptr2 != pMod)) { ptr1 = ptr2; ptr2 = ptr2->pMod; } if (ptr2) ptr1->pMod = ptr2->pMod; } LeaveCriticalSection(&ModListcs);}// Unmap module from processvoid UnCopyRegions(PMODULE pMod) { long basediff = pCurProc->dwVMBase - ProcArray[0].dwVMBase; VirtualFree((LPVOID)((long)pMod->BasePtr+basediff),pMod->e32.e32_vsize,MEM_DECOMMIT|0x80000000); VirtualFree((LPVOID)((long)pMod->BasePtr+basediff),0,MEM_RELEASE);}void FreeModuleMemory(PMODULE pMod) { UnlinkModule(pMod); VirtualFree(pMod->BasePtr,pMod->e32.e32_vsize,MEM_DECOMMIT|0x80000000); if (ZeroPtr(pMod->BasePtr) < pTOC->dllfirst) VirtualFree(pMod->BasePtr,0,MEM_RELEASE); if ((ZeroPtr(pMod->BasePtr) > ZeroPtr(pMod->lpszModName)) || (ZeroPtr(pMod->BasePtr) + pMod->e32.e32_vsize <= ZeroPtr(pMod->lpszModName))) VirtualFree(pMod->lpszModName,0,MEM_RELEASE); if ((ZeroPtr(pMod->BasePtr) > ZeroPtr(pMod->o32_ptr)) || (ZeroPtr(pMod->BasePtr) + pMod->e32.e32_vsize <= ZeroPtr(pMod->o32_ptr))) VirtualFree(pMod->o32_ptr,0,MEM_RELEASE); CloseExe(&pMod->oe); FreeMem(pMod,HEAP_MODULE);}void FreeLibraryByName(LPCHAR lpszName);// Free library from proc (by name), zeroing reference countVOID FreeLibraryFromProc(PMODULE pMod, PPROCESS pproc) { if (pMod->refcnt[pproc->procnum]) { pMod->refcnt[pproc->procnum] = 0; pMod->inuse &= ~(1 << pproc->procnum); if (SystemAPISets[SH_PATCHER]) FreeDllPatch(pproc,pMod); if (!pMod->inuse) { KDUpdateSymbols(((DWORD)pMod->BasePtr)+1, TRUE); CELOG_ModuleFree(pCurProc->hProc, (HANDLE)pMod, TRUE); FreeModuleMemory(pMod); } }}// Free all libraries from procVOID FreeAllProcLibraries(PPROCESS pProc) { PMODULE pMod, pNext; EnterCriticalSection(&LLcs); pMod = pModList; while (pMod) { pNext = pMod->pMod; FreeLibraryFromProc(pMod,pProc); pMod = pNext; } LeaveCriticalSection(&LLcs);}// Pass Reason/Reserved to DLL entry point for pModBOOL CallDLLEntry(PMODULE pMod, DWORD Reason, LPVOID Reserved) { BOOL retval = TRUE; DWORD LastError = KGetLastError(pCurThread); DWORD dwOldMode; if (pMod->startip && !(pMod->wFlags & DONT_RESOLVE_DLL_REFERENCES)) { if ((dwOldMode = GET_TIMEMODE(pCurThread)) == TIMEMODE_KERNEL) GoToUserTime(); if (Reason == DLL_PROCESS_ATTACH) { if (pMod->calledfunc & (1<<pCurProc->procnum)) goto DontCall; pMod->calledfunc |= (1<<pCurProc->procnum); } else if (Reason == DLL_PROCESS_DETACH) { if (!(pMod->calledfunc & (1<<pCurProc->procnum))) goto DontCall; pMod->calledfunc &= ~(1<<pCurProc->procnum); } __try { if (pMod->e32.e32_sect14rva) retval = ((comentry_t)pMod->startip)((HANDLE)pMod,Reason,Reserved, (LPVOID)ZeroPtr(pMod->BasePtr),pMod->e32.e32_sect14rva,pMod->e32.e32_sect14size); else retval = ((entry_t)pMod->startip)((HANDLE)pMod,Reason,Reserved); } __except (EXCEPTION_EXECUTE_HANDLER) { retval = FALSE; }DontCall: if (dwOldMode == TIMEMODE_KERNEL) GoToUserTime(); } KSetLastError(pCurThread,LastError); return retval;}BOOL UnDoDepends(PMODULE pMod);// Decrement ref count on pMod (from hCurProc), freeing if neededBOOL FreeOneLibraryPart2(PMODULE pMod, BOOL bCallEntry) { struct ImpHdr *blockptr; CELOG_ModuleFree(pCurProc->hProc, (HANDLE)pMod, FALSE); if (HasBreadcrumb(pMod)) return TRUE; SetBreadcrumb(pMod); if (HasModRefProcPtr(pMod,pCurProc)) { if (!DecRefCount(pMod)) { if (bCallEntry) CallDLLEntry(pMod,DLL_PROCESS_DETACH,0); if (pMod->e32.e32_sect14size) FreeLibraryByName("mscoree.dll"); pMod->dwNoNotify &= ~(1 << pCurProc->procnum); if(pMod->pmodResource) { FreeOneLibraryPart2(pMod, 0); // DONT call dllentry of RES dll pMod->pmodResource = 0; } if (!(pMod->wFlags & DONT_RESOLVE_DLL_REFERENCES)) UnDoDepends(pMod); UnCopyRegions(pMod); if (SystemAPISets[SH_PATCHER]) FreeDllPatch(pCurProc, pMod); if (pCurThread->pThrdDbg && ProcStarted(pCurProc) && pCurThread->pThrdDbg->hEvent) { pCurThread->pThrdDbg->dbginfo.dwProcessId = (DWORD)hCurProc; pCurThread->pThrdDbg->dbginfo.dwThreadId = (DWORD)hCurThread; pCurThread->pThrdDbg->dbginfo.dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT; pCurThread->pThrdDbg->dbginfo.u.UnloadDll.lpBaseOfDll = (LPVOID)ZeroPtr(pMod->BasePtr); SetEvent(pCurThread->pThrdDbg->hEvent); SC_WaitForMultiple(1,&pCurThread->pThrdDbg->hBlockEvent,FALSE,INFINITE); } } else { if (!(pMod->wFlags & DONT_RESOLVE_DLL_REFERENCES)) UnDoDepends(pMod); } if (!pMod->inuse) { CELOG_ModuleFree(pCurProc->hProc, (HANDLE)pMod, TRUE); KDUpdateSymbols(((DWORD)pMod->BasePtr)+1, TRUE); if (pMod->e32.e32_unit[IMP].rva) { blockptr = (struct ImpHdr *)((long)pMod->BasePtr+pMod->e32.e32_unit[IMP].rva); 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 neededvoid 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -