Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
6f1fd16f
Commit
6f1fd16f
authored
Feb 18, 2022
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winedump: Add dumping of the .apiset PE section.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4a5a3ba7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
123 additions
and
15 deletions
+123
-15
main.c
tools/winedump/main.c
+10
-9
pe.c
tools/winedump/pe.c
+107
-0
winedump.man.in
tools/winedump/winedump.man.in
+6
-6
No files found.
tools/winedump/main.c
View file @
6f1fd16f
...
@@ -207,7 +207,8 @@ static const struct my_option option_table[] = {
...
@@ -207,7 +207,8 @@ static const struct my_option option_table[] = {
{
"-C"
,
DUMP
,
0
,
do_symdmngl
,
"-C Turn on symbol demangling"
},
{
"-C"
,
DUMP
,
0
,
do_symdmngl
,
"-C Turn on symbol demangling"
},
{
"-f"
,
DUMP
,
0
,
do_dumphead
,
"-f Dump file header information"
},
{
"-f"
,
DUMP
,
0
,
do_dumphead
,
"-f Dump file header information"
},
{
"-G"
,
DUMP
,
0
,
do_rawdebug
,
"-G Dump raw debug 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"
},
{
"-t"
,
DUMP
,
0
,
do_symtable
,
"-t Dump symbol table"
},
{
"-x"
,
DUMP
,
0
,
do_dumpall
,
"-x Dump everything"
},
{
"-x"
,
DUMP
,
0
,
do_dumpall
,
"-x Dump everything"
},
{
"sym"
,
DMGL
,
0
,
do_demangle
,
"sym <sym> Demangle C++ symbol <sym> and exit"
},
{
"sym"
,
DMGL
,
0
,
do_demangle
,
"sym <sym> Demangle C++ symbol <sym> and exit"
},
...
@@ -232,22 +233,22 @@ void do_usage (const char *arg)
...
@@ -232,22 +233,22 @@ void do_usage (const char *arg)
const
struct
my_option
*
opt
;
const
struct
my_option
*
opt
;
printf
(
"Usage: winedump [-h | sym <sym> | spec <dll> | dump <file>]
\n
"
);
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
(
"Mode options (can be put as the mode (sym/spec/dump...) is declared):
\n
"
);
printf
(
"
\t
When used in --help mode
\n
"
);
printf
(
"
When used in --help mode
\n
"
);
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
if
(
opt
->
mode
==
NONE
)
if
(
opt
->
mode
==
NONE
)
printf
(
"
\t
%s
\n
"
,
opt
->
usage
);
printf
(
"
%s
\n
"
,
opt
->
usage
);
printf
(
"
\t
When used in sym mode
\n
"
);
printf
(
"
When used in sym mode
\n
"
);
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
if
(
opt
->
mode
==
DMGL
)
if
(
opt
->
mode
==
DMGL
)
printf
(
"
\t
%s
\n
"
,
opt
->
usage
);
printf
(
"
%s
\n
"
,
opt
->
usage
);
printf
(
"
\t
When used in spec mode
\n
"
);
printf
(
"
When used in spec mode
\n
"
);
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
if
(
opt
->
mode
==
SPEC
)
if
(
opt
->
mode
==
SPEC
)
printf
(
"
\t
%s
\n
"
,
opt
->
usage
);
printf
(
"
%s
\n
"
,
opt
->
usage
);
printf
(
"
\t
When used in dump mode
\n
"
);
printf
(
"
When used in dump mode
\n
"
);
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
for
(
opt
=
option_table
;
opt
->
name
;
opt
++
)
if
(
opt
->
mode
==
DUMP
)
if
(
opt
->
mode
==
DUMP
)
printf
(
"
\t
%s
\n
"
,
opt
->
usage
);
printf
(
"
%s
\n
"
,
opt
->
usage
);
puts
(
""
);
puts
(
""
);
exit
(
1
);
exit
(
1
);
...
...
tools/winedump/pe.c
View file @
6f1fd16f
...
@@ -491,6 +491,111 @@ static void dump_sections(const void *base, const void* addr, unsigned num_sect)
...
@@ -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
)
static
void
dump_dir_exported_functions
(
void
)
{
{
unsigned
int
size
=
0
;
unsigned
int
size
=
0
;
...
@@ -2336,6 +2441,8 @@ void pe_dump(void)
...
@@ -2336,6 +2441,8 @@ void pe_dump(void)
dump_dir_reloc
();
dump_dir_reloc
();
if
(
all
||
!
strcmp
(
globals
.
dumpsect
,
"except"
))
if
(
all
||
!
strcmp
(
globals
.
dumpsect
,
"except"
))
dump_dir_exceptions
();
dump_dir_exceptions
();
if
(
all
||
!
strcmp
(
globals
.
dumpsect
,
"apiset"
))
dump_section_apiset
();
}
}
if
(
globals
.
do_symbol_table
)
if
(
globals
.
do_symbol_table
)
dump_symbol_table
();
dump_symbol_table
();
...
...
tools/winedump/winedump.man.in
View file @
6f1fd16f
...
@@ -70,12 +70,12 @@ Dumps file header information.
...
@@ -70,12 +70,12 @@ Dumps file header information.
This option dumps only the standard PE header structures,
This option dumps only the standard PE header structures,
along with the COFF sections available in the file.
along with the COFF sections available in the file.
.IP "\fB-j \fIdir_name\fR"
.IP "\fB-j \fIdir_name\fR"
Dumps only the content of directory \fIdir_name\fR, for files
Dumps only the content of directory \fIdir_name\fR, for files
which
which header points to directories.
header points to directories. For PE files, the \fBimport\fR,
For PE files, currently the import, export, debug, resource
,
\fBexport\fR, \fBdebug\fR, \fBresource\fR, \fBtls\fR, \fBloadcfg\fR
,
tls and clr directories are implemented.
\fBclr\fR, \fBreloc\fR and \fBexcept\fR directories, as well as the
For NE files, currently the export and resource directories are
\fBapiset\fR section, are implemented. For NE files, the \fBexport\fR
implemented.
and \fBresource\fR directories are
implemented.
.IP \fB-x\fR
.IP \fB-x\fR
Dumps everything.
Dumps everything.
This command prints all available information (including all
This command prints all available information (including all
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment