source: trunk/src/kernel32/winimagepeldr.cpp@ 1410

Last change on this file since 1410 was 1410, checked in by sandervl, 26 years ago

Changes for logging & getversionsize/struct

File size: 43.1 KB
Line 
1/* $Id: winimagepeldr.cpp,v 1.8 1999-10-23 12:34:48 sandervl Exp $ */
2
3/*
4 * Win32 PE loader Image base class
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Knut St. Osmundsen
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 *
12 * NOTE: RSRC_LOAD is a special flag to only load the resource directory
13 * of a PE image. Processing imports, sections etc is not done.
14 * Nor is it put into the linked list of dlls (if it's a dll).
15 * This is useful for GetVersionSize/Resource in case it wants to
16 * get version info of an image that is not loaded.
17 * So an instance of this type can't be used for anything but resource lookup!
18 *
19 */
20
21#define INCL_DOSFILEMGR /* File Manager values */
22#define INCL_DOSMODULEMGR
23#define INCL_DOSERRORS /* DOS Error values */
24#define INCL_DOSPROCESS /* DOS Process values */
25#define INCL_DOSMISC /* DOS Miscellanous values */
26#define INCL_WIN
27#define INCL_BASE
28#include <os2wrap.h> //Odin32 OS/2 api wrappers
29
30#include <stdio.h>
31#include <string.h>
32#include <stdlib.h>
33
34#include <assert.h>
35#include <misc.h>
36#include <win32type.h>
37#include <winimagebase.h>
38#include <winimagepeldr.h>
39#include <windllpeldr.h>
40#include <pefile.h>
41#include <unicode.h>
42#include <winres.h>
43#include "oslibmisc.h"
44#include "initterm.h"
45#include <win\virtual.h>
46
47char szErrorTitle[] = "Odin";
48char szMemErrorMsg[] = "Memory allocation failure";
49char szFileErrorMsg[] = "File IO error";
50char szPEErrorMsg[] = "Not a valid win32 exe. (perhaps 16 bits windows)";
51char szCPUErrorMsg[] = "Executable doesn't run on x86 machines";
52char szExeErrorMsg[] = "File isn't an executable";
53char szInteralErrorMsg[]= "Internal Error";
54
55#ifndef max
56#define max(a, b) ((a>b) ? a : b)
57#endif
58
59BOOL foutInit = FALSE;
60ofstream fout;
61
62ULONG MissingApi();
63char *hex(ULONG num);
64
65extern ULONG flAllocMem; /*Tue 03.03.1998: knut */
66
67//******************************************************************************
68//******************************************************************************
69Win32PeLdrImage::Win32PeLdrImage(char *szFileName, int loadtype) :
70 Win32ImageBase(-1),
71 nrsections(0), imageSize(0),
72 imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0),
73 nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
74 pResSection(NULL), fImgMapping(0)
75{
76 loadType = loadtype;
77
78 strcpy(this->szFileName, szFileName);
79
80 strcpy(szModule, OSLibStripPath(szFileName));
81 strupr(szModule);
82 char *dot = strstr(szModule, ".");
83 while(dot) {
84 char *newdot = strstr(dot+1, ".");
85 if(newdot == NULL) break;
86 dot = newdot;
87 }
88 if(dot)
89 *dot = 0;
90
91 if(foutInit == FALSE) {
92 char logname[32];
93 sprintf(logname, "pe_%d.log", loadNr);
94 fout.open(logname, ios::out | ios::trunc);
95 if(fout.good() == FALSE) {
96 sprintf(logname, "%spe_%d.log", kernel32Path, loadNr);
97 fout.open(logname, ios::out | ios::trunc);
98 }
99 dprintf(("PE LOGFILE for %s: %s", szModule, logname));
100 foutInit = TRUE;
101 }
102}
103//******************************************************************************
104//******************************************************************************
105Win32PeLdrImage::~Win32PeLdrImage()
106{
107 if(realBaseAddress)
108 DosFreeMem((PVOID)realBaseAddress);
109
110 if(nameexports)
111 free(nameexports);
112
113 if(ordexports)
114 free(ordexports);
115
116 //SvL: Only happens for images that aren't really loaded (RSRC_LOAD)
117 if(fImgMapping) CloseHandle(fImgMapping);
118 fImgMapping = 0;
119}
120//******************************************************************************
121//******************************************************************************
122BOOL Win32PeLdrImage::init(ULONG reservedMem)
123{
124 char szErrorMsg[64];
125 LPVOID win32file = NULL;
126 ULONG filesize, ulRead;
127 PIMAGE_SECTION_HEADER psh;
128 IMAGE_TLS_DIRECTORY *tlsDir = NULL;
129 int nSections, i;
130 char szFullPath[CCHMAXPATH] = "";
131
132 fImgMapping = VIRTUAL_MapFileA(szFileName, &win32file);
133
134 if (fImgMapping == -1) {
135 sprintf(szErrorMsg, "Unable to open %32s\n", szFileName);
136 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
137 goto failure;
138 }
139
140 if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) {
141 setFullPath(szFullPath);
142 }
143
144 if(GetPEFileHeader (win32file, &fh) == FALSE) {
145 fout << "Not a valid PE file (probably a 16 bits windows exe/dll)!" << endl;
146 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
147 goto failure;
148 }
149
150 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
151 fout << "Not a valid PE file!" << endl;
152 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
153 goto failure;
154 }
155 if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
156 fout << "You need a REAL CPU to run this code" << endl;
157 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szCPUErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
158 goto failure;
159 }
160 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
161 if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
162 fout << "Can't convert system files" << endl;
163 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szExeErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
164 goto failure;
165 }
166
167 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
168 fout << "No fixups, might not run!" << endl;
169 }
170
171 GetPEOptionalHeader (win32file, &oh);
172 fout << "PE file : " << szFileName << endl;
173 fout << "PE Optional header: " << endl;
174 fout << "Preferred address : " << oh.ImageBase << endl;
175 fout << "Base Of Code : " << oh.BaseOfCode << endl;
176 fout << "CodeSize : " << oh.SizeOfCode << endl;
177 fout << "Base Of Data : " << oh.BaseOfData << endl;
178 fout << "Data Size (uninit): " << oh.SizeOfUninitializedData << endl;
179 fout << "Data Size (init) : " << oh.SizeOfInitializedData << endl;
180 fout << "Entry Point : " << oh.AddressOfEntryPoint << endl;
181 fout << "Section Alignment : " << oh.SectionAlignment << endl;
182 fout << "Stack Reserve size: " << oh.SizeOfStackReserve << endl;
183 fout << "Stack Commit size : " << oh.SizeOfStackCommit << endl;
184 fout << "SizeOfHeapReserve : " << oh.SizeOfHeapReserve << endl;
185 fout << "SizeOfHeapCommit : " << oh.SizeOfHeapCommit << endl;
186 fout << "FileAlignment : " << oh.FileAlignment << endl;
187 fout << "Subsystem : " << oh.Subsystem << endl;
188
189 nSections = NR_SECTIONS(win32file);
190
191 if(loadType == REAL_LOAD)
192 {
193 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) {
194 fout << endl << "*************************PE SECTIONS START**************************" << endl;
195 for (i=0; i<nSections; i++) {
196 fout << "Raw data size: " << hex(psh[i].SizeOfRawData) << endl;
197 fout << "Virtual Address: " << hex(psh[i].VirtualAddress) << endl;
198 fout << "Virtual Size: " << hex(psh[i].Misc.VirtualSize) << endl;
199 fout << "Pointer to raw data: " << hex(psh[i].PointerToRawData) << endl;
200 fout << "Section flags: " << hex(psh[i].Characteristics) << endl << endl;
201 if(strcmp(psh[i].Name, ".reloc") == 0) {
202 fout << ".reloc" << endl << endl;
203 addSection(SECTION_RELOC, (char *)win32file+psh[i].PointerToRawData,
204 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
205 psh[i].Misc.VirtualSize);
206 continue;
207 }
208 if(strcmp(psh[i].Name, ".edata") == 0) {
209 fout << ".edata" << endl << endl;
210 addSection(SECTION_EXPORT, (char *)win32file+psh[i].PointerToRawData,
211 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
212 psh[i].Misc.VirtualSize);
213 continue;
214 }
215 if(strcmp(psh[i].Name, ".rsrc") == 0) {
216 fout << ".rsrc" << endl << endl;
217 addSection(SECTION_RESOURCE, (char *)win32file+psh[i].PointerToRawData,
218 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
219 psh[i].Misc.VirtualSize);
220 continue;
221 }
222 if(strcmp(psh[i].Name, ".tls") == 0)
223 {
224 tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS);
225 if(tlsDir) {
226 fout << "TLS Directory" << endl;
227 fout << "TLS Address of Index " << hex((ULONG)tlsDir->AddressOfIndex) << endl;
228 fout << "TLS Address of Callbacks " << hex((ULONG)tlsDir->AddressOfCallBacks) << endl;
229 fout << "TLS SizeOfZeroFill " << hex(tlsDir->SizeOfZeroFill) << endl;
230 fout << "TLS Characteristics " << hex(tlsDir->Characteristics) << endl;
231 addSection(SECTION_TLS, (char *)win32file+psh[i].PointerToRawData,
232 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
233 psh[i].Misc.VirtualSize);
234 }
235 continue;
236 }
237
238 if(strcmp(psh[i].Name, ".debug") == 0) {
239 fout << ".rdebug" << endl << endl;
240 addSection(SECTION_DEBUG, (char *)win32file+psh[i].PointerToRawData,
241 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
242 psh[i].Misc.VirtualSize);
243 continue;
244 }
245 if(IsImportSection(win32file, &psh[i]))
246 {
247 int type = SECTION_IMPORT;
248 fout << "Import Data Section" << endl << endl;
249 if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE) {
250 fout << "Also Code Section" << endl << endl;
251 type |= SECTION_CODE;
252 }
253 addSection(type, (char *)win32file+psh[i].PointerToRawData,
254 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
255 psh[i].Misc.VirtualSize);
256 continue;
257 }
258
259 //KSO Sun 1998-08-09: Borland does not alway set the CODE flag for its "CODE" section
260 if( psh[i].Characteristics & IMAGE_SCN_CNT_CODE ||
261 (psh[i].Characteristics & IMAGE_SCN_MEM_EXECUTE &&
262 !(psh[i].Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA))) //KSO: make sure its not marked as a datasection
263 )
264 {
265 fout << "Code Section" << endl << endl;
266 addSection(SECTION_CODE, (char *)win32file+psh[i].PointerToRawData,
267 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
268 psh[i].Misc.VirtualSize);
269 continue;
270 }
271 if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section
272 fout << "Read Only Data Section" << endl << endl;
273 addSection(SECTION_READONLYDATA, (char *)win32file+psh[i].PointerToRawData,
274 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
275 psh[i].Misc.VirtualSize);
276 continue;
277 }
278 if(psh[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
279 fout << "Uninitialized Data Section" << endl << endl;
280 addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,
281 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
282 psh[i].Misc.VirtualSize);
283 continue;
284 }
285 if(psh[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) {
286 fout << "Initialized Data Section" << endl << endl;
287 addSection(SECTION_INITDATA, (char *)win32file+psh[i].PointerToRawData,
288 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
289 psh[i].Misc.VirtualSize);
290 continue;
291 }
292 if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) {
293 fout << "Other Section, stored as read/write uninit data" << endl << endl;
294 addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,
295 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
296 psh[i].Misc.VirtualSize);
297 continue;
298 }
299 fout << "Unknown section" << endl;
300 goto failure;
301 }
302 }
303 fout << "*************************PE SECTIONS END **************************" << endl;
304 imageSize += imageVirtBase - oh.ImageBase;
305 fout << "Total size of Image " << imageSize << endl;
306 fout << "imageVirtBase " << imageVirtBase << endl;
307 fout << "imageVirtEnd " << imageVirtEnd << endl;
308
309 //In case there are any gaps between sections, adjust size
310 if(imageSize != imageVirtEnd - oh.ImageBase) {
311 fout << "imageSize != imageVirtEnd - oh.ImageBase!" << endl;
312 imageSize = imageVirtEnd - oh.ImageBase;
313 }
314 if(allocSections(reservedMem) == FALSE) {
315 fout << "Failed to allocate image memory, rc " << errorState << endl;
316 goto failure;
317 }
318 fout << "OS/2 base address " << realBaseAddress << endl;
319 if(storeSections((char *)win32file) == FALSE) {
320 fout << "Failed to store sections, rc " << errorState << endl;
321 goto failure;
322 }
323 if(oh.AddressOfEntryPoint) {
324 entryPoint = realBaseAddress + oh.AddressOfEntryPoint;
325 }
326 else {
327 fout << "EntryPoint == NULL" << endl;
328 entryPoint = NULL;
329 }
330
331 if(tlsDir != NULL) {
332 Section *sect = findSection(SECTION_TLS);
333
334 if(sect == NULL) {
335 fout << "Couldn't find TLS section!!" << endl;
336 goto failure;
337 }
338 setTLSAddress((char *)(sect->realvirtaddr + (tlsDir->StartAddressOfRawData - sect->virtaddr)));
339 setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData);
340 setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill);
341
342 sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex);
343 if(sect == NULL) {
344 fout << "Couldn't find TLS AddressOfIndex section!!" << endl;
345 goto failure;
346 }
347 setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr)));
348
349 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks);
350 if(sect == NULL) {
351 fout << "Couldn't find TLS AddressOfCallBacks section!!" << endl;
352 goto failure;
353 }
354 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr)));
355 }
356
357 if(realBaseAddress != oh.ImageBase) {
358 if(setFixups((PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC)) == FALSE) {
359 fout << "Failed to set fixups" << endl;
360 goto failure;
361 }
362 }
363 if(fh.Characteristics & IMAGE_FILE_DLL) {
364 if(processExports((char *)win32file) == FALSE) {
365 fout << "Failed to process exported apis" << endl;
366 goto failure;
367 }
368 }
369
370 //SvL: Use pointer to image header as module handle now. Some apps needs this
371 hinstance = (HINSTANCE)realBaseAddress;
372 }
373
374 //PH: get pResDir pointer correct first, since processImports may
375 // implicitly call functions depending on it.
376 IMAGE_SECTION_HEADER sh;
377 if(GetSectionHdrByName (win32file, &sh, ".rsrc")) {
378 //get offset in resource object of directory entry
379 pResDir = (PIMAGE_RESOURCE_DIRECTORY)(sh.VirtualAddress + realBaseAddress);
380 pResourceSectionStart = (ULONG)pResSection->virtaddr - oh.ImageBase;
381 }
382
383 if (loadType == REAL_LOAD)
384 {
385 if(processImports((char *)win32file) == FALSE) {
386 fout << "Failed to process imports!" << endl;
387 goto failure;
388 }
389
390 //set final memory protection flags (storeSections sets them to read/write)
391 if(setMemFlags() == FALSE) {
392 fout << "Failed to set memory protection" << endl;
393 goto failure;
394 }
395 CloseHandle(fImgMapping);
396 fImgMapping = 0;
397 }
398 return(TRUE);
399failure:
400 if(fImgMapping) CloseHandle(fImgMapping);
401 fImgMapping = 0;
402 errorState = ERROR_INTERNAL;
403 return FALSE;
404}
405//******************************************************************************
406//******************************************************************************
407void Win32PeLdrImage::addSection(ULONG type, char *rawdata, ULONG rawsize, ULONG virtaddress, ULONG virtsize)
408{
409 virtsize = max(rawsize, virtsize);
410
411 section[nrsections].type = type;
412 section[nrsections].rawdata = rawdata;
413 section[nrsections].rawsize = rawsize;
414 section[nrsections].virtaddr = virtaddress;
415
416 if(type == SECTION_RESOURCE) {
417 pResSection = &section[nrsections];
418 }
419 virtsize = ((virtsize - 1) & ~0xFFF) + PAGE_SIZE;
420 imageSize += virtsize;
421 section[nrsections].virtualsize = virtsize;
422
423 if(virtaddress < imageVirtBase)
424 imageVirtBase = virtaddress;
425 if(virtaddress + virtsize > imageVirtEnd)
426 imageVirtEnd = virtaddress + virtsize;
427
428 nrsections++;
429}
430//******************************************************************************
431//******************************************************************************
432BOOL Win32PeLdrImage::allocSections(ULONG reservedMem)
433{
434 APIRET rc;
435 ULONG baseAddress;
436
437 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
438 fout << "No fixups, might not run!" << endl;
439 return allocFixedMem(reservedMem);
440 }
441 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | flAllocMem);
442 if(rc) {
443 errorState = rc;
444 return(FALSE);
445 }
446 realBaseAddress = baseAddress;
447 return(TRUE);
448}
449//******************************************************************************
450//******************************************************************************
451Section *Win32PeLdrImage::findSection(ULONG type)
452{
453 for(int i=0;i<nrsections;i++) {
454 if(section[i].type == type) {
455 return &section[i];
456 }
457 }
458 return NULL;
459}
460//******************************************************************************
461//******************************************************************************
462Section *Win32PeLdrImage::findSectionByAddr(ULONG addr)
463{
464 for(int i=0;i<nrsections;i++) {
465 if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) {
466 return &section[i];
467 }
468 }
469 return NULL;
470}
471//******************************************************************************
472#define FALLOC_SIZE (1024*1024)
473//NOTE: Needs testing (while loop)
474//TODO: Free unused (parts of) reservedMem
475//******************************************************************************
476BOOL Win32PeLdrImage::allocFixedMem(ULONG reservedMem)
477{
478 ULONG address = 0;
479 ULONG *memallocs;
480 ULONG alloccnt = 0;
481 ULONG diff, i, baseAddress;
482 APIRET rc;
483
484 realBaseAddress = 0;
485
486 if(reservedMem && reservedMem <= oh.ImageBase &&
487 ((oh.ImageBase - reservedMem) + imageSize < PELDR_RESERVEDMEMSIZE))
488 {
489 //ok, it fits perfectly
490 realBaseAddress = oh.ImageBase;
491 return TRUE;
492 }
493
494 //Reserve enough space to store 4096 pointers to 1MB memory chunks
495 memallocs = (ULONG *)malloc(4096*sizeof(ULONG *));
496 if(memallocs == NULL) {
497 fout << "allocFixedMem: MALLOC FAILED for memallocs" << endl;
498 return FALSE;
499 }
500
501 while(TRUE) {
502 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | flAllocMem);
503 if(rc) break;
504
505 fout << "DosAllocMem returned " << address << endl;
506 if(address + FALLOC_SIZE >= oh.ImageBase) {
507 if(address > oh.ImageBase) {//we've passed it!
508 DosFreeMem((PVOID)address);
509 break;
510 }
511 //found the right address
512 DosFreeMem((PVOID)address);
513
514 diff = oh.ImageBase - address;
515 if(diff) {
516 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | flAllocMem);
517 if(rc) break;
518 }
519 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | flAllocMem);
520 if(rc) break;
521
522 if(diff) DosFreeMem((PVOID)address);
523
524 realBaseAddress = baseAddress;
525 break;
526 }
527 memallocs[alloccnt++] = address;
528 }
529 for(i=0;i<alloccnt;i++) {
530 DosFreeMem((PVOID)memallocs[i]);
531 }
532 free(memallocs);
533
534 if(realBaseAddress == 0) //Let me guess.. MS Office app?
535 return(FALSE);
536
537 return(TRUE);
538}
539//******************************************************************************
540//******************************************************************************
541BOOL Win32PeLdrImage::storeSections(char *win32file)
542{
543 int i;
544 APIRET rc;
545 ULONG pagFlags = PAG_COMMIT;
546 ULONG headersize;
547 WINIMAGE_LOOKUP *imgLookup;
548
549 //Commit memory for image header
550 headersize = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) +
551 sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections;
552
553 if(headersize + sizeof(WINIMAGE_LOOKUP) < PAGE_SIZE) {
554 headersize = PAGE_SIZE;
555 }
556 else {//ooops, just in case this doesn't work
557 fout << "ERROR: storeSections: header too big!!!!!! Fatal error" << endl;
558 return FALSE;
559 }
560
561 rc = DosSetMem((PVOID)realBaseAddress, headersize, pagFlags | PAG_WRITE | PAG_READ);
562 if(rc) {
563 fout << "DosSetMem failed for Image header! " << rc << endl;
564 return FALSE;
565 }
566 // Store the NT header at the load addr
567 memcpy((char *)realBaseAddress, win32file, sizeof(IMAGE_DOS_HEADER));
568 memcpy((char *)PE_HEADER(realBaseAddress), PE_HEADER(win32file), sizeof(IMAGE_NT_HEADERS));
569 memcpy(PE_SECTIONS(realBaseAddress), PE_SECTIONS(win32file),
570 sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections );
571
572 imgLookup = WINIMAGE_LOOKUPADDR(realBaseAddress);
573 imgLookup->image = this;
574#ifdef DEBUG
575 imgLookup->magic = MAGIC_WINIMAGE;
576#endif
577
578 // Process all the image sections
579 for(i=0;i<nrsections;i++) {
580 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase);
581 }
582 for(i=0;i<nrsections;i++) {
583 pagFlags = PAG_COMMIT;
584 switch(section[i].type) {
585 case SECTION_CODE:
586 case (SECTION_CODE | SECTION_IMPORT):
587 case SECTION_INITDATA:
588 case SECTION_UNINITDATA:
589 case SECTION_IMPORT:
590 case SECTION_READONLYDATA:
591 case SECTION_RESOURCE:
592 case SECTION_TLS:
593 pagFlags |= PAG_WRITE | PAG_READ;
594 break;
595 case SECTION_EXPORT:
596 case SECTION_DEBUG:
597 case SECTION_RELOC:
598 pagFlags = 0; //don't commit
599 break;
600 }
601 if(pagFlags == 0) continue; //debug or export section
602
603 rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags);
604 if(rc) {
605 errorState = rc;
606 return(FALSE);
607 }
608 if(section[i].type != SECTION_UNINITDATA) {
609 assert(section[i].rawdata);
610 memcpy((char *)section[i].realvirtaddr, section[i].rawdata, section[i].rawsize);
611 }
612 }
613 return(TRUE);
614}
615//******************************************************************************
616//******************************************************************************
617BOOL Win32PeLdrImage::setMemFlags()
618{
619 int i;
620 APIRET rc;
621 ULONG pagFlags = 0;
622
623 for(i=0;i<nrsections;i++) {
624 pagFlags = 0;
625 switch(section[i].type) {
626 case SECTION_CODE:
627 case (SECTION_CODE | SECTION_IMPORT):
628 pagFlags |= PAG_EXECUTE | PAG_READ;
629 break;
630 case SECTION_INITDATA:
631 case SECTION_UNINITDATA:
632 case SECTION_IMPORT: //TODO: read only?
633 pagFlags |= PAG_WRITE | PAG_READ;
634 break;
635 case SECTION_READONLYDATA:
636 case SECTION_RESOURCE:
637 case SECTION_TLS:
638 pagFlags |= PAG_READ;
639 break;
640 default:
641 continue;
642 }
643 rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags);
644 if(rc) {
645 errorState = rc;
646 return(FALSE);
647 }
648 }
649 return(TRUE);
650}
651//******************************************************************************
652//******************************************************************************
653BOOL Win32PeLdrImage::setFixups(PIMAGE_BASE_RELOCATION prel)
654{
655 int i, j;
656 char *page;
657 ULONG count;
658
659 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
660 return(TRUE);
661 }
662
663 if(prel) {
664 j = 1;
665 while(prel->VirtualAddress) {
666 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
667 count = (prel->SizeOfBlock - 8)/2;
668 fout.setf(ios::hex, ios::basefield);
669 fout << "Page " << j << " Address " << (ULONG)prel->VirtualAddress << " Count " << count << endl;
670 fout.setf(ios::dec, ios::basefield);
671 j++;
672 for(i=0;i<count;i++) {
673 int type = prel->TypeOffset[i] >> 12;
674 int offset = prel->TypeOffset[i] & 0xFFF;
675 switch(type) {
676 case IMAGE_REL_BASED_ABSOLUTE:
677//// fout << "absolute fixup; unused" << endl;
678 break; //skip
679 case IMAGE_REL_BASED_HIGHLOW:
680//// fout << "address " << offset << " type " << type << endl;
681 AddOff32Fixup(oh.ImageBase +
682 prel->VirtualAddress + offset);
683 break;
684 case IMAGE_REL_BASED_HIGH:
685 AddOff16Fixup(oh.ImageBase + prel->VirtualAddress + offset, TRUE);
686 break;
687 case IMAGE_REL_BASED_LOW:
688 AddOff16Fixup(oh.ImageBase + prel->VirtualAddress + offset, FALSE);
689 break;
690 case IMAGE_REL_BASED_HIGHADJ:
691 case IMAGE_REL_BASED_MIPS_JMPADDR:
692 default:
693 fout << "Unknown/unsupported fixup type!" << endl;
694 break;
695 }
696 }
697 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
698 }//while
699 }
700 else {
701 fout << "No internal fixups found!\n" << endl;
702 errorState = ERROR_INTERNAL;
703 return(FALSE);
704 }
705 return(TRUE);
706}
707//******************************************************************************
708//******************************************************************************
709void Win32PeLdrImage::AddOff32Fixup(ULONG fixupaddr)
710{
711 ULONG orgaddr;
712 ULONG *fixup;
713
714 fixup = (ULONG *)(fixupaddr - oh.ImageBase + realBaseAddress);
715 orgaddr = *fixup;
716 *fixup = realBaseAddress + (*fixup - oh.ImageBase);
717}
718//******************************************************************************
719//******************************************************************************
720void Win32PeLdrImage::AddOff16Fixup(ULONG fixupaddr, BOOL fHighFixup)
721{
722 ULONG orgaddr;
723 USHORT *fixup;
724
725 fixup = (USHORT *)(fixupaddr - oh.ImageBase + realBaseAddress);
726 orgaddr = *fixup;
727 if(fHighFixup) {
728 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) >> 16);
729 }
730 else {
731 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) & 0xFFFF);
732 }
733}
734//******************************************************************************
735//******************************************************************************
736void Win32PeLdrImage::StoreImportByOrd(Win32DllBase *WinDll, ULONG ordinal, ULONG impaddr)
737{
738 ULONG *import;
739 ULONG apiaddr;
740
741 import = (ULONG *)(impaddr - oh.ImageBase + realBaseAddress);
742 apiaddr = WinDll->getApi(ordinal);
743 if(apiaddr == 0)
744 {
745 dprintf(("KERNEL32:Win32PeLdrImage - %s.%u not found\n",
746 WinDll->getName(),
747 ordinal));
748
749 fout << "--->>> NOT FOUND!";
750 *import = (ULONG)MissingApi;
751 }
752 else *import = apiaddr;
753}
754//******************************************************************************
755//******************************************************************************
756void Win32PeLdrImage::StoreImportByName(Win32DllBase *WinDll, char *impname, ULONG impaddr)
757{
758 ULONG *import;
759 ULONG apiaddr;
760
761 import = (ULONG *)(impaddr - oh.ImageBase + realBaseAddress);
762 apiaddr = WinDll->getApi(impname);
763 if(apiaddr == 0)
764 {
765 dprintf(("KERNEL32:Win32PeLdrImage - %s.%s not found\n",
766 WinDll->getName(),
767 impname));
768
769 fout << "--->>> NOT FOUND!";
770 *import = (ULONG)MissingApi;
771 }
772 else *import = apiaddr;
773}
774//******************************************************************************
775//******************************************************************************
776BOOL Win32PeLdrImage::processExports(char *win32file)
777{
778 IMAGE_SECTION_HEADER sh;
779 PIMAGE_EXPORT_DIRECTORY ped;
780 ULONG *ptrNames, *ptrAddress;
781 USHORT *ptrOrd;
782 int i;
783
784 /* get section header and pointer to data directory for .edata section */
785 if((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
786 (win32file, IMAGE_DIRECTORY_ENTRY_EXPORT)) != NULL &&
787 GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_EXPORT, &sh) ) {
788
789 fout << "Exported Functions: " << endl;
790 ptrOrd = (USHORT *)((ULONG)ped->AddressOfNameOrdinals -
791 (ULONG)sh.VirtualAddress +
792 (ULONG)sh.PointerToRawData + (ULONG)win32file);
793 ptrNames = (ULONG *)((ULONG)ped->AddressOfNames -
794 (ULONG)sh.VirtualAddress +
795 (ULONG)sh.PointerToRawData + (ULONG)win32file);
796 ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions -
797 (ULONG)sh.VirtualAddress +
798 (ULONG)sh.PointerToRawData + (ULONG)win32file);
799 nrOrdExports = ped->NumberOfFunctions;
800 nrNameExports = ped->NumberOfNames;
801
802 int ord, RVAExport;
803 char *name;
804 for(i=0;i<ped->NumberOfNames;i++) {
805 ord = ptrOrd[i] + ped->Base;
806 name = (char *)((ULONG)ptrNames[i] - (ULONG)sh.VirtualAddress +
807 (ULONG)sh.PointerToRawData + (ULONG)win32file);
808 RVAExport = ptrAddress[ptrOrd[i]];
809#ifdef FORWARDERS
810 if(RVAExport < sh.VirtualAddress || RVAExport > sh.VirtualAddress + sh.SizeOfRawData) {
811#endif
812 //points to code (virtual address relative to oh.ImageBase
813 fout << "address 0x";
814 fout.setf(ios::hex, ios::basefield);
815 fout << RVAExport;
816 fout.setf(ios::dec, ios::basefield);
817 fout << " " << name << "@" << ord << endl;
818 AddNameExport(oh.ImageBase + RVAExport, name, ord);
819#ifdef FORWARDERS
820
821 }
822 else {//forwarder
823 char *forward = (char *)((ULONG)RVAExport -
824 (ULONG)sh.VirtualAddress +
825 (ULONG)sh.PointerToRawData +
826 (ULONG)win32file);
827 fout << RVAExport << " " << name << " @" << ord << " is forwarder to " << (int)forward << endl;
828 }
829#endif
830 }
831 for(i=0;i<max(ped->NumberOfNames,ped->NumberOfFunctions);i++) {
832 ord = ped->Base + i; //Correct??
833 RVAExport = ptrAddress[i];
834#ifdef FORWARDERS
835 if(RVAExport < sh.VirtualAddress || RVAExport > sh.VirtualAddress + sh.SizeOfRawData) {
836#endif
837 if(RVAExport) {
838 //points to code (virtual address relative to oh.ImageBase
839 fout << "ord " << ord << " at 0x";
840 fout.setf(ios::hex, ios::basefield);
841 fout << RVAExport << endl;
842 fout.setf(ios::dec, ios::basefield);
843 AddOrdExport(oh.ImageBase + RVAExport, ord);
844 }
845#ifdef FORWARDERS
846 }
847 else {//forwarder or empty
848 char *forward = (char *)((ULONG)RVAExport -
849 (ULONG)sh.VirtualAddress +
850 (ULONG)sh.PointerToRawData +
851 (ULONG)win32file);
852 fout << "ord " << ord << " at 0x";
853 fout.setf(ios::hex, ios::basefield);
854 fout << RVAExport << " is forwarder to 0x" << (int)forward << endl;
855 fout.setf(ios::dec, ios::basefield);
856 }
857#endif
858 }
859 }
860 return(TRUE);
861}
862//******************************************************************************
863//******************************************************************************
864void Win32PeLdrImage::AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal)
865{
866 ULONG nsize;
867
868 if(nameexports == NULL) {
869 nameExportSize= 4096;
870 nameexports = (NameExport *)malloc(nameExportSize);
871 curnameexport = nameexports;
872 }
873 nsize = (ULONG)curnameexport - (ULONG)nameexports;
874 if(nsize + sizeof(NameExport) + strlen(apiname) > nameExportSize) {
875 nameExportSize += 4096;
876 char *tmp = (char *)nameexports;
877 nameexports = (NameExport *)malloc(nameExportSize);
878 memcpy(nameexports, tmp, nsize);
879 curnameexport = (NameExport *)((ULONG)nameexports + nsize);
880 free(tmp);
881 }
882 curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
883 curnameexport->ordinal = ordinal;
884 *(ULONG *)curnameexport->name = 0;
885 strcpy(curnameexport->name, apiname);
886
887 curnameexport->nlength = strlen(apiname) + 1;
888 if(curnameexport->nlength < sizeof(curnameexport->name))
889 curnameexport->nlength = sizeof(curnameexport->name);
890
891 curnameexport = (NameExport *)((ULONG)curnameexport->name + curnameexport->nlength);
892}
893//******************************************************************************
894//******************************************************************************
895void Win32PeLdrImage::AddOrdExport(ULONG virtaddr, ULONG ordinal)
896{
897 if(ordexports == NULL) {
898 ordexports = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport));
899 curordexport = ordexports;
900 }
901 curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
902 curordexport->ordinal = ordinal;
903 curordexport++;
904}
905//******************************************************************************
906/** All initial processing of imports is done here
907 * Should now detect most Borland styled files including the GifCon32.exe and
908 * loader32 from SoftIce. (Stupid Borland!!!)
909 *
910 * knut [Jul 22 1998 2:44am]
911 **/
912//******************************************************************************
913BOOL Win32PeLdrImage::processImports(char *win32file)
914{
915 PIMAGE_IMPORT_DESCRIPTOR pID;
916 IMAGE_SECTION_HEADER shID;
917 IMAGE_SECTION_HEADER shExtra = {0};
918 PIMAGE_OPTIONAL_HEADER pOH;
919 int i,j;
920 BOOL fBorland = 0;
921 int cModules;
922 char *pszModules;
923 char *pszCurModule;
924 char *pszTmp;
925 ULONG *pulImport;
926 ULONG ulCurFixup;
927 int Size;
928 Win32PeLdrDll *WinDll;
929
930/* "algorithm:"
931 * 1) get module names and store them
932 * a) check dwRVAModuleName is within .idata seg - if not find section
933 * 2) iterate thru functions of each module
934 * a) check OriginalFirstThunk is not 0 and that it points to a RVA.
935 * b) if not a) borland-styled PE-file - ARG!!!
936 * check FirstThunk
937 * c) check OriginalFirstThunk/FirstThunk ok RVAs and find right section
938 * d) store ordinal/name import
939 * 3) finished
940 */
941
942 /* 1) get module names */
943 pID = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_IMPORT);
944 if (pID == NULL)
945 return TRUE;
946 if (!GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_IMPORT, &shID))
947 return TRUE;
948
949 //calc size of module list
950 i = Size = cModules = 0;
951 while (pID[i].Name != 0)
952 {
953 //test RVA inside ID-Section
954 if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) {
955 pszTmp = (char*)(pID[i].Name- shID.VirtualAddress + shID.PointerToRawData + (ULONG)win32file);
956 }
957 else {
958 //is the "Extra"-section already found or do we have to find it?
959 if (pID[i].Name < shExtra.VirtualAddress || pID[i].Name >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData)) {
960 if (!GetSectionHdrByRVA(win32file, &shExtra, pID[i].Name))
961 return FALSE;
962 }
963 pszTmp = (char*)(pID[i].Name- shExtra.VirtualAddress + shExtra.PointerToRawData + (ULONG)win32file);
964 }
965 Size += strlen(pszTmp) + 1;
966 i++;
967 cModules++;
968 }
969
970 pszModules = (char*)malloc(Size);
971 assert(pszModules != NULL);
972 j = 0;
973 for (i = 0; i < cModules; i++)
974 {
975 //test RVA inside ID-Section
976 if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) {
977 pszTmp = (char*)(pID[i].Name- shID.VirtualAddress + shID.PointerToRawData + (ULONG)win32file);
978 }
979 else {
980 fBorland = TRUE;
981 //is the "Extra"-section already found or do we have to find it?
982 if (pID[i].Name < shExtra.VirtualAddress || pID[i].Name >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData))
983 {
984 if (GetSectionHdrByRVA(win32file, &shExtra, pID[i].Name)) {
985 free(pszModules);
986 return FALSE;
987 }
988 }
989 pszTmp = (char*)(pID[i].Name- shExtra.VirtualAddress + shExtra.PointerToRawData + (ULONG)win32file);
990 }
991
992 strcpy(pszModules+j, pszTmp);
993 j += strlen(pszTmp) + 1;
994 }
995 fout << endl;
996 if (fBorland)
997 fout << "Borland-styled PE-File." << endl;
998 //Store modules
999 fout << cModules << " imported Modules: " << endl;
1000
1001 /* 2) functions */
1002 pszCurModule = pszModules;
1003 pOH = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF(win32file);
1004 for (i = 0; i < cModules; i++)
1005 {
1006 fout << "Module " << pszCurModule << endl;
1007 // a) check that OriginalFirstThunk not is 0 and look for Borland-styled PE
1008 if (i == 0)
1009 {
1010 //heavy borland-style test - assume array of thunks is within that style does not change
1011 if((ULONG)pID[i].u.OriginalFirstThunk == 0 ||
1012 (ULONG)pID[i].u.OriginalFirstThunk < shID.VirtualAddress ||
1013 (ULONG)pID[i].u.OriginalFirstThunk >= shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData) ||
1014 (ULONG)pID[i].u.OriginalFirstThunk >= pOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress &&
1015 (ULONG)pID[i].u.OriginalFirstThunk < sizeof(*pID)*cModules + pOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
1016 {
1017 fBorland = TRUE;
1018 }
1019 }
1020 //light borland-style test
1021 if (pID[i].u.OriginalFirstThunk == 0 || fBorland)
1022 pulImport = (ULONG*)pID[i].FirstThunk;
1023 else pulImport = (ULONG*)pID[i].u.OriginalFirstThunk;
1024
1025 // b) check if RVA ok
1026 if (!(pulImport > 0 && (ULONG)pulImport < pOH->SizeOfImage)) {
1027 fout << "Invalid RVA " << hex((ULONG)pulImport) << endl;
1028 break;
1029 }
1030 // check section
1031 if ((ULONG)pulImport < shExtra.VirtualAddress || (ULONG)pulImport >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData))
1032 {
1033 if (!GetSectionHdrByRVA(win32file, &shExtra, (ULONG)pulImport))
1034 {
1035 fout << "warning: could not find section for Thunk RVA " << hex((ULONG)pulImport) << endl;
1036 break;
1037 }
1038 }
1039
1040 //SvL: Load dll if needed
1041 fout << "**********************************************************************" << endl;
1042 fout << "************** Import Module " << pszCurModule << endl;
1043 fout << "**********************************************************************" << endl;
1044 WinDll = (Win32PeLdrDll *)Win32DllBase::findModule(pszCurModule);
1045
1046 if(WinDll == NULL)
1047 { //not found, so load it
1048 if(isPEImage(pszCurModule) == FALSE)
1049 {//LX image, so let OS/2 do all the work for us
1050 APIRET rc;
1051 char szModuleFailure[CCHMAXPATH] = "";
1052 char szModuleName[CCHMAXPATH];
1053 ULONG hInstanceNewDll;
1054
1055 strcpy(szModuleName, pszCurModule);
1056 char *dot = strchr(szModuleName, '.');
1057 if(dot) {
1058 *dot = 0;
1059 }
1060 strcat(szModuleName, ".DLL");
1061 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), szModuleName, (HMODULE *)&hInstanceNewDll);
1062 if(rc) {
1063 dprintf(("DosLoadModule returned %X for %s\n", rc, szModuleFailure));
1064 errorState = rc;
1065 return(FALSE);
1066 }
1067 WinDll = (Win32PeLdrDll *)Win32DllBase::findModule(hInstanceNewDll);
1068 if(WinDll == NULL) {//shouldn't happen!
1069 dprintf(("Just loaded the dll, but can't find it anywhere?!!?"));
1070 errorState = ERROR_INTERNAL;
1071 return(FALSE);
1072 }
1073 }
1074 else {
1075 WinDll = new Win32PeLdrDll(pszCurModule, this);
1076
1077 if(WinDll == NULL) {
1078 fout << "WinDll: Error allocating memory" << endl;
1079 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
1080 errorState = ERROR_INTERNAL;
1081 return(FALSE);
1082 }
1083 fout << "**********************************************************************" << endl;
1084 fout << "********************** Loading Module *********************" << endl;
1085 fout << "**********************************************************************" << endl;
1086 if(WinDll->init(0) == FALSE) {
1087 fout << "Internal WinDll error " << WinDll->getError() << endl;
1088 return(FALSE);
1089 }
1090 if(WinDll->attachProcess() == FALSE) {
1091 fout << "attachProcess failed!" << endl;
1092 errorState = ERROR_INTERNAL;
1093 return(FALSE);
1094 }
1095 WinDll->AddRef();
1096 }
1097 fout << "**********************************************************************" << endl;
1098 fout << "********************** Finished Loading Module *********************" << endl;
1099 fout << "**********************************************************************" << endl;
1100 }
1101 else fout << "Already found " << pszCurModule << endl;
1102
1103 WinDll->AddRef();
1104
1105 pulImport = (PULONG)((ULONG)pulImport - shExtra.VirtualAddress + (ULONG)win32file + shExtra.PointerToRawData);
1106 j = 0;
1107 ulCurFixup = (ULONG)pID[i].FirstThunk + pOH->ImageBase;
1108 while (pulImport[j] != 0) {
1109 if (pulImport[j] & IMAGE_ORDINAL_FLAG) { //ordinal
1110 fout.setf(ios::hex, ios::basefield);
1111 fout << "0x" << ulCurFixup << " Imported function " << pszCurModule << "@" << (pulImport[j] & ~IMAGE_ORDINAL_FLAG) << endl;
1112 fout.setf(ios::dec, ios::basefield);
1113 StoreImportByOrd(WinDll, pulImport[j] & ~IMAGE_ORDINAL_FLAG, ulCurFixup);
1114 }
1115 else { //name
1116 //check
1117 if (pulImport[j] < shExtra.VirtualAddress || pulImport[j] >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData)) {
1118 if (!GetSectionHdrByRVA(win32file, &shExtra, pulImport[j]))
1119 {
1120 fout << "warning: could not find section for Import Name RVA " << hex(pulImport[j]) << endl;
1121 break;
1122 }
1123 }
1124 //KSO - Aug 6 1998 1:15am:this eases comparing...
1125 char *pszFunctionName = (char*)(pulImport[j] + (ULONG)win32file + shExtra.PointerToRawData - shExtra.VirtualAddress + 2);
1126 fout.setf(ios::hex, ios::basefield);
1127 fout << "0x" << ulCurFixup << " Imported function " << pszFunctionName << endl;
1128 fout.setf(ios::dec, ios::basefield);
1129 StoreImportByName(WinDll, pszFunctionName, ulCurFixup);
1130 }
1131 ulCurFixup += sizeof(IMAGE_THUNK_DATA);
1132 j++;
1133 }
1134 fout << "**********************************************************************" << endl;
1135 fout << "************** End Import Module " << pszCurModule << endl;
1136 fout << "**********************************************************************" << endl;
1137
1138 pszCurModule += strlen(pszCurModule) + 1;
1139 fout << endl;
1140 }//for (i = 0; i < cModules; i++)
1141
1142 free(pszModules);
1143 return TRUE;
1144}
1145//******************************************************************************
1146//******************************************************************************
1147ULONG MissingApi()
1148{
1149 static BOOL fIgnore = FALSE;
1150 int r;
1151
1152 dprintf(("Missing api called!\n"));
1153 if(fIgnore)
1154 return(0);
1155
1156 do {
1157 r = WinMessageBox(HWND_DESKTOP, NULLHANDLE, "The application has called a non-existing api\n",
1158 "Internal Error", 0, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | MB_MOVEABLE);
1159 }
1160 while(r == MBID_RETRY); //giggle
1161
1162 if( r != MBID_IGNORE )
1163 exit(987);
1164
1165 fIgnore = TRUE;
1166 return(0);
1167}
1168/******************************************************************************/
1169/******************************************************************************/
1170/*heximal(decimal) KSO Sun 24.05.1998*/
1171char szHexBuffer[30];
1172
1173char *hex(ULONG num)
1174{
1175 sprintf(szHexBuffer, "0x%+08x (%lu)",num,num);
1176 return szHexBuffer;
1177}
1178//******************************************************************************
1179//******************************************************************************
Note: See TracBrowser for help on using the repository browser.