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
143143ad
Commit
143143ad
authored
Jul 20, 2017
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add small assembly wrappers for snooping instead of saving/restoring the entire context.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
a75e3f73
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
51 additions
and
50 deletions
+51
-50
relay.c
dlls/ntdll/relay.c
+51
-50
No files found.
dlls/ntdll/relay.c
View file @
143143ad
...
...
@@ -840,9 +840,6 @@ typedef struct
{
/* code part */
BYTE
lcall
;
/* 0xe8 call snoopentry (relative) */
/* NOTE: If you move snoopentry OR nrofargs fix the relative offset
* calculation!
*/
DWORD
snoopentry
;
/* SNOOP_Entry relative */
/* unreached */
int
nrofargs
;
...
...
@@ -863,15 +860,12 @@ typedef struct
{
/* code part */
BYTE
lcall
;
/* 0xe8 call snoopret relative*/
/* NOTE: If you move snoopret OR origreturn fix the relative offset
* calculation!
*/
DWORD
snoopret
;
/* SNOOP_Ret relative */
/* unreached */
FARPROC
origreturn
;
SNOOP_DLL
*
dll
;
DWORD
ordinal
;
DWORD
origESP
;
void
**
origESP
;
DWORD
*
args
;
/* saved args across a stdcall */
}
SNOOP_RETURNENTRY
;
...
...
@@ -1025,8 +1019,7 @@ FARPROC SNOOP_GetProcAddress( HMODULE hmod, const IMAGE_EXPORT_DIRECTORY *export
{
fun
->
name
=
ename
;
fun
->
lcall
=
0xe8
;
/* NOTE: origreturn struct member MUST come directly after snoopentry */
fun
->
snoopentry
=
(
char
*
)
SNOOP_Entry
-
((
char
*
)(
&
fun
->
nrofargs
));
fun
->
snoopentry
=
(
char
*
)
SNOOP_Entry
-
(
char
*
)(
&
fun
->
snoopentry
+
1
);
fun
->
origfun
=
origfun
;
fun
->
nrofargs
=
-
1
;
}
...
...
@@ -1070,29 +1063,19 @@ static void SNOOP_PrintArg(DWORD x)
__ENDTRY
}
#define CALLER1REF (*(DWORD*)context->Esp)
void
WINAPI
__regs_SNOOP_Entry
(
CONTEXT
*
context
)
void
WINAPI
__regs_SNOOP_Entry
(
void
**
stack
)
{
DWORD
ordinal
=
0
,
entry
=
context
->
Eip
-
5
;
SNOOP_DLL
*
dll
=
firstdll
;
SNOOP_FUN
*
fun
=
NULL
;
SNOOP_DLL
*
dll
;
SNOOP_FUN
*
fun
=
(
SNOOP_FUN
*
)((
char
*
)
stack
[
0
]
-
5
);
SNOOP_RETURNENTRIES
**
rets
=
&
firstrets
;
SNOOP_RETURNENTRY
*
ret
;
int
i
=
0
,
max
;
while
(
dll
)
{
if
(
((
char
*
)
entry
>=
(
char
*
)
dll
->
funs
)
&&
((
char
*
)
entry
<=
(
char
*
)(
dll
->
funs
+
dll
->
nrofordinals
))
)
{
fun
=
(
SNOOP_FUN
*
)
entry
;
ordinal
=
fun
-
dll
->
funs
;
break
;
}
dll
=
dll
->
next
;
}
for
(
dll
=
firstdll
;
dll
;
dll
=
dll
->
next
)
if
(
fun
>=
dll
->
funs
&&
fun
<
dll
->
funs
+
dll
->
nrofordinals
)
break
;
if
(
!
dll
)
{
FIXME
(
"entrypoint
0x%08x not found
\n
"
,
entry
);
FIXME
(
"entrypoint
%p not found
\n
"
,
fun
);
return
;
/* oops */
}
/* guess cdecl ... */
...
...
@@ -1102,7 +1085,7 @@ void WINAPI __regs_SNOOP_Entry( CONTEXT *context )
* which has (for xxxxxxxx up to 255 the opcode "83 C4 xx".
* (after that 81 C2 xx xx xx xx)
*/
LPBYTE
reteip
=
(
LPBYTE
)
CALLER1REF
;
LPBYTE
reteip
=
stack
[
1
]
;
if
(
reteip
)
{
if
((
reteip
[
0
]
==
0x83
)
&&
(
reteip
[
1
]
==
0xc4
))
...
...
@@ -1128,33 +1111,31 @@ void WINAPI __regs_SNOOP_Entry( CONTEXT *context )
PAGE_EXECUTE_READWRITE
);
if
(
!
addr
)
return
;
*
rets
=
addr
;
memset
(
*
rets
,
0
,
4096
);
i
=
0
;
/* entry 0 is free */
}
ret
=
&
((
*
rets
)
->
entry
[
i
]);
ret
->
lcall
=
0xe8
;
/* NOTE: origreturn struct member MUST come directly after snoopret */
ret
->
snoopret
=
((
char
*
)
SNOOP_Return
)
-
(
char
*
)(
&
ret
->
origreturn
);
ret
->
origreturn
=
(
FARPROC
)
CALLER1REF
;
CALLER1REF
=
(
DWORD
)
&
ret
->
lcall
;
ret
->
snoopret
=
(
char
*
)
SNOOP_Return
-
(
char
*
)(
&
ret
->
snoopret
+
1
);
ret
->
origreturn
=
stack
[
1
];
stack
[
1
]
=
&
ret
->
lcall
;
ret
->
dll
=
dll
;
ret
->
args
=
NULL
;
ret
->
ordinal
=
ordinal
;
ret
->
origESP
=
context
->
Esp
;
ret
->
ordinal
=
fun
-
dll
->
funs
;
ret
->
origESP
=
stack
;
context
->
Eip
=
(
DWORD
)
fun
->
origfun
;
stack
[
0
]
=
fun
->
origfun
;
if
(
!
TRACE_ON
(
snoop
))
return
;
if
(
TRACE_ON
(
timestamp
))
print_timestamp
();
if
(
fun
->
name
)
DPRINTF
(
"%04x:CALL %s.%s("
,
GetCurrentThreadId
(),
dll
->
name
,
fun
->
name
);
else
DPRINTF
(
"%04x:CALL %s.%d("
,
GetCurrentThreadId
(),
dll
->
name
,
dll
->
ordbase
+
ordinal
);
else
DPRINTF
(
"%04x:CALL %s.%d("
,
GetCurrentThreadId
(),
dll
->
name
,
dll
->
ordbase
+
ret
->
ordinal
);
if
(
fun
->
nrofargs
>
0
)
{
max
=
fun
->
nrofargs
;
if
(
max
>
16
)
max
=
16
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
SNOOP_PrintArg
(
*
(
DWORD
*
)(
context
->
Esp
+
4
+
sizeof
(
DWORD
)
*
i
)
);
SNOOP_PrintArg
(
(
DWORD
)
stack
[
i
+
2
]
);
if
(
i
<
fun
->
nrofargs
-
1
)
DPRINTF
(
","
);
}
if
(
max
!=
fun
->
nrofargs
)
...
...
@@ -1163,16 +1144,16 @@ void WINAPI __regs_SNOOP_Entry( CONTEXT *context )
DPRINTF
(
"<unknown, check return>"
);
ret
->
args
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
16
*
sizeof
(
DWORD
));
memcpy
(
ret
->
args
,
(
LPBYTE
)(
context
->
Esp
+
4
),
sizeof
(
DWORD
)
*
16
);
memcpy
(
ret
->
args
,
stack
+
2
,
sizeof
(
DWORD
)
*
16
);
}
DPRINTF
(
") ret=%08x
\n
"
,(
DWORD
)
ret
->
origreturn
);
}
void
WINAPI
__regs_SNOOP_Return
(
CONTEXT
*
context
)
void
WINAPI
__regs_SNOOP_Return
(
void
**
stack
)
{
SNOOP_RETURNENTRY
*
ret
=
(
SNOOP_RETURNENTRY
*
)(
context
->
Eip
-
5
);
SNOOP_RETURNENTRY
*
ret
=
(
SNOOP_RETURNENTRY
*
)((
char
*
)
stack
[
0
]
-
5
);
SNOOP_FUN
*
fun
=
&
ret
->
dll
->
funs
[
ret
->
ordinal
];
DWORD
retval
=
(
DWORD
)
stack
[
-
1
];
/* get saved %eax from the stack */
/* We haven't found out the nrofargs yet. If we called a cdecl
* function it is too late anyway and we can just set '0' (which
...
...
@@ -1180,8 +1161,8 @@ void WINAPI __regs_SNOOP_Return( CONTEXT *context )
* If stdcall -> everything ok.
*/
if
(
ret
->
dll
->
funs
[
ret
->
ordinal
].
nrofargs
<
0
)
ret
->
dll
->
funs
[
ret
->
ordinal
].
nrofargs
=
(
context
->
Esp
-
ret
->
origESP
-
4
)
/
4
;
context
->
Eip
=
(
DWORD
)
ret
->
origreturn
;
ret
->
dll
->
funs
[
ret
->
ordinal
].
nrofargs
=
stack
-
ret
->
origESP
-
1
;
stack
[
0
]
=
ret
->
origreturn
;
if
(
!
TRACE_ON
(
snoop
))
{
ret
->
origreturn
=
NULL
;
/* mark as empty */
...
...
@@ -1207,8 +1188,7 @@ void WINAPI __regs_SNOOP_Return( CONTEXT *context )
SNOOP_PrintArg
(
ret
->
args
[
i
]);
if
(
i
<
max
-
1
)
DPRINTF
(
","
);
}
DPRINTF
(
") retval=%08x ret=%08x
\n
"
,
context
->
Eax
,(
DWORD
)
ret
->
origreturn
);
DPRINTF
(
") retval=%08x ret=%08x
\n
"
,
retval
,
(
DWORD
)
ret
->
origreturn
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
ret
->
args
);
ret
->
args
=
NULL
;
}
...
...
@@ -1217,19 +1197,40 @@ void WINAPI __regs_SNOOP_Return( CONTEXT *context )
if
(
fun
->
name
)
DPRINTF
(
"%04x:RET %s.%s() retval=%08x ret=%08x
\n
"
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
fun
->
name
,
context
->
Eax
,
(
DWORD
)
ret
->
origreturn
);
ret
->
dll
->
name
,
fun
->
name
,
retval
,
(
DWORD
)
ret
->
origreturn
);
else
DPRINTF
(
"%04x:RET %s.%d() retval=%08x ret=%08x
\n
"
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
ret
->
dll
->
ordbase
+
ret
->
ordinal
,
context
->
Eax
,
(
DWORD
)
ret
->
origreturn
);
retval
,
(
DWORD
)
ret
->
origreturn
);
}
ret
->
origreturn
=
NULL
;
/* mark as empty */
}
/* assembly wrappers that save the context */
DEFINE_REGS_ENTRYPOINT
(
SNOOP_Entry
,
0
)
DEFINE_REGS_ENTRYPOINT
(
SNOOP_Return
,
0
)
/* small wrappers that save registers and get the stack pointer */
#define SNOOP_WRAPPER(name) \
__ASM_STDCALL_FUNC( name, 0, \
"pushl %eax\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
"pushl %ecx\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
"pushl %edx\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
"leal 12(%esp),%eax\n\t" \
"pushl %eax\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
"call " __ASM_NAME("__regs_" #name) __ASM_STDCALL(4) "\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") \
"popl %edx\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") \
"popl %ecx\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") \
"popl %eax\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") \
"ret" )
SNOOP_WRAPPER
(
SNOOP_Entry
)
SNOOP_WRAPPER
(
SNOOP_Return
)
#else
/* __i386__ */
...
...
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