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>
22 #define MAP_ANONYMOUS 0x20
24 unsigned int load_addr
;
26 void my_wcstombs(char * result
, u_short
* source
, int len
)
29 if(isascii(*source
)) *result
++ = *source
++;
31 printf("Unable to handle unicode right now\n");
37 char * xmmap(char * vaddr
, unsigned int v_size
, int prot
, int flags
,
38 int fd
, unsigned int file_offset
)
41 result
= mmap(vaddr
, v_size
, prot
, flags
, fd
, file_offset
);
42 if((unsigned int) result
!= 0xffffffff) return result
;
44 /* Sigh. Alignment must be wrong for mmap. Do this the hard way. */
45 if(!(flags
& MAP_FIXED
)) {
46 vaddr
= (char *)0x40000000;
50 mmap(vaddr
, v_size
, prot
, MAP_ANONYMOUS
| flags
, 0, 0);
51 lseek(fd
, file_offset
, SEEK_SET
);
52 read(fd
, vaddr
, v_size
);
56 void dump_exports(struct PE_Export_Directory
* pe_exports
)
62 u_char
** name
, *ename
;
64 Module
= ((char *) load_addr
) + pe_exports
->Name
;
65 printf("\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n",
67 pe_exports
->Number_Of_Functions
,
68 pe_exports
->Number_Of_Names
);
70 ordinal
= (u_short
*) (((char *) load_addr
) + (int) pe_exports
->Address_Of_Name_Ordinals
);
71 function
= (u_long
*) (((char *) load_addr
) + (int) pe_exports
->AddressOfFunctions
);
72 name
= (u_char
**) (((char *) load_addr
) + (int) pe_exports
->AddressOfNames
);
74 printf("%-32s Ordinal Virt Addr\n", "Function Name");
75 for(i
=0; i
< pe_exports
->Number_Of_Functions
; i
++)
77 ename
= (char *) (((char *) load_addr
) + (int) *name
++);
78 printf("%-32s %4d %8.8lx\n", ename
, *ordinal
++, *function
++);
82 void dump_imports(struct PE_Import_Directory
*pe_imports
)
84 struct PE_Import_Directory
* pe_imp
;
86 /* OK, now dump the import list */
87 printf("\nDumping imports list\n");
89 while (pe_imp
->ModuleName
)
92 struct pe_import_name
* pe_name
;
93 unsigned int * import_list
;
96 Module
= ((char *) load_addr
) + pe_imp
->ModuleName
;
97 printf("%s\n", Module
);
98 c
= strchr(Module
, '.');
101 import_list
= (unsigned int *)
102 (((unsigned int) load_addr
) + pe_imp
->Import_List
);
106 pe_name
= (struct pe_import_name
*) ((int) load_addr
+ *import_list
);
107 printf("--- %s %s.%d\n", pe_name
->Name
, Module
, pe_name
->Hint
);
114 static void dump_table(struct w_files
*wpnt
)
118 printf("Dump of segment table\n");
119 printf(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n");
120 for(i
=0; i
< wpnt
->pe
->pe_header
->coff
.NumberOfSections
; i
++)
122 printf("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n",
123 wpnt
->pe
->pe_seg
[i
].Name
,
124 wpnt
->pe
->pe_seg
[i
].Virtual_Size
,
125 wpnt
->pe
->pe_seg
[i
].Virtual_Address
,
126 wpnt
->pe
->pe_seg
[i
].Size_Of_Raw_Data
,
127 wpnt
->pe
->pe_seg
[i
].PointerToRawData
,
128 wpnt
->pe
->pe_seg
[i
].PointerToRelocations
,
129 wpnt
->pe
->pe_seg
[i
].PointerToLinenumbers
,
130 wpnt
->pe
->pe_seg
[i
].NumberOfRelocations
,
131 wpnt
->pe
->pe_seg
[i
].NumberOfLinenumbers
,
132 wpnt
->pe
->pe_seg
[i
].Characteristics
);
136 /**********************************************************************
138 * Load one PE format executable into memory
140 HINSTANCE
PE_LoadImage(struct w_files
*wpnt
)
144 wpnt
->pe
= malloc(sizeof(struct pe_data
));
145 wpnt
->pe
->pe_header
= malloc(sizeof(struct pe_header_s
));
148 lseek(wpnt
->fd
, wpnt
->mz_header
->ne_offset
, SEEK_SET
);
149 read(wpnt
->fd
, wpnt
->pe
->pe_header
, sizeof(struct pe_header_s
));
152 wpnt
->pe
->pe_seg
= malloc(sizeof(struct pe_segment_table
) *
153 wpnt
->pe
->pe_header
->coff
.NumberOfSections
);
154 read(wpnt
->fd
, wpnt
->pe
->pe_seg
, sizeof(struct pe_segment_table
) *
155 wpnt
->pe
->pe_header
->coff
.NumberOfSections
);
157 load_addr
= wpnt
->pe
->pe_header
->opt_coff
.BaseOfImage
;
160 for(i
=0; i
< wpnt
->pe
->pe_header
->coff
.NumberOfSections
; i
++)
163 result
= xmmap((char *)0, wpnt
->pe
->pe_seg
[i
].Size_Of_Raw_Data
, 7,
164 MAP_PRIVATE
, wpnt
->fd
, wpnt
->pe
->pe_seg
[i
].PointerToRawData
);
165 load_addr
= (unsigned int) result
- wpnt
->pe
->pe_seg
[i
].Virtual_Address
;
167 result
= xmmap((char *) load_addr
+ wpnt
->pe
->pe_seg
[i
].Virtual_Address
,
168 wpnt
->pe
->pe_seg
[i
].Size_Of_Raw_Data
, 7, MAP_PRIVATE
| MAP_FIXED
,
169 wpnt
->fd
, wpnt
->pe
->pe_seg
[i
].PointerToRawData
);
172 if(strcmp(wpnt
->pe
->pe_seg
[i
].Name
, ".idata") == 0)
173 wpnt
->pe
->pe_import
= (struct PE_Import_Directory
*) result
;
175 if(strcmp(wpnt
->pe
->pe_seg
[i
].Name
, ".edata") == 0)
176 wpnt
->pe
->pe_export
= (struct PE_Export_Directory
*) result
;
178 if(strcmp(wpnt
->pe
->pe_seg
[i
].Name
, ".rsrc") == 0) {
179 wpnt
->pe
->pe_resource
= (struct PE_Resource_Directory
*) result
;
181 /* save offset for PE_FindResource */
182 wpnt
->pe
->resource_offset
= wpnt
->pe
->pe_seg
[i
].Virtual_Address
-
183 wpnt
->pe
->pe_seg
[i
].PointerToRawData
;
187 if(wpnt
->pe
->pe_import
) dump_imports(wpnt
->pe
->pe_import
);
188 if(wpnt
->pe
->pe_export
) dump_exports(wpnt
->pe
->pe_export
);
190 wpnt
->hinstance
= 0x8000;
191 return (wpnt
->hinstance
);
194 int PE_UnloadImage(struct w_files
*wpnt
)
196 printf("PEunloadImage() called!\n");
197 /* free resources, image, unmap */
201 int PE_StartProgram(struct w_files
*wpnt
)
203 printf("StartPEprogram() called!\n");
207 void PE_InitDLL(struct w_files
*wpnt
)
209 /* Is this a library? */
210 if (wpnt
->pe
->pe_header
->coff
.Characteristics
& IMAGE_FILE_DLL
) {
211 printf("InitPEDLL() called!\n");