Alexandre Julliard : winedump: Add dumping of the .apiset PE section.

Alexandre Julliard julliard at winehq.org
Fri Feb 18 15:14:59 CST 2022


Module: wine
Branch: master
Commit: 6f1fd16f92ccbc41999878fce1dc16c9d4d4e283
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6f1fd16f92ccbc41999878fce1dc16c9d4d4e283

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Feb 18 10:00:55 2022 +0100

winedump: Add dumping of the .apiset PE section.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 tools/winedump/main.c          |  19 ++++----
 tools/winedump/pe.c            | 107 +++++++++++++++++++++++++++++++++++++++++
 tools/winedump/winedump.man.in |  12 ++---
 3 files changed, 123 insertions(+), 15 deletions(-)

diff --git a/tools/winedump/main.c b/tools/winedump/main.c
index fd5b44d637d..f9557983465 100644
--- a/tools/winedump/main.c
+++ b/tools/winedump/main.c
@@ -207,7 +207,8 @@ static const struct my_option option_table[] = {
   {"-C",    DUMP, 0, do_symdmngl, "-C              Turn on symbol demangling"},
   {"-f",    DUMP, 0, do_dumphead, "-f              Dump file header information"},
   {"-G",    DUMP, 0, do_rawdebug, "-G              Dump raw debug information"},
-  {"-j",    DUMP, 1, do_dumpsect, "-j <sect_name>  Dump only the content of section 'sect_name' (import, export, debug, resource, tls, loadcfg, clr, reloc, except)"},
+  {"-j",    DUMP, 1, do_dumpsect, "-j <sect_name>  Dump only the content of section 'sect_name'\n"
+                            "                        (import, export, debug, resource, tls, loadcfg, clr, reloc, except, apiset)"},
   {"-t",    DUMP, 0, do_symtable, "-t              Dump symbol table"},
   {"-x",    DUMP, 0, do_dumpall,  "-x              Dump everything"},
   {"sym",   DMGL, 0, do_demangle, "sym <sym>       Demangle C++ symbol <sym> and exit"},
@@ -232,22 +233,22 @@ void do_usage (const char *arg)
     const struct my_option *opt;
     printf ("Usage: winedump [-h | sym <sym> | spec <dll> | dump <file>]\n");
     printf ("Mode options (can be put as the mode (sym/spec/dump...) is declared):\n");
-    printf ("\tWhen used in --help mode\n");
+    printf ("   When used in --help mode\n");
     for (opt = option_table; opt->name; opt++)
 	if (opt->mode == NONE)
-	    printf ("\t   %s\n", opt->usage);
-    printf ("\tWhen used in sym mode\n");
+	    printf ("      %s\n", opt->usage);
+    printf ("   When used in sym mode\n");
     for (opt = option_table; opt->name; opt++)
 	if (opt->mode == DMGL)
-	    printf ("\t   %s\n", opt->usage);
-    printf ("\tWhen used in spec mode\n");
+	    printf ("      %s\n", opt->usage);
+    printf ("   When used in spec mode\n");
     for (opt = option_table; opt->name; opt++)
 	if (opt->mode == SPEC)
-	    printf ("\t   %s\n", opt->usage);
-    printf ("\tWhen used in dump mode\n");
+	    printf ("      %s\n", opt->usage);
+    printf ("   When used in dump mode\n");
     for (opt = option_table; opt->name; opt++)
 	if (opt->mode == DUMP)
-	    printf ("\t   %s\n", opt->usage);
+	    printf ("      %s\n", opt->usage);
 
     puts ("");
     exit (1);
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c
index 6ff14f95791..2207ed9accc 100644
--- a/tools/winedump/pe.c
+++ b/tools/winedump/pe.c
@@ -491,6 +491,111 @@ static void dump_sections(const void *base, const void* addr, unsigned num_sect)
     }
 }
 
