2 * Copyright 1994 Eric Youndale & Erik Bos
4 * based on Eric Youndale's pe-test and:
6 * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
14 #include <sys/types.h>
21 #define MAP_ANONYMOUS 0x20
23 unsigned int load_addr
;
25 void my_wcstombs(char * result
, u_short
* source
, int len
)
28 if(isascii(*source
)) *result
++ = *source
++;
30 printf("Unable to handle unicode right now\n");
36 char * xmmap(char * vaddr
, unsigned int v_size
, int prot
, int flags
,
37 int fd
, unsigned int file_offset
)
40 result
= mmap(vaddr
, v_size
, prot
, flags
, fd
, file_offset
);
41 if((unsigned int) result
!= 0xffffffff) return result
;
43 /* Sigh. Alignment must be wrong for mmap. Do this the hard way. */
44 if(!(flags
& MAP_FIXED
)) {
45 vaddr
= (char *)0x40000000;
49 mmap(vaddr
, v_size
, prot
, MAP_ANONYMOUS
| flags
, 0, 0);
50 lseek(fd
, file_offset
, SEEK_SET
);
51 read(fd
, vaddr
, v_size
);
55 void dump_exports(struct PE_Export_Directory
* pe_exports
)
61 u_char
** name
, *ename
;
63 Module
= ((char *) load_addr
) + pe_exports
->Name
;
64 printf("\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n",
66 pe_exports
->Number_Of_Functions
,
67 pe_exports
->Number_Of_Names
);
69 ordinal
= (u_short
*) (((char *) load_addr
) + (int) pe_exports
->Address_Of_Name_Ordinals
);
70 function
= (u_long
*) (((char *) load_addr
) + (int) pe_exports
->AddressOfFunctions
);
71 name
= (u_char
**) (((char *) load_addr
) + (int) pe_exports
->AddressOfNames
);
73 printf("%-32s Ordinal Virt Addr\n", "Function Name");
74 for(i
=0; i
< pe_exports
->Number_Of_Functions
; i
++)
76 ename
= (char *) (((char *) load_addr
) + (int) *name
++);
77 printf("%-32s %4d %8.8lx\n", ename
, *ordinal
++, *function
++);
81 void dump_imports(struct PE_Import_Directory
*pe_imports
)
83 struct PE_Import_Directory
* pe_imp
;
85 /* OK, now dump the import list */
86 printf("\nDumping imports list\n");
88 while (pe_imp
->ModuleName
)
91 struct pe_import_name
* pe_name
;
92 unsigned int * import_list
;
95 Module
= ((char *) load_addr
) + pe_imp
->ModuleName
;
96 printf("%s\n", Module
);
97 c
= strchr(Module
, '.');
100 import_list
= (unsigned int *)
101 (((unsigned int) load_addr
) + pe_imp
->Import_List
);
105 pe_name
= (struct pe_import_name
*) ((int) load_addr
+ *import_list
);
106 printf("--- %s %s.%d\n", pe_name
->Name
, Module
, pe_name
->Hint
);
113 static void dump_table(struct w_files
*wpnt
)
117 printf("Dump of segment table\n");
118 printf(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n");
119 for(i
=0; i
< wpnt
->pe
->pe_header
->coff
.NumberOfSections
; i
++)
121 printf("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n",
122 wpnt
->pe
->pe_seg
[i
].Name
,
123 wpnt
->pe
->pe_seg
[i
].Virtual_Size
,
124 wpnt
->pe
->pe_seg
[i
].Virtual_Address
,
125 wpnt
->pe
->pe_seg
[i
].Size_Of_Raw_Data
,
126 wpnt
->pe
->pe_seg
[i
].PointerToRawData
,
127 wpnt
->pe
->pe_seg
[i
].PointerToRelocations
,
128 wpnt
->pe
->pe_seg
[i
].PointerToLinenumbers
,
129 wpnt
->pe
->pe_seg
[i
].NumberOfRelocations
,
130 wpnt
->pe
->pe_seg
[i
].NumberOfLinenumbers
,
131 wpnt
->pe
->pe_seg
[i
].Characteristics
);
135 /**********************************************************************
137 * Load one PE format executable into memory
139 HINSTANCE
LoadPEImage(struct w_files
*wpnt
)
143 wpnt
->pe
= malloc(sizeof(struct pe_data
));
144 wpnt
->pe
->pe_header
= malloc(sizeof(struct pe_header_s
));
147 lseek(wpnt
->fd
, wpnt
->mz_header
->ne_offset
, SEEK_SET
);
148 read(wpnt
->fd
, wpnt
->pe
->pe_header
, sizeof(struct pe_header_s
));
151 wpnt
->pe
->pe_seg
= malloc(sizeof(struct pe_segment_table
) *
152 wpnt
->pe
->pe_header
->coff
.NumberOfSections
);
153 read(wpnt
->fd
, wpnt
->pe
->pe_seg
, sizeof(struct pe_segment_table
) *
154 wpnt
->pe
->pe_header
->coff
.NumberOfSections
);
156 load_addr
= wpnt
->pe
->pe_header
->opt_coff
.BaseOfImage
;
159 for(i
=0; i
< wpnt
->pe
->pe_header
->coff
.NumberOfSections
; i
++)
162 result
= xmmap(0, wpnt
->pe
->pe_seg
[i
].Size_Of_Raw_Data
, 7, MAP_PRIVATE
,
163 wpnt
->fd
, wpnt
->pe
->pe_seg
[i
].PointerToRawData
);
164 load_addr
= (unsigned int) result
- wpnt
->pe
->pe_seg
[i
].Virtual_Address
;
166 result
= xmmap((char *) load_addr
+ wpnt
->pe
->pe_seg
[i
].Virtual_Address
,
167 wpnt
->pe
->pe_seg
[i
].Size_Of_Raw_Data
, 7, MAP_PRIVATE
| MAP_FIXED
,
168 wpnt
->fd
, wpnt
->pe
->pe_seg
[i
].PointerToRawData
);
171 if(strcmp(wpnt
->pe
->pe_seg
[i
].Name
, ".idata") == 0)
172 wpnt
->pe
->pe_import
= (struct PE_Import_Directory
*) result
;
174 if(strcmp(wpnt
->pe
->pe_seg
[i
].Name
, ".edata") == 0)
175 wpnt
->pe
->pe_export
= (struct PE_Export_Directory
*) result
;
177 if(strcmp(wpnt
->pe
->pe_seg
[i
].Name
, ".rsrc") == 0) {
178 wpnt
->pe
->pe_resource
= (struct PE_Resource_Directory
*) result
;
180 /* save offset for PE_FindResource */
181 wpnt
->pe
->resource_offset
= wpnt
->pe
->pe_seg
[i
].Virtual_Address
-
182 wpnt
->pe
->pe_seg
[i
].PointerToRawData
;
186 if(wpnt
->pe
->pe_import
) dump_imports(wpnt
->pe
->pe_import
);
187 if(wpnt
->pe
->pe_export
) dump_exports(wpnt
->pe
->pe_export
);
189 wpnt
->hinstance
= 0x8000;
190 return (wpnt
->hinstance
);
193 int PEunloadImage(struct w_files
*wpnt
)
195 printf("PEunloadImage() called!\n");
196 /* free resources, image, unmap */
200 int StartPEprogram(struct w_files
*wpnt
)
202 printf("StartPEprogram() called!\n");
206 void InitPEDLL(struct w_files
*wpnt
)
208 /* Is this a library? */
209 if (wpnt
->pe
->pe_header
->coff
.Characteristics
& IMAGE_FILE_DLL
) {
210 printf("InitPEDLL() called!\n");