Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
ea331926
Commit
ea331926
authored
Feb 11, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Report load dll events upon mapping a SEC_IMAGE view.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4f2ed66a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
53 deletions
+100
-53
debugger.c
dlls/kernel32/tests/debugger.c
+47
-1
debugger.c
server/debugger.c
+3
-38
mapping.c
server/mapping.c
+50
-10
process.c
server/process.c
+0
-4
No files found.
dlls/kernel32/tests/debugger.c
View file @
ea331926
...
...
@@ -26,6 +26,7 @@
#include <windows.h>
#include <winternl.h>
#include <winreg.h>
#include <psapi.h>
#include "wine/test.h"
#include "wine/heap.h"
#include "wine/rbtree.h"
...
...
@@ -828,7 +829,9 @@ static void doChild(int argc, char **argv)
{
struct
child_blackbox
blackbox
;
const
char
*
blackbox_file
;
HANDLE
parent
;
WCHAR
path
[
MAX_PATH
];
HMODULE
mod
;
HANDLE
parent
,
file
,
map
;
DWORD
ppid
;
BOOL
debug
;
BOOL
ret
;
...
...
@@ -876,10 +879,49 @@ static void doChild(int argc, char **argv)
NtCurrentTeb
()
->
Peb
->
BeingDebugged
=
TRUE
;
mod
=
LoadLibraryW
(
L"ole32.dll"
);
FreeLibrary
(
mod
);
GetSystemDirectoryW
(
path
,
MAX_PATH
);
wcscat
(
path
,
L"
\\
oleaut32.dll"
);
file
=
CreateFileW
(
path
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
0
,
0
);
child_ok
(
file
!=
INVALID_HANDLE_VALUE
,
"failed to open %s: %u
\n
"
,
debugstr_w
(
path
),
GetLastError
());
map
=
CreateFileMappingW
(
file
,
NULL
,
SEC_IMAGE
|
PAGE_READONLY
,
0
,
0
,
NULL
);
child_ok
(
map
!=
NULL
,
"failed to create mapping %s: %u
\n
"
,
debugstr_w
(
path
),
GetLastError
()
);
mod
=
MapViewOfFile
(
map
,
FILE_MAP_READ
,
0
,
0
,
0
);
child_ok
(
mod
!=
NULL
,
"failed to map %s: %u
\n
"
,
debugstr_w
(
path
),
GetLastError
()
);
CloseHandle
(
file
);
CloseHandle
(
map
);
UnmapViewOfFile
(
mod
);
blackbox
.
failures
=
child_failures
;
save_blackbox
(
blackbox_file
,
&
blackbox
,
sizeof
(
blackbox
),
NULL
);
}
static
HMODULE
ole32_mod
,
oleaut32_mod
;
static
void
check_dll_event
(
HANDLE
process
,
DEBUG_EVENT
*
ev
)
{
WCHAR
*
p
,
module
[
MAX_PATH
];
switch
(
ev
->
dwDebugEventCode
)
{
case
CREATE_PROCESS_DEBUG_EVENT
:
break
;
case
LOAD_DLL_DEBUG_EVENT
:
if
(
!
GetMappedFileNameW
(
process
,
ev
->
u
.
LoadDll
.
lpBaseOfDll
,
module
,
MAX_PATH
))
module
[
0
]
=
0
;
if
((
p
=
wcsrchr
(
module
,
'\\'
)))
p
++
;
else
p
=
module
;
if
(
!
wcsicmp
(
p
,
L"ole32.dll"
))
ole32_mod
=
ev
->
u
.
LoadDll
.
lpBaseOfDll
;
else
if
(
!
wcsicmp
(
p
,
L"oleaut32.dll"
))
oleaut32_mod
=
ev
->
u
.
LoadDll
.
lpBaseOfDll
;
break
;
case
UNLOAD_DLL_DEBUG_EVENT
:
if
(
ev
->
u
.
UnloadDll
.
lpBaseOfDll
==
ole32_mod
)
ole32_mod
=
(
HMODULE
)
1
;
if
(
ev
->
u
.
UnloadDll
.
lpBaseOfDll
==
oleaut32_mod
)
oleaut32_mod
=
(
HMODULE
)
1
;
break
;
}
}
static
void
test_debug_loop
(
int
argc
,
char
**
argv
)
{
const
char
*
arguments
=
" debugger child "
;
...
...
@@ -926,6 +968,7 @@ static void test_debug_loop(int argc, char **argv)
if
(
!
ret
)
break
;
if
(
ev
.
dwDebugEventCode
==
EXIT_PROCESS_DEBUG_EVENT
)
break
;
check_dll_event
(
pi
.
hProcess
,
&
ev
);
#if defined(__i386__) || defined(__x86_64__)
if
(
ev
.
dwDebugEventCode
==
EXCEPTION_DEBUG_EVENT
&&
ev
.
u
.
Exception
.
ExceptionRecord
.
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
...
...
@@ -940,6 +983,9 @@ static void test_debug_loop(int argc, char **argv)
if
(
!
ret
)
break
;
}
ok
(
ole32_mod
==
(
HMODULE
)
1
,
"ole32.dll was not reported
\n
"
);
ok
(
oleaut32_mod
==
(
HMODULE
)
1
,
"oleaut32.dll was not reported
\n
"
);
ret
=
CloseHandle
(
pi
.
hThread
);
ok
(
ret
,
"CloseHandle failed, last error %#x.
\n
"
,
GetLastError
());
ret
=
CloseHandle
(
pi
.
hProcess
);
...
...
server/debugger.c
View file @
ea331926
...
...
@@ -181,9 +181,7 @@ static void fill_exit_process_event( struct debug_event *event, const void *arg
static
void
fill_load_dll_event
(
struct
debug_event
*
event
,
const
void
*
arg
)
{
struct
process
*
process
=
event
->
sender
->
process
;
const
struct
process_dll
*
dll
=
arg
;
struct
memory_view
*
view
=
find_mapped_view
(
process
,
dll
->
base
);
const
struct
memory_view
*
view
=
arg
;
const
pe_image_info_t
*
image_info
=
get_view_image_info
(
view
,
&
event
->
data
.
load_dll
.
base
);
event
->
data
.
load_dll
.
dbg_offset
=
image_info
->
dbg_offset
;
...
...
@@ -194,8 +192,8 @@ static void fill_load_dll_event( struct debug_event *event, const void *arg )
static
void
fill_unload_dll_event
(
struct
debug_event
*
event
,
const
void
*
arg
)
{
const
mod_handle_t
*
base
=
arg
;
event
->
data
.
unload_dll
.
base
=
*
base
;
const
struct
memory_view
*
view
=
arg
;
get_view_image_info
(
view
,
&
event
->
data
.
unload_dll
.
base
)
;
}
typedef
void
(
*
fill_event_func
)(
struct
debug_event
*
event
,
const
void
*
arg
);
...
...
@@ -534,39 +532,6 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj )
resume_process
(
process
);
}
/* generate all startup events of a given process */
void
generate_startup_debug_events
(
struct
process
*
process
)
{
struct
list
*
ptr
;
struct
memory_view
*
view
=
get_exe_view
(
process
);
struct
thread
*
thread
,
*
first_thread
=
get_process_first_thread
(
process
);
if
(
!
view
)
return
;
generate_debug_event
(
first_thread
,
DbgCreateProcessStateChange
,
view
);
ptr
=
list_head
(
&
process
->
dlls
);
/* skip main module reported in create process event */
/* generate ntdll.dll load event */
if
(
ptr
&&
(
ptr
=
list_next
(
&
process
->
dlls
,
ptr
)))
{
struct
process_dll
*
dll
=
LIST_ENTRY
(
ptr
,
struct
process_dll
,
entry
);
generate_debug_event
(
first_thread
,
DbgLoadDllStateChange
,
dll
);
}
/* generate creation events */
LIST_FOR_EACH_ENTRY
(
thread
,
&
process
->
thread_list
,
struct
thread
,
proc_entry
)
{
if
(
thread
!=
first_thread
)
generate_debug_event
(
thread
,
DbgCreateThreadStateChange
,
NULL
);
}
/* generate dll events (in loading order) */
while
(
ptr
&&
(
ptr
=
list_next
(
&
process
->
dlls
,
ptr
)))
{
struct
process_dll
*
dll
=
LIST_ENTRY
(
ptr
,
struct
process_dll
,
entry
);
generate_debug_event
(
first_thread
,
DbgLoadDllStateChange
,
dll
);
}
}
/* create a debug object */
DECL_HANDLER
(
create_debug_obj
)
{
...
...
server/mapping.c
View file @
ea331926
...
...
@@ -348,11 +348,15 @@ struct memory_view *get_exe_view( struct process *process )
}
/* add a view to the process list */
static
void
add_process_view
(
struct
process
*
process
,
struct
memory_view
*
view
)
static
void
add_process_view
(
struct
thread
*
thread
,
struct
memory_view
*
view
)
{
struct
process
*
process
=
thread
->
process
;
if
(
view
->
flags
&
SEC_IMAGE
)
{
if
(
!
is_process_init_done
(
process
)
&&
!
(
view
->
image
.
image_charact
&
IMAGE_FILE_DLL
))
if
(
is_process_init_done
(
process
))
generate_debug_event
(
thread
,
DbgLoadDllStateChange
,
view
);
else
if
(
!
(
view
->
image
.
image_charact
&
IMAGE_FILE_DLL
))
{
/* main exe */
list_add_head
(
&
process
->
views
,
&
view
->
entry
);
...
...
@@ -1001,6 +1005,42 @@ int get_view_nt_name( const struct memory_view *view, struct unicode_str *name )
return
1
;
}
/* generate all startup events of a given process */
void
generate_startup_debug_events
(
struct
process
*
process
)
{
struct
memory_view
*
view
;
struct
list
*
ptr
=
list_head
(
&
process
->
views
);
struct
thread
*
thread
,
*
first_thread
=
get_process_first_thread
(
process
);
if
(
!
ptr
)
return
;
view
=
LIST_ENTRY
(
ptr
,
struct
memory_view
,
entry
);
generate_debug_event
(
first_thread
,
DbgCreateProcessStateChange
,
view
);
/* generate ntdll.dll load event */
while
(
ptr
&&
(
ptr
=
list_next
(
&
process
->
views
,
ptr
)))
{
view
=
LIST_ENTRY
(
ptr
,
struct
memory_view
,
entry
);
if
(
!
(
view
->
flags
&
SEC_IMAGE
))
continue
;
generate_debug_event
(
first_thread
,
DbgLoadDllStateChange
,
view
);
break
;
}
/* generate creation events */
LIST_FOR_EACH_ENTRY
(
thread
,
&
process
->
thread_list
,
struct
thread
,
proc_entry
)
{
if
(
thread
!=
first_thread
)
generate_debug_event
(
thread
,
DbgCreateThreadStateChange
,
NULL
);
}
/* generate dll events (in loading order) */
while
(
ptr
&&
(
ptr
=
list_next
(
&
process
->
views
,
ptr
)))
{
view
=
LIST_ENTRY
(
ptr
,
struct
memory_view
,
entry
);
if
(
!
(
view
->
flags
&
SEC_IMAGE
))
continue
;
generate_debug_event
(
first_thread
,
DbgLoadDllStateChange
,
view
);
}
}
static
void
mapping_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
mapping
*
mapping
=
(
struct
mapping
*
)
obj
;
...
...
@@ -1142,7 +1182,7 @@ DECL_HANDLER(map_view)
view
->
start
=
req
->
start
;
view
->
flags
=
SEC_IMAGE
;
memcpy
(
&
view
->
image
,
get_req_data
(),
min
(
sizeof
(
view
->
image
),
get_req_data_size
()
));
add_process_view
(
current
->
process
,
view
);
add_process_view
(
current
,
view
);
return
;
}
...
...
@@ -1173,12 +1213,10 @@ DECL_HANDLER(map_view)
view
->
fd
=
!
is_fd_removable
(
mapping
->
fd
)
?
(
struct
fd
*
)
grab_object
(
mapping
->
fd
)
:
NULL
;
view
->
committed
=
mapping
->
committed
?
(
struct
ranges
*
)
grab_object
(
mapping
->
committed
)
:
NULL
;
view
->
shared
=
mapping
->
shared
?
(
struct
shared_map
*
)
grab_object
(
mapping
->
shared
)
:
NULL
;
if
(
mapping
->
flags
&
SEC_IMAGE
)
{
view
->
image
=
mapping
->
image
;
if
(
view
->
base
!=
mapping
->
image
.
base
)
set_error
(
STATUS_IMAGE_NOT_AT_BASE
);
}
add_process_view
(
current
->
process
,
view
);
if
(
view
->
flags
&
SEC_IMAGE
)
view
->
image
=
mapping
->
image
;
add_process_view
(
current
,
view
);
if
(
view
->
flags
&
SEC_IMAGE
&&
view
->
base
!=
mapping
->
image
.
base
)
set_error
(
STATUS_IMAGE_NOT_AT_BASE
);
}
done
:
...
...
@@ -1190,7 +1228,9 @@ DECL_HANDLER(unmap_view)
{
struct
memory_view
*
view
=
find_mapped_view
(
current
->
process
,
req
->
base
);
if
(
view
)
free_memory_view
(
view
);
if
(
!
view
)
return
;
if
(
view
->
flags
&
SEC_IMAGE
)
generate_debug_event
(
current
,
DbgUnloadDllStateChange
,
view
);
free_memory_view
(
view
);
}
/* get a range of committed pages in a file mapping */
...
...
server/process.c
View file @
ea331926
...
...
@@ -832,7 +832,6 @@ static void process_unload_dll( struct process *process, mod_handle_t base )
free
(
dll
->
filename
);
list_remove
(
&
dll
->
entry
);
free
(
dll
);
generate_debug_event
(
current
,
DbgUnloadDllStateChange
,
&
base
);
}
else
set_error
(
STATUS_INVALID_PARAMETER
);
}
...
...
@@ -1602,9 +1601,6 @@ DECL_HANDLER(load_dll)
if
((
dll
=
process_load_dll
(
current
->
process
,
req
->
base
,
get_req_data
(),
get_req_data_size
()
)))
{
dll
->
name
=
req
->
name
;
/* only generate event if initialization is done */
if
(
is_process_init_done
(
current
->
process
))
generate_debug_event
(
current
,
DbgLoadDllStateChange
,
dll
);
}
}
...
...
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