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

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

Color cursor changes + dll loading fixes

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