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
34b2d920
Commit
34b2d920
authored
Oct 14, 2014
by
Sebastian Lackner
Committed by
Alexandre Julliard
Oct 15, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Improve check_atl_thunk to prevent passing exceptions to the usermode application.
parent
511a8490
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
89 additions
and
12 deletions
+89
-12
virtual.c
dlls/kernel32/tests/virtual.c
+0
-1
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+2
-0
signal_i386.c
dlls/ntdll/signal_i386.c
+9
-11
virtual.c
dlls/ntdll/virtual.c
+78
-0
No files found.
dlls/kernel32/tests/virtual.c
View file @
34b2d920
...
...
@@ -2071,7 +2071,6 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
pRtlRemoveVectoredExceptionHandler
(
vectored_handler
);
ok
(
ret
==
43
,
"call returned wrong result, expected 43, got %d
\n
"
,
ret
);
todo_wine
ok
(
num_execute_fault_calls
==
1
,
"expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions
\n
"
,
num_execute_fault_calls
);
}
else
...
...
dlls/ntdll/ntdll_misc.h
View file @
34b2d920
...
...
@@ -169,6 +169,8 @@ extern BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size ) DECLS
extern
NTSTATUS
virtual_handle_fault
(
LPCVOID
addr
,
DWORD
err
)
DECLSPEC_HIDDEN
;
extern
BOOL
virtual_check_buffer_for_read
(
const
void
*
ptr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
BOOL
virtual_check_buffer_for_write
(
void
*
ptr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
SIZE_T
virtual_uninterrupted_read_memory
(
const
void
*
addr
,
void
*
buffer
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
SIZE_T
virtual_uninterrupted_write_memory
(
void
*
addr
,
const
void
*
buffer
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
void
VIRTUAL_SetForceExec
(
BOOL
enable
)
DECLSPEC_HIDDEN
;
extern
void
virtual_release_address_space
(
void
)
DECLSPEC_HIDDEN
;
extern
void
virtual_set_large_address_space
(
void
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/signal_i386.c
View file @
34b2d920
...
...
@@ -1633,26 +1633,24 @@ struct atl_thunk
static
BOOL
check_atl_thunk
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
const
struct
atl_thunk
*
thunk
=
(
const
struct
atl_thunk
*
)
rec
->
ExceptionInformation
[
1
];
struct
atl_thunk
thunk_copy
;
BOOL
ret
=
FALSE
;
if
(
!
virtual_is_valid_code_address
(
thunk
,
sizeof
(
*
thunk
)
))
return
FALSE
;
if
(
virtual_uninterrupted_read_memory
(
thunk
,
&
thunk_copy
,
sizeof
(
*
thunk
)
)
!=
sizeof
(
*
thunk
))
return
FALSE
;
__TRY
if
(
thunk_copy
.
movl
==
0x042444c7
&&
thunk_copy
.
jmp
==
0xe9
)
{
if
(
thunk
->
movl
==
0x042444c7
&&
thunk
->
jmp
==
0xe9
)
if
(
virtual_uninterrupted_write_memory
(
(
DWORD
*
)
context
->
Esp
+
1
,
&
thunk_copy
.
this
,
sizeof
(
DWORD
)
)
==
sizeof
(
DWORD
))
{
*
((
DWORD
*
)
context
->
Esp
+
1
)
=
thunk
->
this
;
context
->
Eip
=
(
DWORD_PTR
)(
&
thunk
->
func
+
1
)
+
thunk
->
func
;
context
->
Eip
=
(
DWORD_PTR
)(
&
thunk
->
func
+
1
)
+
thunk_copy
.
func
;
TRACE
(
"emulating ATL thunk at %p, func=%08x arg=%08x
\n
"
,
thunk
,
context
->
Eip
,
*
((
DWORD
*
)
context
->
Esp
+
1
)
);
thunk
,
context
->
Eip
,
thunk_copy
.
this
);
ret
=
TRUE
;
}
}
__EXCEPT_PAGE_FAULT
{
return
FALSE
;
}
__ENDTRY
return
ret
;
}
...
...
dlls/ntdll/virtual.c
View file @
34b2d920
...
...
@@ -1672,6 +1672,84 @@ BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size )
/***********************************************************************
* virtual_uninterrupted_read_memory
*
* Similar to NtReadVirtualMemory, but without wineserver calls. Moreover
* permissions are checked before accessing each page, to ensure that no
* exceptions can happen.
*/
SIZE_T
virtual_uninterrupted_read_memory
(
const
void
*
addr
,
void
*
buffer
,
SIZE_T
size
)
{
struct
file_view
*
view
;
sigset_t
sigset
;
SIZE_T
bytes_read
=
0
;
if
(
!
size
)
return
0
;
server_enter_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
if
((
view
=
VIRTUAL_FindView
(
addr
,
size
)))
{
if
(
!
(
view
->
protect
&
VPROT_SYSTEM
))
{
void
*
page
=
ROUND_ADDR
(
addr
,
page_mask
);
BYTE
*
p
=
view
->
prot
+
(((
const
char
*
)
page
-
(
const
char
*
)
view
->
base
)
>>
page_shift
);
while
(
bytes_read
<
size
&&
(
VIRTUAL_GetUnixProt
(
*
p
++
)
&
PROT_READ
))
{
SIZE_T
block_size
=
min
(
size
,
page_size
-
((
UINT_PTR
)
addr
&
page_mask
)
);
memcpy
(
buffer
,
addr
,
block_size
);
addr
=
(
const
void
*
)((
const
char
*
)
addr
+
block_size
);
buffer
=
(
void
*
)((
char
*
)
buffer
+
block_size
);
bytes_read
+=
block_size
;
}
}
}
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
return
bytes_read
;
}
/***********************************************************************
* virtual_uninterrupted_write_memory
*
* Similar to NtWriteVirtualMemory, but without wineserver calls. Moreover
* permissions are checked before accessing each page, to ensure that no
* exceptions can happen.
*/
SIZE_T
virtual_uninterrupted_write_memory
(
void
*
addr
,
const
void
*
buffer
,
SIZE_T
size
)
{
struct
file_view
*
view
;
sigset_t
sigset
;
SIZE_T
bytes_written
=
0
;
if
(
!
size
)
return
0
;
server_enter_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
if
((
view
=
VIRTUAL_FindView
(
addr
,
size
)))
{
if
(
!
(
view
->
protect
&
VPROT_SYSTEM
))
{
void
*
page
=
ROUND_ADDR
(
addr
,
page_mask
);
BYTE
*
p
=
view
->
prot
+
(((
const
char
*
)
page
-
(
const
char
*
)
view
->
base
)
>>
page_shift
);
while
(
bytes_written
<
size
&&
(
VIRTUAL_GetUnixProt
(
*
p
++
)
&
PROT_WRITE
))
{
SIZE_T
block_size
=
min
(
size
,
page_size
-
((
UINT_PTR
)
addr
&
page_mask
)
);
memcpy
(
addr
,
buffer
,
block_size
);
addr
=
(
void
*
)((
char
*
)
addr
+
block_size
);
buffer
=
(
const
void
*
)((
const
char
*
)
buffer
+
block_size
);
bytes_written
+=
block_size
;
}
}
}
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
return
bytes_written
;
}
/***********************************************************************
* VIRTUAL_SetForceExec
*
* Whether to force exec prot on all views.
...
...
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