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

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

version loading fixes + heap corruption fix

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