00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <windows.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <process.h>
00029
00030
00031 #ifdef _ALPHA_
00032 #define e_magic_number IMAGE_FILE_MACHINE_ALPHA
00033 #else
00034 #define e_magic_number IMAGE_FILE_MACHINE_I386
00035 #endif
00036
00037 #define stricmp _stricmp
00038
00039
00040
00041
00042
00043
00044
00045
00046 int
00047 GetArgcArgv(char *s, char **argv)
00048 {
00049 int quote = 0;
00050 int argc = 0;
00051 char *bp;
00052
00053 bp = s;
00054 while (1) {
00055 while (isspace(*bp)) {
00056 bp++;
00057 }
00058 if (*bp == '\n' || *bp == '\0') {
00059 *bp = '\0';
00060 return argc;
00061 }
00062 if (*bp == '\"') {
00063 quote = 1;
00064 bp++;
00065 }
00066 argv[argc++] = bp;
00067
00068 while (*bp != '\0') {
00069 if (quote) {
00070 if (*bp == '\"') {
00071 quote = 0;
00072 *bp = '\0';
00073 bp++;
00074 break;
00075 }
00076 bp++;
00077 continue;
00078 }
00079 if (isspace(*bp)) {
00080 *bp = '\0';
00081 bp++;
00082 break;
00083 }
00084 bp++;
00085 }
00086 }
00087 }
00088
00089
00090
00091
00092 char * SzStorageClass1[] = {
00093 "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
00094 "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
00095 "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
00096 "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
00097 };
00098
00099
00100
00101
00102 char * SzStorageClass2[] = {
00103 "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
00104 };
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 PSTR
00115 GetSZStorageClass(BYTE storageClass)
00116 {
00117 if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
00118 return SzStorageClass1[storageClass];
00119 else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
00120 && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
00121 return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
00122 else
00123 return "???";
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 void
00138 GetSectionName(WORD section, PSTR buffer, unsigned cbBuffer)
00139 {
00140 char tempbuffer[10];
00141
00142 switch ( (SHORT)section )
00143 {
00144 case IMAGE_SYM_UNDEFINED: strcpy(tempbuffer, "UNDEF"); break;
00145 case IMAGE_SYM_ABSOLUTE: strcpy(tempbuffer, "ABS "); break;
00146 case IMAGE_SYM_DEBUG: strcpy(tempbuffer, "DEBUG"); break;
00147 default: wsprintf(tempbuffer, "%-5X", section);
00148 }
00149
00150 strncpy(buffer, tempbuffer, cbBuffer-1);
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 void
00162 DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
00163 {
00164 unsigned i;
00165 PSTR stringTable;
00166 char sectionName[10];
00167
00168 fprintf(fout, "Symbol Table - %X entries (* = auxillary symbol)\n",
00169 cSymbols);
00170
00171 fprintf(fout,
00172 "Indx Name Value Section cAux Type Storage\n"
00173 "---- -------------------- -------- ---------- ----- ------- --------\n");
00174
00175
00176
00177
00178 stringTable = (PSTR)&pSymbolTable[cSymbols];
00179
00180 for ( i=0; i < cSymbols; i++ ) {
00181 fprintf(fout, "%04X ", i);
00182 if ( pSymbolTable->N.Name.Short != 0 )
00183 fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
00184 else
00185 fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
00186
00187 fprintf(fout, " %08X", (unsigned int)pSymbolTable->Value);
00188
00189 GetSectionName(pSymbolTable->SectionNumber, sectionName,
00190 sizeof(sectionName));
00191 fprintf(fout, " sect:%s aux:%X type:%02X st:%s\n",
00192 sectionName,
00193 pSymbolTable->NumberOfAuxSymbols,
00194 pSymbolTable->Type,
00195 GetSZStorageClass(pSymbolTable->StorageClass) );
00196 #if 0
00197 if ( pSymbolTable->NumberOfAuxSymbols )
00198 DumpAuxSymbols(pSymbolTable);
00199 #endif
00200
00201
00202
00203
00204 i += pSymbolTable->NumberOfAuxSymbols;
00205 pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
00206 pSymbolTable++;
00207 }
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 void
00219 DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
00220 {
00221 unsigned i;
00222 PSTR stringTable;
00223 char *s, *f;
00224 char symbol[1024];
00225
00226
00227
00228
00229 stringTable = (PSTR)&pSymbolTable[cSymbols];
00230
00231 for ( i=0; i < cSymbols; i++ ) {
00232 if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
00233 if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
00234 if (pSymbolTable->N.Name.Short != 0) {
00235 strncpy(symbol, pSymbolTable->N.ShortName, 8);
00236 symbol[8] = 0;
00237 } else {
00238 s = stringTable + pSymbolTable->N.Name.Long;
00239 strcpy(symbol, s);
00240 }
00241 s = symbol;
00242 f = strchr(s, '@');
00243 if (f) {
00244 *f = 0;
00245 }
00246 #if defined(_MSC_VER) && defined(_X86_)
00247 if (symbol[0] == '_') {
00248 s = &symbol[1];
00249 }
00250 #endif
00251 if (( stricmp(s, "DllEntryPoint") != 0)
00252 && (stricmp(s, "DllMain") != 0)) {
00253 if ( s[0] != '?' )
00254 fprintf(fout, "\t%s\n", s);
00255 }
00256 }
00257 }
00258
00259
00260
00261
00262 i += pSymbolTable->NumberOfAuxSymbols;
00263 pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
00264 pSymbolTable++;
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 void
00277 DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full)
00278 {
00279 PIMAGE_SYMBOL PCOFFSymbolTable;
00280 DWORD COFFSymbolCount;
00281
00282 PCOFFSymbolTable = (PIMAGE_SYMBOL)
00283 ((DWORD)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
00284 COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
00285
00286 if (full) {
00287 DumpSymbolTable(PCOFFSymbolTable, fout, COFFSymbolCount);
00288 } else {
00289 DumpExternals(PCOFFSymbolTable, fout, COFFSymbolCount);
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 BYTE
00303 SkipToNextRecord(BYTE **ppBuffer)
00304 {
00305 int length;
00306 (*ppBuffer)++;
00307 length = *((WORD*)(*ppBuffer))++;
00308 *ppBuffer += length;
00309 return **ppBuffer;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 void
00321 DumpROMFObjFile(LPVOID pBuffer, FILE *fout)
00322 {
00323 BYTE type, length;
00324 char symbol[1024], *s;
00325
00326 while (1) {
00327 BYTE *loc = (BYTE*)pBuffer;
00328 type = SkipToNextRecord(&loc);
00329 if (type == 0x90) {
00330 if (((BYTE*)pBuffer)[4] != 0) {
00331 length = ((BYTE*)pBuffer)[5];
00332 strncpy(symbol, ((char*)pBuffer) + 6, length);
00333 symbol[length] = '\0';
00334 s = symbol;
00335 if ((stricmp(s, "DllEntryPoint") != 0)
00336 && (stricmp(s, "DllMain") != 0)) {
00337 if (s[0] == '_') {
00338 s++;
00339 fprintf(fout, "\t_%s\n\t%s=_%s\n", s, s, s);
00340 } else if (s[0] != '?' ) {
00341 fprintf(fout, "\t%s\n", s);
00342 }
00343 }
00344 }
00345 } else if (type == 0x8B || type == 0x8A) {
00346 break;
00347 }
00348 }
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 void
00360 DumpFile(LPSTR filename, FILE *fout, int full)
00361 {
00362 HANDLE hFile;
00363 HANDLE hFileMapping;
00364 LPVOID lpFileBase;
00365 PIMAGE_DOS_HEADER dosHeader;
00366
00367 hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
00368 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
00369
00370 if (hFile == INVALID_HANDLE_VALUE) {
00371 fprintf(stderr, "Couldn't open file with CreateFile()\n");
00372 return;
00373 }
00374
00375 hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
00376 if (hFileMapping == 0) {
00377 CloseHandle(hFile);
00378 fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
00379 return;
00380 }
00381
00382 lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
00383 if (lpFileBase == 0) {
00384 CloseHandle(hFileMapping);
00385 CloseHandle(hFile);
00386 fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
00387 return;
00388 }
00389
00390 dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
00391 if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
00392 #if 0
00393 DumpExeFile( dosHeader );
00394 #else
00395 fprintf(stderr, "File is an executable. I don't dump those.\n");
00396 return;
00397 #endif
00398 }
00399
00400 else if ((dosHeader->e_magic == e_magic_number)
00401 && (dosHeader->e_sp == 0)) {
00402
00403
00404
00405
00406
00407 DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full);
00408 } else if (*((BYTE *)lpFileBase) == 0x80) {
00409
00410
00411
00412 DumpROMFObjFile(lpFileBase, fout);
00413 } else {
00414 printf("unrecognized file format\n");
00415 }
00416 UnmapViewOfFile(lpFileBase);
00417 CloseHandle(hFileMapping);
00418 CloseHandle(hFile);
00419 }
00420
00421 int main(int argc, char **argv)
00422 {
00423 int noheader = 0;
00424 char *fargv[1000];
00425 char cmdline[10000];
00426 int i, arg;
00427 FILE *fout;
00428 int pos;
00429 int full = 0;
00430 char *outfile = NULL;
00431
00432 if (argc < 3) {
00433 Usage:
00434 fprintf(stderr, "Usage: %s ?-o outfile? ?-n? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
00435 exit(1);
00436 }
00437
00438 arg = 1;
00439 while (argv[arg][0] == '-') {
00440 if (strcmp(argv[arg], "--") == 0) {
00441 arg++;
00442 break;
00443 } else if (strcmp(argv[arg], "-f") == 0) {
00444 full = 1;
00445 } else if (strcmp(argv[arg], "-n") == 0) {
00446 noheader = 1;
00447 } else if (strcmp(argv[arg], "-o") == 0) {
00448 arg++;
00449 if (arg == argc) {
00450 goto Usage;
00451 }
00452 outfile = argv[arg];
00453 }
00454 arg++;
00455 }
00456 if (arg == argc) {
00457 goto Usage;
00458 }
00459
00460 if (outfile) {
00461 fout = fopen(outfile, "w+");
00462 if (fout == NULL) {
00463 fprintf(stderr, "Unable to open \'%s\' for writing:\n",
00464 argv[arg]);
00465 perror("");
00466 exit(1);
00467 }
00468 } else {
00469 fout = stdout;
00470 }
00471
00472 if (! full) {
00473 char *dllname = argv[arg];
00474 arg++;
00475 if (arg == argc) {
00476 goto Usage;
00477 }
00478 if (noheader != 1)
00479 {
00480 fprintf(fout, "LIBRARY %s\n", dllname);
00481
00482
00483
00484
00485 fprintf(fout, "EXPORTS\n");
00486 }
00487 }
00488
00489 for (; arg < argc; arg++) {
00490 if (argv[arg][0] == '@') {
00491 FILE *fargs = fopen(&argv[arg][1], "r");
00492 if (fargs == NULL) {
00493 fprintf(stderr, "Unable to open \'%s\' for reading:\n",
00494 argv[arg]);
00495 perror("");
00496 exit(1);
00497 }
00498 pos = 0;
00499 for (i = 0; i < arg; i++) {
00500 strcpy(&cmdline[pos], argv[i]);
00501 pos += strlen(&cmdline[pos]) + 1;
00502 fargv[i] = argv[i];
00503 }
00504 fgets(&cmdline[pos], sizeof(cmdline), fargs);
00505 fprintf(stderr, "%s\n", &cmdline[pos]);
00506 fclose(fargs);
00507 i += GetArgcArgv(&cmdline[pos], &fargv[i]);
00508 argc = i;
00509 argv = fargv;
00510 }
00511 DumpFile(argv[arg], fout, full);
00512 }
00513 exit(0);
00514 return 0;
00515 }