source: trunk/src/win32k/include/pe2lx.h@ 1467

Last change on this file since 1467 was 1467, checked in by bird, 26 years ago

Corrections to make win32k work.
(And now it does work, at least at my test machine...)

File size: 12.9 KB
Line 
1/* $Id: pe2lx.h,v 1.5 1999-10-27 02:02:57 bird Exp $
2 *
3 * Pe2Lx class declarations. Ring 0 and Ring 3
4 *
5 * Copyright (c) 1998-1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
6 * Copyright (c) 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright (c) 1998 Peter Fitzsimmons
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#ifndef _PE2LX_H_
13#define _PE2LX_H_
14
15
16/*******************************************************************************
17* Defined Constants And Macros *
18*******************************************************************************/
19/*
20 * Misc
21 */
22#define PAGESIZE 0x1000
23
24/*
25 * BufferedRVAReader config
26 */
27#define BUFFEREDRVAREADER_BUFFERSIZE PAGESIZE /* reader code assumes this size... */
28
29
30/*
31 * Error definitions (used in addition to them in bseerr.h)
32 */
33#define ERROR_FAILED_TO_ADD_OBJECT 0x42000000UL
34#define ERROR_INITMETHOD_NOT_INITTIME 0x42000001UL
35#define ERROR_INTERNAL_PROCESSING_ERROR 0x42000002UL
36
37
38/*
39 * Output macros.
40 * Macros: option infolevel
41 * printIPE -W1 Error
42 * printErr -W1 Error
43 * printWar -W2 Warning
44 * printInf -W3 Info
45 * printInfA -W4 InfoAll
46 */
47#define printIPE(a) (Pe2Lx::ulInfoLevel >= Pe2Lx::Error ? \
48 Pe2Lx::printf("\nerror(%d:"__FUNCTION__"): !Internal Processing Error!\n\t", __LINE__), \
49 Pe2Lx::printf a, \
50 Pe2Lx::printf("\n") \
51 : (void)0,(void)0,(void)0 )
52#define printErr(a) (Pe2Lx::ulInfoLevel >= Pe2Lx::Error ? \
53 Pe2Lx::printf("error(%d:"__FUNCTION__"): ", __LINE__), \
54 Pe2Lx::printf a \
55 : (void)0,(void)0 )
56#define printWar(a) (Pe2Lx::ulInfoLevel >= Pe2Lx::Warning ? \
57 Pe2Lx::printf("warning("__FUNCTION__"): "), \
58 Pe2Lx::printf a \
59 : (void)0,(void)0 )
60#define printInf(a) (Pe2Lx::ulInfoLevel >= Pe2Lx::Info ? \
61 Pe2Lx::printf a : (void)0 )
62#define printInfA(a)(Pe2Lx::ulInfoLevel >= Pe2Lx::InfoAll ? \
63 Pe2Lx::printf a : (void)0 )
64
65
66
67/*******************************************************************************
68* Structures and Typedefs *
69*******************************************************************************/
70/**
71 * LXObject is use to store objects in the virtual LX file.
72 */
73typedef struct LXObject
74{
75 ULONG ulRVA; /* Object relative virtual address */
76 ULONG cbPhysical; /* Physical size */
77 ULONG cbVirtual; /* Virtual size */
78 ULONG flFlags; /* LX flags! */
79 struct
80 {
81 ULONG offTIBFix : 30; /* TIBfix offset (from the object start) */
82 ULONG fTIBFixObject : 1;/* Set: The object contains the tibfix. Clear: not tib fix object. */
83 ULONG fStackObject : 1; /* Set: The object is the stack object. Clear: not the stack object. */
84 } Misc;
85 ULONG offPEFile; /* section offset into real PE file. */
86 ULONG offLXFile; /* object offset into virtual LX file. */
87} LXOBJECT, *PLXOBJECT;
88typedef const LXOBJECT *PCLXOBJECT;
89
90
91
92/**
93 * Pe2Lx class. Reads a PE executable image and creates a virtual LX file which
94 * can be read from and (RING3) dumped to file.
95 *
96 * @author knut st. osmundsen
97 * @approval knut st. osmundsen
98 */
99class Pe2Lx
100{
101public:
102 /** @cat Constructor/Destructor */
103 Pe2Lx(SFN hFile);
104 ~Pe2Lx();
105
106 /** @cat Public Main methods */
107 ULONG init(PCSZ pszFilename);
108 ULONG read(ULONG offLXFile, PVOID pvBuffer, ULONG cbToRead, ULONG flFlags, PMTE pMTE);
109 #ifndef RING0
110 ULONG writeLxFile(PCSZ pszLXFilename);
111 #endif
112
113 /** @cat public Helper methods */
114 BOOL queryIsModuleName(PCSZ pszFilename);
115 ULONG querySizeOfLxFile();
116 VOID dumpVirtualLxFile();
117
118
119private:
120 /** @cat conversion methods */
121 ULONG makeObjectTable();
122 ULONG makeObjectPageTable();
123 ULONG makeFixups();
124 ULONG makeExports();
125
126 /** @cat conversion helper(s) */
127 ULONG loadNtHeaders();
128 VOID releaseNtHeaders();
129
130 /** @cat init() helper methods - may only be called at init time! */
131 ULONG addObject(ULONG ulRVA, ULONG cbPhysical, ULONG cbVirtual, ULONG flFlags, ULONG offPEFile);
132 ULONG addTIBFixObject();
133 ULONG addStackObject(ULONG cbStack);
134
135 /** @cat PE helper methods */
136
137 /** @cat Fixups Helpers - calls allowed from makeFixups only! */
138 ULONG initFixups();
139 ULONG addPageFixupEntry(BOOL fLast = FALSE);
140 ULONG add32OffsetFixup(WORD offSource, ULONG ulTarget);
141 ULONG add32OrdImportFixup(WORD offSource, ULONG ulModuleOrdinal, ULONG ulFunctionOrdinal);
142 ULONG add32NameImportFixup(WORD offSource, ULONG ulModuleOrdinal, PCSZ pszFnName);
143 ULONG addModule(PCSZ pszModuleName, PULONG pulModuleOrdinal);
144 ULONG addImportFunctionName(PCSZ pszFnName, PULONG poffFnName);
145 VOID finalizeFixups();
146 VOID finalizeImportNames();
147
148 /** @cat Entry table / Resident nametable helpers */
149 ULONG initEntry();
150 ULONG addResName(ULONG ulOrdinal, PCSZ pszName, ULONG cchName);
151 ULONG addEntry(ULONG ulOrdinal, ULONG ulRVA);
152 ULONG addForwarderEntry(ULONG ulOrdinal, PCSZ pszDllName, PCSZ pszFnNameOrOrd);
153 ULONG addLastEntry();
154 VOID finalizeExports();
155
156 /** @cat Misc helpers */
157 ULONG getCountOfPages();
158 ULONG queryObjectAndOffset(ULONG ulRVA, PULONG pulObject, PULONG poffObject);
159
160 /** @cat static helpers */
161 static PCSZ queryOdin32ModuleName(PCSZ pszWin32ModuleName);
162
163 /** @cat static dump methods */
164 static VOID dumpNtHeaders(PIMAGE_NT_HEADERS pNtHdrs);
165 static VOID dumpSectionHeader(PIMAGE_SECTION_HEADER pSection);
166
167 /** @cat static print method */
168public:
169 static VOID printf(PCSZ pszFormat, ...);
170
171private:
172 /** @cat private data members - allways present. */
173 #ifdef DEBUG
174 BOOL fInitTime; /* init time indicator (debug) */
175 #endif
176 SFN hFile; /* filehandle */
177 PSZ pszFilename; /* fullpath */
178 PSZ pszModuleName; /* filename without extention. */
179 BOOL fAllInOneObject; /* The All-in-object fix will be or is applied. */
180 PLXOBJECT paObjects; /* Pointer to object array. */
181 USHORT cObjects; /* Count of elements in the object array. */
182 USHORT cObjectsAllocated; /* Size of the object array. */
183
184 /**
185 * @cat LX structures
186 */
187 struct e32_exe LXHdr; /* Lxheader */
188
189 struct o32_obj *paObjTab; /* Pointer to object table - if null check cObjects > 0 and generate it using makeObjectTable */
190 struct o32_map *paObjPageTab; /* Pointer to object page table - if null check cObjects > 0 and generate it using makeObjectPageTable */
191
192 PCHAR pachResNameTable; /* Pointer to resident name table. */
193 ULONG offCurResName; /* Offset of the next entry in the resident name table. */
194 ULONG cchRNTAllocated; /* Count of char allocated for the resident name table. */
195
196 struct b32_bundle *pEntryBundles; /* Pointer to entry bundles. (exports) */
197 ULONG offCurEntryBundle; /* Offset of the next bundle. */
198 ULONG offLastEntryBundle; /* Offset of the last entry bundle. */
199 ULONG ulLastOrdinal; /* Ordinal number of last entry which was added. */
200 ULONG cbEBAllocated; /* Count of bytes allocate for entry bundles. */
201 BOOL fForwarders; /* Set if forwarders are present. */
202
203 PULONG paulFixupPageTable; /* Pointer to fixup pagetable. If null generate it using makeFixups. */
204 ULONG cFixupPTEntries; /* Number of entries in the fixup page table. */
205 ULONG cFPTEAllocated; /* Number of page table entries allocated. */
206
207 PVOID pFixupRecords; /* Pointer to fixup records. If null generate it using makeFixups. */
208 ULONG offCurFixupRec; /* Offset of next fixup. */
209 ULONG cbFRAllocated; /* Count of bytes allocated for Fixup records. */
210
211 PVOID pvCrossPageFixup; /* Pointer to cross page fixup. */
212 ULONG cbCrossPageFixup; /* Fixup size in bytes. */
213
214 PCHAR pachImpModuleNames; /* Pointer to list of module names. */
215 ULONG offCurImpModuleName; /* Offset of next modulename. */
216 ULONG cchIMNAllocated; /* Count of chars allocated for pachImpModuleNames. */
217
218 PCHAR pachImpFunctionNames; /* Pointer to list of function names. */
219 ULONG offCurImpFunctionName; /* Offset of next functionname. */
220 ULONG cchIFNAllocated; /* Count of chars allocated for pachImpFunctionNames. */
221
222 /**
223 * @cat PE structues
224 */
225 ULONG offNtHeaders; /* Fileoffset of the PE\0\0 signature. */
226 PIMAGE_NT_HEADERS pNtHdrs; /* Pointer to NT-Headers. If null load it using loadNtHeaders. */
227 ULONG ulImageBase; /* Image base address. */
228
229 /**
230 * @cat static data.
231 */
232 static struct LieListEntry /* Dll Name lie table. */
233 {
234 PCSZ pszWin32Name; /* Win32 dll name. */
235 PCSZ pszOdin32Name; /* Odin32 dll name. */
236 } paLieList[];
237
238 static struct PeCharacteristicsToLxFlags/* section characteristics to object flags */
239 {
240 unsigned int Characteristics; /* set of section characteristics */
241 ULONG flFlags; /* equivalent object flags */
242 } paSecChars2Flags[];
243
244public:
245 static ULONG ulInfoLevel; /* Current output message detail level. */
246 enum {Quiet, Error, Warning, Info, InfoAll}; /* Output message detail levels. */
247};
248
249
250/**
251 * BufferedRVARead - read at RVA with buffering.
252 * @author knut st. osmundsen
253 * @approval knut st. osmundsen
254 */
255class BufferedRVARead
256{
257public:
258 BufferedRVARead(SFN hFile, ULONG cObjects, PCLXOBJECT paObjects);
259#if 0
260 ULONG readAtRVA(ULONG ulRVA, PVOID pvBuffer, ULONG cbBuffer)
261#else
262 /**
263 * Reads a chunk of data at the spcified RVA.
264 * @returns NO_ERROR on success.
265 * ERROR_INVALID_PARAMETER
266 * <Whatever rc ReadAt returns>
267 * @param ulRVA RVA to read from. Within the filesize.
268 * @param pvBuffer Pointer to output buffer. pvBuffer > 64KB
269 * @param cbBuffer Number of bytes to read. 0 < cbBuffer > 256MB
270 * @status completely
271 * @author knut st. osmundsen
272 */
273 inline ULONG readAtRVA(ULONG ulRVA, PVOID pvBuffer, ULONG cbBuffer)
274 {
275 /*
276 * five cases:
277 * 1) entire area is within the buffer.
278 * 2) start of area is within the buffer.
279 * 3) end of area is within the buffer.
280 * 4) the area is larger than the buffer, covering it.
281 * 5) the area is outside the buffer.
282 *
283 * these are optimal: 1, 2, and 5.
284 * The request is allways process from start to end. This will make case 3 and 4 less effecient.
285 */
286 #ifdef DEBUG
287 if (ulRVA == ~0UL || (ULONG)pvBuffer < 0x10000UL || cbBuffer == 0UL || cbBuffer >= 0x10000000UL)
288 return ERROR_INVALID_PARAMETER;
289 #endif
290
291 do
292 {
293 if (ulRVA >= this->ulRVA && ulRVA < this->ulRVA + sizeof(achBuffer))
294 { /* in buffer */
295 register ULONG cbRead = sizeof(achBuffer) - (ulRVA - this->ulRVA);
296 cbRead = min(cbRead, cbBuffer);
297 memcpy(pvBuffer, &achBuffer[ulRVA - this->ulRVA], (size_t)cbRead);
298 if (cbBuffer == cbRead)
299 return NO_ERROR;
300 cbBuffer -= cbRead;
301 pvBuffer = (PVOID)((ULONG)pvBuffer + cbRead);
302 ulRVA += cbRead;
303 }
304 else
305 { /* not in buffer, then read it into the buffer! */
306 APIRET rc = readToBuffer(ulRVA);
307 if (rc != NO_ERROR)
308 return rc;
309 }
310 } while (cbBuffer != 0UL);
311
312 return NO_ERROR;
313 }
314#endif
315
316 ULONG dupString(ULONG ulRVA, PSZ *ppsz);
317 BufferedRVARead & operator =(BufferedRVARead &SrcObj);
318
319private:
320 ULONG readToBuffer(ULONG ulRVA);
321
322private:
323 SFN hFile; /* Filehandle. */
324 ULONG cObjects; /* Count of objects */
325 PCLXOBJECT paObjects; /* Pointer to a readonly array of objects. */
326 ULONG ulRVA; /* RVA for the buffer start */
327 CHAR achBuffer[BUFFEREDRVAREADER_BUFFERSIZE]; /* Buffer. NOTE! Code assumes that it is a page. */
328};
329
330#endif
Note: See TracBrowser for help on using the repository browser.