source: trunk/src/kernel32/old/winimage.cpp@ 1036

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

Backup copy of old kernel32

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