source: trunk/src/kernel32/winimage.cpp@ 281

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

Major changes in PE2LX/KERNEL32 for TLS support. DLL VERSION INCREASED TO 3 AS THIS CHANGE MAKES IT INCOMPATIBLE WITH APPS CONVERTED WITH PREVIOUS VERSION OF PE2LX (OR WIN32K)

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