le.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*
  2. * Dumping of LE binaries
  3. *
  4. * Copyright 2004 Robert Reif
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include "config.h"
  21. #include "wine/port.h"
  22. #include <fcntl.h>
  23. #include <stdarg.h>
  24. #include <stdio.h>
  25. #ifdef HAVE_UNISTD_H
  26. #include <unistd.h>
  27. #endif
  28. #include "windef.h"
  29. #include "winbase.h"
  30. #include "winedump.h"
  31. struct o32_obj
  32. {
  33. unsigned long o32_size;
  34. unsigned long o32_base;
  35. unsigned long o32_flags;
  36. unsigned long o32_pagemap;
  37. unsigned long o32_mapsize;
  38. char o32_name[4];
  39. };
  40. struct o32_map
  41. {
  42. unsigned short o32_pagedataoffset;
  43. unsigned char o32_pagesize;
  44. unsigned char o32_pageflags;
  45. };
  46. struct b32_bundle
  47. {
  48. unsigned char b32_cnt;
  49. unsigned char b32_type;
  50. };
  51. struct vxd_descriptor
  52. {
  53. unsigned long next;
  54. unsigned short sdk_version;
  55. unsigned short device_number;
  56. unsigned char version_major;
  57. unsigned char version_minor;
  58. unsigned short flags;
  59. char name[8];
  60. unsigned long init_order;
  61. unsigned long ctrl_ofs;
  62. unsigned long v86_ctrl_ofs;
  63. unsigned long pm_ctrl_ofs;
  64. unsigned long v86_ctrl_csip;
  65. unsigned long pm_ctrl_csip;
  66. unsigned long rm_ref_data;
  67. unsigned long service_table_ofs;
  68. unsigned long service_table_size;
  69. unsigned long win32_service_table_ofs;
  70. unsigned long prev;
  71. unsigned long size;
  72. unsigned long reserved0;
  73. unsigned long reserved1;
  74. unsigned long reserved2;
  75. };
  76. static inline WORD get_word( const BYTE *ptr )
  77. {
  78. return ptr[0] | (ptr[1] << 8);
  79. }
  80. static void dump_le_header( const IMAGE_VXD_HEADER *le )
  81. {
  82. printf( "File header:\n" );
  83. printf( " Magic: %04x (%c%c)\n",
  84. le->e32_magic, LOBYTE(le->e32_magic), HIBYTE(le->e32_magic));
  85. printf( " Byte order: %s\n",
  86. le->e32_border == 0 ? "little-indian" : "big-endian");
  87. printf( " Word order: %s\n",
  88. le->e32_worder == 0 ? "little-indian" : "big-endian");
  89. printf( " Executable format level: %d\n",
  90. le->e32_level);
  91. printf( " CPU type: %s\n",
  92. le->e32_cpu == 0x01 ? "Intel 80286" :
  93. le->e32_cpu == 0x02 ? "Intel 80386" :
  94. le->e32_cpu == 0x03 ? "Intel 80486" :
  95. le->e32_cpu == 0x04 ? "Intel 80586" :
  96. le->e32_cpu == 0x20 ? "Intel i860 (N10)" :
  97. le->e32_cpu == 0x21 ? "Intel i860 (N11)" :
  98. le->e32_cpu == 0x40 ? "MIPS Mark I" :
  99. le->e32_cpu == 0x41 ? "MIPS Mark II" :
  100. le->e32_cpu == 0x42 ? "MIPS Mark III" :
  101. "Unknown");
  102. printf( " Target operating system: %s\n",
  103. le->e32_os == 0x01 ? "OS/2" :
  104. le->e32_os == 0x02 ? "Windows" :
  105. le->e32_os == 0x03 ? "DOS 4.x" :
  106. le->e32_os == 0x04 ? "Windows 386" :
  107. "Unknown");
  108. printf( " Module version: %d\n",
  109. le->e32_ver);
  110. printf( " Module type flags: %08x\n",
  111. le->e32_mflags);
  112. if (le->e32_mflags & 0x8000)
  113. {
  114. if (le->e32_mflags & 0x0004)
  115. printf( " Global initialization\n");
  116. else
  117. printf( " Per-Process initialization\n");
  118. if (le->e32_mflags & 0x0010)
  119. printf( " No internal fixup\n");
  120. if (le->e32_mflags & 0x0020)
  121. printf( " No external fixup\n");
  122. if ((le->e32_mflags & 0x0700) == 0x0100)
  123. printf( " Incompatible with PM windowing\n");
  124. else if ((le->e32_mflags & 0x0700) == 0x0200)
  125. printf( " Compatible with PM windowing\n");
  126. else if ((le->e32_mflags & 0x0700) == 0x0300)
  127. printf( " Uses PM windowing API\n");
  128. if (le->e32_mflags & 0x2000)
  129. printf( " Module not loadable\n");
  130. if (le->e32_mflags & 0x8000)
  131. printf( " Module is DLL\n");
  132. }
  133. printf( " Number of memory pages: %d\n",
  134. le->e32_mpages);
  135. printf( " Initial object CS number: %08x\n",
  136. le->e32_startobj);
  137. printf( " Initial EIP: %08x\n",
  138. le->e32_eip);
  139. printf( " Initial object SS number: %08x\n",
  140. le->e32_stackobj);
  141. printf( " Initial ESP: %08x\n",
  142. le->e32_esp);
  143. printf( " Memory page size: %d\n",
  144. le->e32_pagesize);
  145. printf( " Bytes on last page: %d\n",
  146. le->e32_lastpagesize);
  147. printf( " Fix-up section size: %d\n",
  148. le->e32_fixupsize);
  149. printf( " Fix-up section checksum: %08x\n",
  150. le->e32_fixupsum);
  151. printf( " Loader section size: %d\n",
  152. le->e32_ldrsize);
  153. printf( " Loader section checksum: %08x\n",
  154. le->e32_ldrsum);
  155. printf( " Offset of object table: %08x\n",
  156. le->e32_objtab);
  157. printf( " Object table entries: %d\n",
  158. le->e32_objcnt);
  159. printf( " Object page map offset: %08x\n",
  160. le->e32_objmap);
  161. printf( " Object iterate data map offset: %08x\n",
  162. le->e32_itermap);
  163. printf( " Resource table offset: %08x\n",
  164. le->e32_rsrctab);
  165. printf( " Resource table entries: %d\n",
  166. le->e32_rsrccnt);
  167. printf( " Resident names table offset: %08x\n",
  168. le->e32_restab);
  169. printf( " Entry table offset: %08x\n",
  170. le->e32_enttab);
  171. printf( " Module directives table offset: %08x\n",
  172. le->e32_dirtab);
  173. printf( " Module directives entries: %d\n",
  174. le->e32_dircnt);
  175. printf( " Fix-up page table offset: %08x\n",
  176. le->e32_fpagetab);
  177. printf( " Fix-up record table offset: %08x\n",
  178. le->e32_frectab);
  179. printf( " Imported modules name table offset: %08x\n",
  180. le->e32_impmod);
  181. printf( " Imported modules count: %d\n",
  182. le->e32_impmodcnt);
  183. printf( " Imported procedure name table offset: %08x\n",
  184. le->e32_impproc);
  185. printf( " Per-page checksum table offset: %08x\n",
  186. le->e32_pagesum);
  187. printf( " Data pages offset from top of table: %08x\n",
  188. le->e32_datapage);
  189. printf( " Preload page count: %08x\n",
  190. le->e32_preload);
  191. printf( " Non-resident names table offset: %08x\n",
  192. le->e32_nrestab);
  193. printf( " Non-resident names table length: %d\n",
  194. le->e32_cbnrestab);
  195. printf( " Non-resident names table checksum: %08x\n",
  196. le->e32_nressum);
  197. printf( " Automatic data object: %08x\n",
  198. le->e32_autodata);
  199. printf( " Debug information offset: %08x\n",
  200. le->e32_debuginfo);
  201. printf( " Debug information length: %d\n",
  202. le->e32_debuglen);
  203. printf( " Preload instance pages number: %d\n",
  204. le->e32_instpreload);
  205. printf( " Demand instance pages number: %d\n",
  206. le->e32_instdemand);
  207. printf( " Extra heap allocation: %d\n",
  208. le->e32_heapsize);
  209. printf( " VxD resource table offset: %08x\n",
  210. le->e32_winresoff);
  211. printf( " Size of VxD resource table: %d\n",
  212. le->e32_winreslen);
  213. printf( " VxD identifier: %x\n",
  214. le->e32_devid);
  215. printf( " VxD DDK version: %x\n",
  216. le->e32_ddkver);
  217. }
  218. static void dump_le_objects( const IMAGE_VXD_HEADER *le )
  219. {
  220. const struct o32_obj *pobj;
  221. unsigned int i;
  222. printf("\nObject table:\n");
  223. pobj = (const struct o32_obj *)((const unsigned char *)le + le->e32_objtab);
  224. for (i = 0; i < le->e32_objcnt; i++)
  225. {
  226. unsigned int j;
  227. const struct o32_map *pmap=0;
  228. printf(" Obj. Rel.Base Codesize Flags Tableidx Tablesize Name\n");
  229. printf(" %04X %08lx %08lx %08lx %08lx %08lx ", i + 1,
  230. pobj->o32_base, pobj->o32_size, pobj->o32_flags,
  231. pobj->o32_pagemap, pobj->o32_mapsize);
  232. for (j = 0; j < 4; j++)
  233. {
  234. if (isprint(pobj->o32_name[j]))
  235. printf("%c", pobj->o32_name[j]);
  236. else
  237. printf(".");
  238. }
  239. printf("\n");
  240. if(pobj->o32_flags & 0x0001)
  241. printf("\tReadable\n");
  242. if(pobj->o32_flags & 0x0002)
  243. printf("\tWritable\n");
  244. if(pobj->o32_flags & 0x0004)
  245. printf("\tExecutable\n");
  246. if(pobj->o32_flags & 0x0008)
  247. printf("\tResource\n");
  248. if(pobj->o32_flags & 0x0010)
  249. printf("\tDiscardable\n");
  250. if(pobj->o32_flags & 0x0020)
  251. printf("\tShared\n");
  252. if(pobj->o32_flags & 0x0040)
  253. printf("\tPreloaded\n");
  254. if(pobj->o32_flags & 0x0080)
  255. printf("\tInvalid\n");
  256. if(pobj->o32_flags & 0x2000)
  257. printf("\tUse 32\n");
  258. printf(" Page tables:\n");
  259. printf(" Tableidx Offset Flags\n");
  260. pmap = (const struct o32_map *)((const unsigned char *)le + le->e32_objmap);
  261. pmap = &(pmap[pobj->o32_pagemap - 1]);
  262. for (j = 0; j < pobj->o32_mapsize; j++)
  263. {
  264. printf(" %08lx %06x %02x\n",
  265. pobj->o32_pagemap + j,
  266. (pmap->o32_pagedataoffset << 8) + pmap->o32_pagesize,
  267. (int)pmap->o32_pageflags);
  268. pmap++;
  269. }
  270. pobj++;
  271. }
  272. }
  273. static void dump_le_names( const IMAGE_VXD_HEADER *le )
  274. {
  275. const unsigned char *pstr = (const unsigned char *)le + le->e32_restab;
  276. printf( "\nResident name table:\n" );
  277. while (*pstr)
  278. {
  279. printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr,
  280. pstr + 1 );
  281. pstr += *pstr + 1 + sizeof(WORD);
  282. }
  283. if (le->e32_cbnrestab)
  284. {
  285. printf( "\nNon-resident name table:\n" );
  286. pstr = PRD(le->e32_nrestab, 0);
  287. while (*pstr)
  288. {
  289. printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr,
  290. pstr + 1 );
  291. pstr += *pstr + 1 + sizeof(WORD);
  292. }
  293. }
  294. }
  295. static void dump_le_resources( const IMAGE_VXD_HEADER *le )
  296. {
  297. printf( "\nResources:\n" );
  298. printf( " Not Implemented\n" );
  299. }
  300. static void dump_le_modules( const IMAGE_VXD_HEADER *le )
  301. {
  302. printf( "\nImported modulename table:\n" );
  303. printf( " Not Implemented\n" );
  304. }
  305. static void dump_le_entries( const IMAGE_VXD_HEADER *le )
  306. {
  307. printf( "\nEntry table:\n" );
  308. printf( " Not Implemented\n" );
  309. }
  310. static void dump_le_fixups( const IMAGE_VXD_HEADER *le )
  311. {
  312. printf( "\nFixup table:\n" );
  313. printf( " Not Implemented\n" );
  314. }
  315. static void dump_le_VxD( const IMAGE_VXD_HEADER *le )
  316. {
  317. printf( "\nVxD descriptor:\n" );
  318. printf( " Not Implemented\n" );
  319. }
  320. void le_dump( void )
  321. {
  322. const IMAGE_DOS_HEADER *dos;
  323. const IMAGE_VXD_HEADER *le;
  324. dos = PRD(0, sizeof(*dos));
  325. if (!dos) return;
  326. le = PRD(dos->e_lfanew, sizeof(*le));
  327. dump_le_header( le );
  328. dump_le_objects( le );
  329. dump_le_resources( le );
  330. dump_le_names( le );
  331. dump_le_entries( le );
  332. dump_le_modules( le );
  333. dump_le_fixups( le );
  334. dump_le_VxD( le );
  335. }