+static char *get_str( char *buffer, unsigned int rva, unsigned int len )
+{
+    const WCHAR *wstr = PRD( rva, len );
+    char *ret = buffer;
+
+    len /= sizeof(WCHAR);
+    while (len--) *buffer++ = *wstr++;
+    *buffer = 0;
+    return ret;
+}
+
+static void dump_section_apiset(void)
+{
+    const IMAGE_SECTION_HEADER *sect = IMAGE_FIRST_SECTION(PE_nt_headers);
+    const UINT *ptr, *entry, *value, *hash;
+    unsigned int i, j, count, val_count, rva;
+    char buffer[128];
+
+    for (i = 0; i < PE_nt_headers->FileHeader.NumberOfSections; i++, sect++)
+    {
+        if (strncmp( (const char *)sect->Name, ".apiset", 8 )) continue;
+        rva = sect->PointerToRawData;
+        ptr = PRD( rva, sizeof(*ptr) );
+        printf( "ApiSet section:\n" );
+        switch (ptr[0]) /* version */
+        {
+        case 2:
+            printf( "  Version:     %u\n",   ptr[0] );
+            printf( "  Count:       %08x\n", ptr[1] );
+            count = ptr[1];
+            if (!(entry = PRD( rva + 2 * sizeof(*ptr), count * 3 * sizeof(*entry) ))) break;
+            for (i = 0; i < count; i++, entry += 3)
+            {
+                printf( "    %s ->", get_str( buffer, rva + entry[0], entry[1] ));
+                if (!(value = PRD( rva + entry[2], sizeof(*value) ))) break;
+                val_count = *value++;
+                for (j = 0; j < val_count; j++, value += 4)
+                {
+                    putchar( ' ' );
+                    if (value[1]) printf( "%s:", get_str( buffer, rva + value[0], value[1] ));
+                    printf( "%s", get_str( buffer, rva + value[2], value[3] ));
+                }
+                printf( "\n");
+            }
+            break;
+        case 4:
+            printf( "  Version:     %u\n",   ptr[0] );
+            printf( "  Size:        %08x\n", ptr[1] );
+            printf( "  Flags:       %08x\n", ptr[2] );
+            printf( "  Count:       %08x\n", ptr[3] );
+            count = ptr[3];
+            if (!(entry = PRD( rva + 4 * sizeof(*ptr), count * 6 * sizeof(*entry) ))) break;
+            for (i = 0; i < count; i++, entry += 6)
+            {
+                printf( "    %08x %s ->", entry[0], get_str( buffer, rva + entry[1], entry[2] ));
+                if (!(value = PRD( rva + entry[5], sizeof(*value) ))) break;
+                value++; /* flags */
+                val_count = *value++;
+                for (j = 0; j < val_count; j++, value += 5)
+                {
+                    putchar( ' ' );
+                    if (value[1]) printf( "%s:", get_str( buffer, rva + value[1], value[2] ));
+                    printf( "%s", get_str( buffer, rva + value[3], value[4] ));
+                }
+                printf( "\n");
+            }
+            break;
+        case 6:
+            printf( "  Version:     %u\n",   ptr[0] );
+            printf( "  Size:        %08x\n", ptr[1] );
+            printf( "  Flags:       %08x\n", ptr[2] );
+            printf( "  Count:       %08x\n", ptr[3] );
+            printf( "  EntryOffset: %08x\n", ptr[4] );
+            printf( "  HashOffset:  %08x\n", ptr[5] );
+            printf( "  HashFactor:  %08x\n", ptr[6] );
+            count = ptr[3];
+            if (!(entry = PRD( rva + ptr[4], count * 6 * sizeof(*entry) ))) break;
+            for (i = 0; i < count; i++, entry += 6)
+            {
+                printf( "    %08x %s ->", entry[0], get_str( buffer, rva + entry[1], entry[2] ));
+                if (!(value = PRD( rva + entry[4], entry[5] * 5 * sizeof(*value) ))) break;
+                for (j = 0; j < entry[5]; j++, value += 5)
+                {
+                    putchar( ' ' );
+                    if (value[1]) printf( "%s:", get_str( buffer, rva + value[1], value[2] ));
+                    printf( "%s", get_str( buffer, rva + value[3], value[4] ));
+                }
+                printf( "\n" );
+            }
+            printf( "  Hash table:\n" );
+            if (!(hash = PRD( rva + ptr[5], count * 2 * sizeof(*hash) ))) break;
+            for (i = 0; i < count; i++, hash += 2)
+            {
+                entry = PRD( rva + ptr[4] + hash[1] * 6 * sizeof(*entry), 6 * sizeof(*entry) );
+                printf( "    %08x -> %s\n", hash[0], get_str( buffer, rva + entry[1], entry[3] ));
+            }
+            break;
+        default:
+            printf( "*** Unknown version %u\n", ptr[0] );
+            break;
+        }
+        break;
+    }
+}
+
 static	void	dump_dir_exported_functions(void)
 {
     unsigned int size = 0;
@@ -2336,6 +2441,8 @@ void pe_dump(void)
 	    dump_dir_reloc();
 	if (all || !strcmp(globals.dumpsect, "except"))
 	    dump_dir_exceptions();
+	if (all || !strcmp(globals.dumpsect, "apiset"))
+	    dump_section_apiset();
     }
     if (globals.do_symbol_table)
         dump_symbol_table();
diff --git a/tools/winedump/winedump.man.in b/tools/winedump/winedump.man.in
index a915ff49225..56460f26e7c 100644
--- a/tools/winedump/winedump.man.in
+++ b/tools/winedump/winedump.man.in
@@ -70,12 +70,12 @@ Dumps file header information.
 This option dumps only the standard PE header structures,
 along with the COFF sections available in the file.
 .IP "\fB-j \fIdir_name\fR"
-Dumps only the content of directory \fIdir_name\fR, for files
-which header points to directories.
-For PE files, currently the import, export, debug, resource,
-tls and clr directories are implemented.
-For NE files, currently the export and resource directories are
-implemented.
+Dumps only the content of directory \fIdir_name\fR, for files which
+header points to directories.  For PE files, the \fBimport\fR,
+\fBexport\fR, \fBdebug\fR, \fBresource\fR, \fBtls\fR, \fBloadcfg\fR,
+\fBclr\fR, \fBreloc\fR and \fBexcept\fR directories, as well as the
+\fBapiset\fR section, are implemented.  For NE files, the \fBexport\fR
+and \fBresource\fR directories are implemented.
 .IP \fB-x\fR
 Dumps everything.
 This command prints all available information (including all




More information about the wine-cvs mailing list