2 * Dumping of NE binaries
4 * Copyright 2002 Alexandre Julliard
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
33 #include "wine/winbase16.h"
36 static inline WORD
get_word( const BYTE
*ptr
)
38 return ptr
[0] | (ptr
[1] << 8);
41 static void dump_ne_header( const IMAGE_OS2_HEADER
*ne
)
43 printf( "File header:\n" );
44 printf( "Linker version: %d.%d\n", ne
->ne_ver
, ne
->ne_rev
);
45 printf( "Entry table: %x len %d\n", ne
->ne_enttab
, ne
->ne_cbenttab
);
46 printf( "Checksum: %08lx\n", ne
->ne_crc
);
47 printf( "Flags: %04x\n", ne
->ne_flags
);
48 printf( "Auto data segment: %x\n", ne
->ne_autodata
);
49 printf( "Heap size: %d bytes\n", ne
->ne_heap
);
50 printf( "Stack size: %d bytes\n", ne
->ne_stack
);
51 printf( "Stack pointer: %x:%04x\n", SELECTOROF(ne
->ne_sssp
), OFFSETOF(ne
->ne_sssp
) );
52 printf( "Entry point: %x:%04x\n", SELECTOROF(ne
->ne_csip
), OFFSETOF(ne
->ne_csip
) );
53 printf( "Number of segments: %d\n", ne
->ne_cseg
);
54 printf( "Number of modrefs: %d\n", ne
->ne_cmod
);
55 printf( "Segment table: %x\n", ne
->ne_segtab
);
56 printf( "Resource table: %x\n", ne
->ne_rsrctab
);
57 printf( "Resident name table: %x\n", ne
->ne_restab
);
58 printf( "Module table: %x\n", ne
->ne_modtab
);
59 printf( "Import table: %x\n", ne
->ne_imptab
);
60 printf( "Non-resident table: %lx\n", ne
->ne_nrestab
);
61 printf( "Exe type: %x\n", ne
->ne_exetyp
);
62 printf( "Other flags: %x\n", ne
->ne_flagsothers
);
63 printf( "Fast load area: %x-%x\n", ne
->ne_pretthunks
<< ne
->ne_align
,
64 (ne
->ne_pretthunks
+ne
->ne_psegrefbytes
) << ne
->ne_align
);
65 printf( "Expected version: %d.%d\n", HIBYTE(ne
->ne_expver
), LOBYTE(ne
->ne_expver
) );
68 static void dump_ne_names( const void *base
, const IMAGE_OS2_HEADER
*ne
)
70 char *pstr
= (char *)ne
+ ne
->ne_restab
;
72 printf( "\nResident name table:\n" );
75 printf( " %4d: %*.*s\n", get_word(pstr
+ *pstr
+ 1), *pstr
, *pstr
, pstr
+ 1 );
76 pstr
+= *pstr
+ 1 + sizeof(WORD
);
80 printf( "\nNon-resident name table:\n" );
81 pstr
= (char *)base
+ ne
->ne_nrestab
;
84 printf( " %4d: %*.*s\n", get_word(pstr
+ *pstr
+ 1), *pstr
, *pstr
, pstr
+ 1 );
85 pstr
+= *pstr
+ 1 + sizeof(WORD
);
90 static const char *get_resource_type( WORD id
)
92 static char buffer
[5];
95 case NE_RSCTYPE_CURSOR
: return "CURSOR";
96 case NE_RSCTYPE_BITMAP
: return "BITMAP";
97 case NE_RSCTYPE_ICON
: return "ICON";
98 case NE_RSCTYPE_MENU
: return "MENU";
99 case NE_RSCTYPE_DIALOG
: return "DIALOG";
100 case NE_RSCTYPE_STRING
: return "STRING";
101 case NE_RSCTYPE_FONTDIR
: return "FONTDIR";
102 case NE_RSCTYPE_FONT
: return "FONT";
103 case NE_RSCTYPE_ACCELERATOR
: return "ACCELERATOR";
104 case NE_RSCTYPE_RCDATA
: return "RCDATA";
105 case NE_RSCTYPE_GROUP_CURSOR
: return "CURSOR_GROUP";
106 case NE_RSCTYPE_GROUP_ICON
: return "ICON_GROUP";
108 sprintf( buffer
, "%04x", id
);
113 static void dump_ne_resources( const void *base
, const IMAGE_OS2_HEADER
*ne
)
116 const void *res_ptr
= (char *)ne
+ ne
->ne_rsrctab
;
117 WORD size_shift
= get_word(res_ptr
);
118 NE_TYPEINFO
*info
= (NE_TYPEINFO
*)((WORD
*)res_ptr
+ 1);
121 printf( "\nResources:\n" );
122 while (info
->type_id
!= 0 && (char *)info
< (char *)ne
+ ne
->ne_restab
)
124 name
= (NE_NAMEINFO
*)(info
+ 1);
125 for (count
= info
->count
; count
> 0; count
--, name
++)
127 if (name
->id
& 0x8000) printf( " %d", (name
->id
& ~0x8000) );
128 else printf( " %.*s", *((unsigned char *)res_ptr
+ name
->id
),
129 (char *)res_ptr
+ name
->id
+ 1 );
130 if (info
->type_id
& 0x8000) printf( " %s\n", get_resource_type(info
->type_id
) );
131 else printf( " %.*s\n", *((unsigned char *)res_ptr
+ info
->type_id
),
132 (char *)res_ptr
+ info
->type_id
+ 1 );
133 dump_data( (unsigned char *)base
+ (name
->offset
<< size_shift
),
134 name
->length
<< size_shift
, " " );
136 info
= (NE_TYPEINFO
*)name
;
140 static const char *get_export_name( const void *base
, const IMAGE_OS2_HEADER
*ne
, int ordinal
)
142 static char name
[256];
146 /* search the resident names */
150 if (pass
== 0) /* resident names */
152 pstr
= (BYTE
*)ne
+ ne
->ne_restab
;
153 if (*pstr
) pstr
+= *pstr
+ 1 + sizeof(WORD
); /* skip first entry (module name) */
155 else /* non-resident names */
157 if (!ne
->ne_cbnrestab
) break;
158 pstr
= (BYTE
*)base
+ ne
->ne_nrestab
;
162 WORD ord
= get_word(pstr
+ *pstr
+ 1);
165 memcpy( name
, pstr
+ 1, *pstr
);
169 pstr
+= *pstr
+ 1 + sizeof(WORD
);
177 static void dump_ne_exports( const void *base
, const IMAGE_OS2_HEADER
*ne
)
179 BYTE
*ptr
= (BYTE
*)ne
+ ne
->ne_enttab
;
180 BYTE
*end
= ptr
+ ne
->ne_cbenttab
;
183 if (!ne
->ne_cbenttab
|| !*ptr
) return;
185 printf( "\nExported entry points:\n" );
187 while (ptr
< end
&& *ptr
)
193 case 0: /* next bundle */
196 case 0xff: /* movable */
197 for (i
= 0; i
< count
; i
++)
199 printf( " %4d MOVABLE %d:%04x %s\n",
200 ordinal
+ i
, ptr
[3], get_word(ptr
+ 4),
201 get_export_name( base
, ne
, ordinal
+ i
) );
206 case 0xfe: /* constant */
207 for (i
= 0; i
< count
; i
++)
209 printf( " %4d CONST %04x %s\n",
210 ordinal
+ i
, get_word(ptr
+ 1),
211 get_export_name( base
, ne
, ordinal
+ i
) );
217 for (i
= 0; i
< count
; i
++)
219 printf( " %4d FIXED %d:%04x %s\n",
220 ordinal
+ i
, type
, get_word(ptr
+ 1),
221 get_export_name( base
, ne
, ordinal
+ i
) );
230 void ne_dump( const void *exe
, size_t exe_size
)
232 const IMAGE_DOS_HEADER
*dos
= exe
;
233 const IMAGE_OS2_HEADER
*ne
= (IMAGE_OS2_HEADER
*)((char *)dos
+ dos
->e_lfanew
);
235 dump_ne_header( ne
);
236 dump_ne_names( exe
, ne
);
237 dump_ne_resources( exe
, ne
);
238 dump_ne_exports( exe
, ne
);