3 * Portable Executable Loader
\r
10 #define DEBUG (ACESS_DEBUG|PE_DEBUG)
\r
12 //#define DLL_BASE_PATH "/Acess/Windows/"
\r
13 #define DLL_BASE_PATH NULL
\r
16 # define DEBUGS(v...) SysDebug(v)
\r
18 # define DEBUGS(v...)
\r
21 // === PROTOTYPES ===
\r
22 void *PE_Relocate(void *Base, char **envp, const char *Filename);
\r
23 char *PE_int_GetTrueFile(char *file);
\r
24 int PE_int_GetForwardSymbol(char *Fwd, void **Value);
\r
27 void *PE_Relocate(void *Base, char **envp, const char *Filename)
\r
29 tPE_DOS_HEADER *dosHdr = Base;
\r
30 tPE_IMAGE_HEADERS *peHeaders;
\r
31 tPE_DATA_DIR *directory;
\r
32 tPE_IMPORT_DIR *impDir;
\r
33 tPE_HINT_NAME *name;
\r
34 Uint32 *importTab, *aIAT;
\r
36 intptr_t iBase = (intptr_t)Base;
\r
39 DEBUGS("PE_Relocate: (Base=0x%x)\n", Base);
\r
41 peHeaders = Base + dosHdr->PeHdrOffs;
\r
43 directory = peHeaders->OptHeader.Directory;
\r
45 // === Load Import Tables
\r
46 impDir = Base + directory[PE_DIR_IMPORT].RVA;
\r
47 for( i = 0; impDir[i].DLLName != NULL; i++ )
\r
49 impDir[i].DLLName += iBase;
\r
50 impDir[i].ImportLookupTable += iBase/4;
\r
51 impDir[i].ImportAddressTable += iBase/4;
\r
52 DEBUGS(" PE_Relocate: DLL Required '%s'(0x%x)\n", impDir[i].DLLName, impDir[i].DLLName);
\r
53 pLibBase = LoadLibrary(PE_int_GetTrueFile(impDir[i].DLLName), DLL_BASE_PATH, envp);
\r
55 SysDebug("Unable to load required library '%s'\n", impDir[i].DLLName);
\r
58 DEBUGS(" PE_Relocate: Loaded as 0x%x\n", pLibBase);
\r
59 importTab = impDir[i].ImportLookupTable;
\r
60 aIAT = impDir[i].ImportAddressTable;
\r
61 for( j = 0; importTab[j] != 0; j++ )
\r
63 if( importTab[j] & 0x80000000 )
\r
64 DEBUGS(" PE_Relocate: Import Ordinal %i\n", importTab[j] & 0x7FFFFFFF);
\r
68 name = (void*)( iBase + importTab[j] );
\r
69 DEBUGS(" PE_Relocate: Import Name '%s', Hint 0x%x\n", name->Name, name->Hint);
\r
70 if( GetSymbolFromBase(pLibBase, name->Name, symPtr, NULL) == 0 )
\r
72 SysDebug("Unable to find symbol '%s' in library '%s'\n", name->Name, impDir[i].DLLName);
\r
75 aIAT[j] = (intptr_t)symPtr;
\r
81 for(i=0;i<PE_DIR_LAST;i++) {
\r
82 if(directory[i].RVA == 0) continue;
\r
83 SysDebug("directory[%i] = {RVA=0x%x,Size=0x%x}\n", i, directory[i].RVA, directory[i].Size);
\r
87 DEBUGS("PE_Relocate: RETURN 0x%x\n", iBase + peHeaders->OptHeader.EntryPoint);
\r
89 return (void*)( iBase + peHeaders->OptHeader.EntryPoint );
\r
93 * \fn int PE_GetSymbol(Uint Base, const char *Name, Uint *Ret)
\r
95 int PE_GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size)
\r
97 tPE_DOS_HEADER *dosHdr = Base;
\r
98 tPE_IMAGE_HEADERS *peHeaders;
\r
99 tPE_DATA_DIR *directory;
\r
100 tPE_EXPORT_DIR *expDir;
\r
101 Uint32 *nameTable, *addrTable;
\r
109 peHeaders = (void*)( Base + dosHdr->PeHdrOffs );
\r
110 directory = peHeaders->OptHeader.Directory;
\r
112 expDir = (void*)( Base + directory[PE_DIR_EXPORT].RVA );
\r
113 expLen = directory[PE_DIR_EXPORT].Size;
\r
114 symbolCount = expDir->NumNamePointers;
\r
115 nameTable = (void*)( Base + expDir->NamePointerRVA );
\r
116 ordTable = (void*)( Base + expDir->OrdinalTableRVA );
\r
117 addrTable = (void*)( Base + expDir->AddressRVA );
\r
118 //DEBUGS(" PE_GetSymbol: %i Symbols\n", symbolCount);
\r
119 for(i=0;i<symbolCount;i++)
\r
121 name = (char*)( Base + nameTable[i] );
\r
122 //DEBUGS(" PE_GetSymbol: '%s' = 0x%x\n", name, Base + addrTable[ ordTable[i] ]);
\r
123 if(strcmp(name, Name) == 0)
\r
125 retVal = (intptr_t) Base + addrTable[ ordTable[i] ];
\r
126 // Check for forwarding
\r
127 if( (intptr_t)expDir < retVal && retVal < (intptr_t)expDir + expLen) {
\r
128 char *fwd = (char*)retVal;
\r
129 DEBUGS(" PE_GetSymbol: '%s' forwards to '%s'\n", name, fwd);
\r
130 return PE_int_GetForwardSymbol(fwd, Ret);
\r
132 *Ret = (void*)retVal;
\r
133 if(Size) *Size = 0;
\r
141 * \fn char *PE_int_GetTrueFile(char *file)
\r
142 * \brief Get the true file name
\r
144 char *PE_int_GetTrueFile(char *file)
\r
147 if(file[0] != ':') return file;
\r
150 for(i=1;file[i];i++)
\r
157 int PE_int_GetForwardSymbol(char *Fwd, void **Value)
\r
165 // -- Find seperator
\r
166 // PE spec says that there sould only be one, but the string may
\r
167 // be mutilated in the loader
\r
168 for(i=0;Fwd[i]!='\0';i++);
\r
169 for(;i&&Fwd[i]!='.';i--);
\r
174 libname = PE_int_GetTrueFile(Fwd);
\r
176 DEBUGS(" PE_int_GetForwardSymbol: Get '%s' from '%s'\n", sym, libname);
\r
178 libbase = LoadLibrary(libname, DLL_BASE_PATH, NULL);
\r
179 ret = GetSymbolFromBase(libbase, sym, Value, NULL);
\r
181 SysDebug(" PE_int_GetForwardSymbol: Unable to find '%s' in '%s'\n", sym, libname);
\r