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
a37e7608
Commit
a37e7608
authored
Sep 19, 2003
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved 32-bit relay and snoop support to dlls/ntdll.
parent
97ad311e
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
449 additions
and
510 deletions
+449
-510
ne_module.c
dlls/kernel/ne_module.c
+2
-1
snoop16.c
dlls/kernel/snoop16.c
+3
-1
Makefile.in
dlls/ntdll/Makefile.in
+1
-3
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-1
relay.c
dlls/ntdll/relay.c
+442
-24
snoop.h
include/snoop.h
+0
-29
module.c
loader/ne/module.c
+0
-1
snoop.c
relay32/snoop.c
+0
-450
No files found.
dlls/kernel/ne_module.c
View file @
a37e7608
...
...
@@ -44,7 +44,6 @@
#include "global.h"
#include "file.h"
#include "task.h"
#include "snoop.h"
#include "builtin16.h"
#include "stackframe.h"
#include "excpt.h"
...
...
@@ -93,6 +92,8 @@ typedef struct
static
const
BUILTIN16_DESCRIPTOR
*
builtin_dlls
[
MAX_DLLS
];
extern
void
SNOOP16_RegisterDLL
(
NE_MODULE
*
,
LPCSTR
);
extern
FARPROC16
SNOOP16_GetProcAddress16
(
HMODULE16
,
DWORD
,
FARPROC16
);
static
HINSTANCE16
NE_LoadModule
(
LPCSTR
name
,
BOOL
lib_only
);
static
BOOL16
NE_FreeModule
(
HMODULE16
hModule
,
BOOL
call_wep
);
...
...
dlls/kernel/snoop16.c
View file @
a37e7608
...
...
@@ -31,10 +31,10 @@
#include "wine/winbase16.h"
#include "wine/library.h"
#include "global.h"
#include "module.h"
#include "stackframe.h"
#include "builtin16.h"
#include "toolhelp.h"
#include "snoop.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
snoop
);
...
...
@@ -43,6 +43,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(snoop);
#include "pshpack1.h"
extern
int
SNOOP_ShowDebugmsgSnoop
(
const
char
*
dll
,
int
ord
,
const
char
*
fname
);
/* FIXME */
void
WINAPI
SNOOP16_Entry
(
FARPROC
proc
,
LPBYTE
args
,
CONTEXT86
*
context
);
void
WINAPI
SNOOP16_Return
(
FARPROC
proc
,
LPBYTE
args
,
CONTEXT86
*
context
);
...
...
dlls/ntdll/Makefile.in
View file @
a37e7608
...
...
@@ -27,8 +27,6 @@ C_SRCS = \
$(TOPOBJDIR)
/misc/registry.c
\
$(TOPOBJDIR)
/misc/version.c
\
$(TOPOBJDIR)
/msdos/dpmi.c
\
$(TOPOBJDIR)
/relay32/relay386.c
\
$(TOPOBJDIR)
/relay32/snoop.c
\
$(TOPOBJDIR)
/scheduler/handle.c
\
$(TOPOBJDIR)
/scheduler/process.c
\
$(TOPOBJDIR)
/scheduler/pthread.c
\
...
...
@@ -51,6 +49,7 @@ C_SRCS = \
path.c
\
process.c
\
reg.c
\
relay.c
\
resource.c
\
rtl.c
\
rtlbitmap.c
\
...
...
@@ -81,7 +80,6 @@ EXTRASUBDIRS = \
$(TOPOBJDIR)
/memory
\
$(TOPOBJDIR)
/misc
\
$(TOPOBJDIR)
/msdos
\
$(TOPOBJDIR)
/relay32
\
$(TOPOBJDIR)
/scheduler
\
$(TOPOBJDIR)
/win32
...
...
dlls/ntdll/ntdll_misc.h
View file @
a37e7608
...
...
@@ -44,7 +44,7 @@ extern FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exp
DWORD
exp_size
,
FARPROC
proc
,
const
char
*
user
);
extern
FARPROC
SNOOP_GetProcAddress
(
HMODULE
hmod
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
DWORD
exp_size
,
FARPROC
origfun
,
DWORD
ordinal
);
extern
void
RELAY_SetupDLL
(
const
char
*
module
);
extern
void
RELAY_SetupDLL
(
HMODULE
hmod
);
extern
void
SNOOP_SetupDLL
(
HMODULE
hmod
);
static
inline
HANDLE
ntdll_get_process_heap
(
void
)
...
...
relay32/relay386
.c
→
dlls/ntdll/relay
.c
View file @
a37e7608
/*
*
386-specific Win32 relay
functions
*
Win32 relay and snoop
functions
*
* Copyright 1997 Alexandre Julliard
* Copyright 1998 Marcus Meissner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -30,12 +31,15 @@
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "excpt.h"
#include "wine/exception.h"
#include "ntdll_misc.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
relay
);
WINE_DECLARE_DEBUG_CHANNEL
(
snoop
);
WINE_DECLARE_DEBUG_CHANNEL
(
seh
);
const
char
**
debug_relay_excludelist
=
NULL
;
const
char
**
debug_relay_includelist
=
NULL
;
...
...
@@ -170,16 +174,77 @@ void RELAY_InitDebugLists(void)
#ifdef __i386__
#include "pshpack1.h"
typedef
struct
{
BYTE
call
;
/* 0xe8 call callfrom32 (relative) */
DWORD
callfrom32
WINE_PACKED
;
/* RELAY_CallFrom32 relative addr */
BYTE
ret
;
/* 0xc2 ret $n or 0xc3 ret */
WORD
args
;
/* nb of args to remove from the stack */
void
*
orig
;
/* original entry point */
DWORD
argtypes
;
/* argument types */
BYTE
call
;
/* 0xe8 call callfrom32 (relative) */
DWORD
callfrom32
;
/* RELAY_CallFrom32 relative addr */
BYTE
ret
;
/* 0xc2 ret $n or 0xc3 ret */
WORD
args
;
/* nb of args to remove from the stack */
void
*
orig
;
/* original entry point */
DWORD
argtypes
;
/* argument types */
}
DEBUG_ENTRY_POINT
;
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
;
FARPROC
origfun
;
const
char
*
name
;
}
SNOOP_FUN
;
typedef
struct
tagSNOOP_DLL
{
HMODULE
hmod
;
SNOOP_FUN
*
funs
;
DWORD
ordbase
;
DWORD
nrofordinals
;
struct
tagSNOOP_DLL
*
next
;
char
name
[
1
];
}
SNOOP_DLL
;
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
;
DWORD
*
args
;
/* saved args across a stdcall */
}
SNOOP_RETURNENTRY
;
typedef
struct
tagSNOOP_RETURNENTRIES
{
SNOOP_RETURNENTRY
entry
[
4092
/
sizeof
(
SNOOP_RETURNENTRY
)];
struct
tagSNOOP_RETURNENTRIES
*
next
;
}
SNOOP_RETURNENTRIES
;
#include "poppack.h"
extern
void
WINAPI
SNOOP_Entry
();
extern
void
WINAPI
SNOOP_Return
();
static
SNOOP_DLL
*
firstdll
;
static
SNOOP_RETURNENTRIES
*
firstrets
;
static
WINE_EXCEPTION_FILTER
(
page_fault
)
{
if
(
GetExceptionCode
()
==
EXCEPTION_ACCESS_VIOLATION
||
GetExceptionCode
()
==
EXCEPTION_PRIV_INSTRUCTION
)
return
EXCEPTION_EXECUTE_HANDLER
;
return
EXCEPTION_CONTINUE_SEARCH
;
}
/***********************************************************************
* check_relay_include
...
...
@@ -259,17 +324,17 @@ static BOOL check_relay_from_module( const char *module )
*
* Find the name of an exported function.
*/
static
const
char
*
find_exported_name
(
const
char
*
module
,
static
const
char
*
find_exported_name
(
HMODULE
module
,
IMAGE_EXPORT_DIRECTORY
*
exp
,
int
ordinal
)
{
int
i
;
const
char
*
ret
=
NULL
;
WORD
*
ordptr
=
(
WORD
*
)(
module
+
exp
->
AddressOfNameOrdinals
);
WORD
*
ordptr
=
(
WORD
*
)(
(
char
*
)
module
+
exp
->
AddressOfNameOrdinals
);
for
(
i
=
0
;
i
<
exp
->
NumberOfNames
;
i
++
,
ordptr
++
)
if
(
*
ordptr
+
exp
->
Base
==
ordinal
)
break
;
if
(
i
<
exp
->
NumberOfNames
)
ret
=
module
+
((
DWORD
*
)(
module
+
exp
->
AddressOfNames
))[
i
];
ret
=
(
char
*
)
module
+
((
DWORD
*
)((
char
*
)
module
+
exp
->
AddressOfNames
))[
i
];
return
ret
;
}
...
...
@@ -283,7 +348,7 @@ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
{
IMAGE_EXPORT_DIRECTORY
*
exp
=
NULL
;
DEBUG_ENTRY_POINT
*
debug
;
char
*
p
,
*
base
=
NULL
;
char
*
p
;
const
char
*
name
;
int
ordinal
=
0
;
PLIST_ENTRY
mark
,
entry
;
...
...
@@ -309,12 +374,11 @@ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
/* Now find the function */
base
=
(
char
*
)
mod
->
BaseAddress
;
strcpy
(
buffer
,
base
+
exp
->
Name
);
strcpy
(
buffer
,
(
char
*
)
mod
->
BaseAddress
+
exp
->
Name
);
p
=
buffer
+
strlen
(
buffer
);
if
(
p
>
buffer
+
4
&&
!
strcasecmp
(
p
-
4
,
".dll"
))
p
-=
4
;
if
((
name
=
find_exported_name
(
base
,
exp
,
ordinal
+
exp
->
Base
)))
if
((
name
=
find_exported_name
(
mod
->
BaseAddress
,
exp
,
ordinal
+
exp
->
Base
)))
sprintf
(
p
,
".%s"
,
name
);
else
sprintf
(
p
,
".%ld"
,
ordinal
+
exp
->
Base
);
...
...
@@ -331,9 +395,9 @@ static inline void RELAY_PrintArgs( int *args, int nb_args, unsigned int typemas
if
((
typemask
&
3
)
&&
HIWORD
(
*
args
))
{
if
(
typemask
&
2
)
DPRINTF
(
"%08x %s"
,
*
args
,
debugstr_w
((
LPWSTR
)
*
args
)
);
DPRINTF
(
"%08x %s"
,
*
args
,
debugstr_w
((
LPWSTR
)
*
args
)
);
else
DPRINTF
(
"%08x %s"
,
*
args
,
debugstr_a
((
LPCSTR
)
*
args
)
);
DPRINTF
(
"%08x %s"
,
*
args
,
debugstr_a
((
LPCSTR
)
*
args
)
);
}
else
DPRINTF
(
"%08x"
,
*
args
);
if
(
nb_args
)
DPRINTF
(
","
);
...
...
@@ -631,7 +695,7 @@ FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
*
* Setup relay debugging for a built-in dll.
*/
void
RELAY_SetupDLL
(
const
char
*
module
)
void
RELAY_SetupDLL
(
HMODULE
module
)
{
IMAGE_EXPORT_DIRECTORY
*
exports
;
DEBUG_ENTRY_POINT
*
debug
;
...
...
@@ -641,12 +705,11 @@ void RELAY_SetupDLL( const char *module )
char
*
p
,
dllname
[
80
];
DWORD
size
;
exports
=
RtlImageDirectoryEntryToData
(
(
HMODULE
)
module
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_EXPORT
,
&
size
);
exports
=
RtlImageDirectoryEntryToData
(
module
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_EXPORT
,
&
size
);
if
(
!
exports
)
return
;
debug
=
(
DEBUG_ENTRY_POINT
*
)((
char
*
)
exports
+
size
);
funcs
=
(
DWORD
*
)(
module
+
exports
->
AddressOfFunctions
);
strcpy
(
dllname
,
module
+
exports
->
Name
);
funcs
=
(
DWORD
*
)(
(
char
*
)
module
+
exports
->
AddressOfFunctions
);
strcpy
(
dllname
,
(
char
*
)
module
+
exports
->
Name
);
p
=
dllname
+
strlen
(
dllname
)
-
4
;
if
(
p
>
dllname
&&
!
strcasecmp
(
p
,
".dll"
))
*
p
=
0
;
...
...
@@ -674,11 +737,355 @@ void RELAY_SetupDLL( const char *module )
debug
->
callfrom32
=
(
char
*
)
debug
->
orig
-
(
char
*
)
&
debug
->
ret
;
}
debug
->
orig
=
(
FARPROC
)(
module
+
(
DWORD
)
*
funcs
);
*
funcs
=
(
char
*
)
debug
-
module
;
debug
->
orig
=
(
FARPROC
)((
char
*
)
module
+
(
DWORD
)
*
funcs
);
*
funcs
=
(
char
*
)
debug
-
(
char
*
)
module
;
}
}
/***********************************************************************
* SNOOP_ShowDebugmsgSnoop
*
* Simple function to decide if a particular debugging message is
* wanted.
*/
int
SNOOP_ShowDebugmsgSnoop
(
const
char
*
dll
,
int
ord
,
const
char
*
fname
)
{
if
(
debug_snoop_excludelist
||
debug_snoop_includelist
)
{
const
char
**
listitem
;
char
buf
[
80
];
int
len
,
len2
,
itemlen
,
show
;
if
(
debug_snoop_excludelist
)
{
show
=
1
;
listitem
=
debug_snoop_excludelist
;
}
else
{
show
=
0
;
listitem
=
debug_snoop_includelist
;
}
len
=
strlen
(
dll
);
assert
(
len
<
64
);
sprintf
(
buf
,
"%s.%d"
,
dll
,
ord
);
len2
=
strlen
(
buf
);
for
(;
*
listitem
;
listitem
++
)
{
itemlen
=
strlen
(
*
listitem
);
if
((
itemlen
==
len
&&
!
strncasecmp
(
*
listitem
,
buf
,
len
))
||
(
itemlen
==
len2
&&
!
strncasecmp
(
*
listitem
,
buf
,
len2
))
||
!
strcasecmp
(
*
listitem
,
fname
))
{
show
=
!
show
;
break
;
}
}
return
show
;
}
return
1
;
}
/***********************************************************************
* SNOOP_SetupDLL
*
* Setup snoop debugging for a native dll.
*/
void
SNOOP_SetupDLL
(
HMODULE
hmod
)
{
SNOOP_DLL
**
dll
=
&
firstdll
;
char
*
p
,
*
name
;
void
*
addr
;
SIZE_T
size
;
IMAGE_EXPORT_DIRECTORY
*
exports
;
exports
=
RtlImageDirectoryEntryToData
(
hmod
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_EXPORT
,
&
size
);
if
(
!
exports
)
return
;
name
=
(
char
*
)
hmod
+
exports
->
Name
;
TRACE
(
"hmod=%p, name=%s
\n
"
,
hmod
,
name
);
while
(
*
dll
)
{
if
((
*
dll
)
->
hmod
==
hmod
)
{
/* another dll, loaded at the same address */
addr
=
(
*
dll
)
->
funs
;
size
=
(
*
dll
)
->
nrofordinals
*
sizeof
(
SNOOP_FUN
);
NtFreeVirtualMemory
(
GetCurrentProcess
(),
&
addr
,
&
size
,
MEM_RELEASE
);
break
;
}
dll
=
&
((
*
dll
)
->
next
);
}
*
dll
=
RtlReAllocateHeap
(
ntdll_get_process_heap
(),
HEAP_ZERO_MEMORY
,
*
dll
,
sizeof
(
SNOOP_DLL
)
+
strlen
(
name
));
(
*
dll
)
->
hmod
=
hmod
;
(
*
dll
)
->
ordbase
=
exports
->
Base
;
(
*
dll
)
->
nrofordinals
=
exports
->
NumberOfFunctions
;
strcpy
(
(
*
dll
)
->
name
,
name
);
p
=
(
*
dll
)
->
name
+
strlen
((
*
dll
)
->
name
)
-
4
;
if
(
p
>
(
*
dll
)
->
name
&&
!
strcasecmp
(
p
,
".dll"
))
*
p
=
0
;
size
=
exports
->
NumberOfFunctions
*
sizeof
(
SNOOP_FUN
);
NtAllocateVirtualMemory
(
GetCurrentProcess
(),
&
addr
,
NULL
,
&
size
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
);
if
(
!
addr
)
{
RtlFreeHeap
(
ntdll_get_process_heap
(),
0
,
*
dll
);
FIXME
(
"out of memory
\n
"
);
return
;
}
(
*
dll
)
->
funs
=
addr
;
memset
((
*
dll
)
->
funs
,
0
,
size
);
}
/***********************************************************************
* SNOOP_GetProcAddress
*
* Return the proc address to use for a given function.
*/
FARPROC
SNOOP_GetProcAddress
(
HMODULE
hmod
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
DWORD
exp_size
,
FARPROC
origfun
,
DWORD
ordinal
)
{
int
i
;
const
char
*
ename
;
WORD
*
ordinals
;
DWORD
*
names
;
SNOOP_DLL
*
dll
=
firstdll
;
SNOOP_FUN
*
fun
;
IMAGE_SECTION_HEADER
*
sec
;
if
(
!
TRACE_ON
(
snoop
))
return
origfun
;
if
(
!*
(
LPBYTE
)
origfun
)
/* 0x00 is an imposs. opcode, poss. dataref. */
return
origfun
;
sec
=
RtlImageRvaToSection
(
RtlImageNtHeader
(
hmod
),
hmod
,
(
char
*
)
origfun
-
(
char
*
)
hmod
);
if
(
!
sec
||
!
(
sec
->
Characteristics
&
IMAGE_SCN_CNT_CODE
))
return
origfun
;
/* most likely a data reference */
while
(
dll
)
{
if
(
hmod
==
dll
->
hmod
)
break
;
dll
=
dll
->
next
;
}
if
(
!
dll
)
/* probably internal */
return
origfun
;
/* try to find a name for it */
ename
=
NULL
;
names
=
(
DWORD
*
)((
char
*
)
hmod
+
exports
->
AddressOfNames
);
ordinals
=
(
WORD
*
)((
char
*
)
hmod
+
exports
->
AddressOfNameOrdinals
);
if
(
names
)
for
(
i
=
0
;
i
<
exports
->
NumberOfNames
;
i
++
)
{
if
(
ordinals
[
i
]
==
ordinal
)
{
ename
=
(
char
*
)
hmod
+
names
[
i
];
break
;
}
}
if
(
!
SNOOP_ShowDebugmsgSnoop
(
dll
->
name
,
ordinal
,
ename
))
return
origfun
;
assert
(
ordinal
<
dll
->
nrofordinals
);
fun
=
dll
->
funs
+
ordinal
;
if
(
!
fun
->
name
)
{
fun
->
name
=
ename
;
fun
->
lcall
=
0xe8
;
/* NOTE: origreturn struct member MUST come directly after snoopentry */
fun
->
snoopentry
=
(
char
*
)
SNOOP_Entry
-
((
char
*
)(
&
fun
->
nrofargs
));
fun
->
origfun
=
origfun
;
fun
->
nrofargs
=
-
1
;
}
return
(
FARPROC
)
&
(
fun
->
lcall
);
}
static
void
SNOOP_PrintArg
(
DWORD
x
)
{
int
i
,
nostring
;
DPRINTF
(
"%08lx"
,
x
);
if
(
!
HIWORD
(
x
)
||
TRACE_ON
(
seh
))
return
;
/* trivial reject to avoid faults */
__TRY
{
LPBYTE
s
=
(
LPBYTE
)
x
;
i
=
0
;
nostring
=
0
;
while
(
i
<
80
)
{
if
(
s
[
i
]
==
0
)
break
;
if
(
s
[
i
]
<
0x20
)
{
nostring
=
1
;
break
;}
if
(
s
[
i
]
>=
0x80
)
{
nostring
=
1
;
break
;}
i
++
;
}
if
(
!
nostring
&&
i
>
5
)
DPRINTF
(
" %s"
,
debugstr_an
((
LPSTR
)
x
,
i
));
else
/* try unicode */
{
LPWSTR
s
=
(
LPWSTR
)
x
;
i
=
0
;
nostring
=
0
;
while
(
i
<
80
)
{
if
(
s
[
i
]
==
0
)
break
;
if
(
s
[
i
]
<
0x20
)
{
nostring
=
1
;
break
;}
if
(
s
[
i
]
>
0x100
)
{
nostring
=
1
;
break
;}
i
++
;
}
if
(
!
nostring
&&
i
>
5
)
DPRINTF
(
" %s"
,
debugstr_wn
((
LPWSTR
)
x
,
i
));
}
}
__EXCEPT
(
page_fault
)
{
}
__ENDTRY
}
#define CALLER1REF (*(DWORD*)context->Esp)
void
WINAPI
SNOOP_DoEntry
(
CONTEXT86
*
context
)
{
DWORD
ordinal
=
0
,
entry
=
context
->
Eip
-
5
;
SNOOP_DLL
*
dll
=
firstdll
;
SNOOP_FUN
*
fun
=
NULL
;
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
;
}
if
(
!
dll
)
{
FIXME
(
"entrypoint 0x%08lx not found
\n
"
,
entry
);
return
;
/* oops */
}
/* guess cdecl ... */
if
(
fun
->
nrofargs
<
0
)
{
/* Typical cdecl return frame is:
* add esp, xxxxxxxx
* which has (for xxxxxxxx up to 255 the opcode "83 C4 xx".
* (after that 81 C2 xx xx xx xx)
*/
LPBYTE
reteip
=
(
LPBYTE
)
CALLER1REF
;
if
(
reteip
)
{
if
((
reteip
[
0
]
==
0x83
)
&&
(
reteip
[
1
]
==
0xc4
))
fun
->
nrofargs
=
reteip
[
2
]
/
4
;
}
}
while
(
*
rets
)
{
for
(
i
=
0
;
i
<
sizeof
((
*
rets
)
->
entry
)
/
sizeof
((
*
rets
)
->
entry
[
0
]);
i
++
)
if
(
!
(
*
rets
)
->
entry
[
i
].
origreturn
)
break
;
if
(
i
!=
sizeof
((
*
rets
)
->
entry
)
/
sizeof
((
*
rets
)
->
entry
[
0
]))
break
;
rets
=
&
((
*
rets
)
->
next
);
}
if
(
!*
rets
)
{
SIZE_T
size
=
4096
;
VOID
*
addr
;
NtAllocateVirtualMemory
(
GetCurrentProcess
(),
&
addr
,
NULL
,
&
size
,
MEM_COMMIT
|
MEM_RESERVE
,
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
->
dll
=
dll
;
ret
->
args
=
NULL
;
ret
->
ordinal
=
ordinal
;
ret
->
origESP
=
context
->
Esp
;
context
->
Eip
=
(
DWORD
)
fun
->
origfun
;
if
(
fun
->
name
)
DPRINTF
(
"%04lx:CALL %s.%s("
,
GetCurrentThreadId
(),
dll
->
name
,
fun
->
name
);
else
DPRINTF
(
"%04lx:CALL %s.%ld("
,
GetCurrentThreadId
(),
dll
->
name
,
dll
->
ordbase
+
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
));
if
(
i
<
fun
->
nrofargs
-
1
)
DPRINTF
(
","
);
}
if
(
max
!=
fun
->
nrofargs
)
DPRINTF
(
" ..."
);
}
else
if
(
fun
->
nrofargs
<
0
)
{
DPRINTF
(
"<unknown, check return>"
);
ret
->
args
=
RtlAllocateHeap
(
ntdll_get_process_heap
(),
0
,
16
*
sizeof
(
DWORD
));
memcpy
(
ret
->
args
,(
LPBYTE
)(
context
->
Esp
+
4
),
sizeof
(
DWORD
)
*
16
);
}
DPRINTF
(
") ret=%08lx
\n
"
,(
DWORD
)
ret
->
origreturn
);
}
void
WINAPI
SNOOP_DoReturn
(
CONTEXT86
*
context
)
{
SNOOP_RETURNENTRY
*
ret
=
(
SNOOP_RETURNENTRY
*
)(
context
->
Eip
-
5
);
SNOOP_FUN
*
fun
=
&
ret
->
dll
->
funs
[
ret
->
ordinal
];
/* 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
* will be the difference between orig and current ESP
* 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
;
if
(
ret
->
args
)
{
int
i
,
max
;
if
(
fun
->
name
)
DPRINTF
(
"%04lx:RET %s.%s("
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
fun
->
name
);
else
DPRINTF
(
"%04lx:RET %s.%ld("
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
ret
->
dll
->
ordbase
+
ret
->
ordinal
);
max
=
fun
->
nrofargs
;
if
(
max
>
16
)
max
=
16
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
SNOOP_PrintArg
(
ret
->
args
[
i
]);
if
(
i
<
max
-
1
)
DPRINTF
(
","
);
}
DPRINTF
(
") retval=%08lx ret=%08lx
\n
"
,
context
->
Eax
,(
DWORD
)
ret
->
origreturn
);
RtlFreeHeap
(
ntdll_get_process_heap
(),
0
,
ret
->
args
);
ret
->
args
=
NULL
;
}
else
{
if
(
fun
->
name
)
DPRINTF
(
"%04lx:RET %s.%s() retval=%08lx ret=%08lx
\n
"
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
fun
->
name
,
context
->
Eax
,
(
DWORD
)
ret
->
origreturn
);
else
DPRINTF
(
"%04lx:RET %s.%ld() retval=%08lx ret=%08lx
\n
"
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
ret
->
dll
->
ordbase
+
ret
->
ordinal
,
context
->
Eax
,
(
DWORD
)
ret
->
origreturn
);
}
ret
->
origreturn
=
NULL
;
/* mark as empty */
}
/* assembly wrappers that save the context */
__ASM_GLOBAL_FUNC
(
SNOOP_Entry
,
"call "
__ASM_NAME
(
"__wine_call_from_32_regs"
)
"
\n\t
"
".long "
__ASM_NAME
(
"SNOOP_DoEntry"
)
",0"
);
__ASM_GLOBAL_FUNC
(
SNOOP_Return
,
"call "
__ASM_NAME
(
"__wine_call_from_32_regs"
)
"
\n\t
"
".long "
__ASM_NAME
(
"SNOOP_DoReturn"
)
",0"
);
#else
/* __i386__ */
FARPROC
RELAY_GetProcAddress
(
HMODULE
module
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
...
...
@@ -687,8 +1094,19 @@ FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
return
proc
;
}
FARPROC
SNOOP_GetProcAddress
(
HMODULE
hmod
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
DWORD
exp_size
,
FARPROC
origfun
,
DWORD
ordinal
)
{
return
origfun
;
}
void
RELAY_SetupDLL
(
const
char
*
module
)
{
}
void
SNOOP_SetupDLL
(
HMODULE
hmod
)
{
FIXME
(
"snooping works only on i386 for now.
\n
"
);
}
#endif
/* __i386__ */
include/snoop.h
deleted
100644 → 0
View file @
97ad311e
/*
* Definitions for inter-dll snooping
*
* Copyright 1998 Marcus Meissner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __WINE_SNOOP_H
#define __WINE_SNOOP_H
#include <module.h>
extern
void
SNOOP16_RegisterDLL
(
NE_MODULE
*
,
LPCSTR
);
extern
FARPROC16
SNOOP16_GetProcAddress16
(
HMODULE16
,
DWORD
,
FARPROC16
);
extern
int
SNOOP_ShowDebugmsgSnoop
(
const
char
*
dll
,
int
ord
,
const
char
*
fname
);
#endif
loader/ne/module.c
View file @
a37e7608
...
...
@@ -41,7 +41,6 @@
#include "toolhelp.h"
#include "file.h"
#include "task.h"
#include "snoop.h"
#include "builtin16.h"
#include "stackframe.h"
#include "excpt.h"
...
...
relay32/snoop.c
deleted
100644 → 0
View file @
97ad311e
/*
* 386-specific Win32 dll<->dll snooping functions
*
* Copyright 1998 Marcus Meissner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "snoop.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "excpt.h"
#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
snoop
);
WINE_DECLARE_DEBUG_CHANNEL
(
seh
);
static
WINE_EXCEPTION_FILTER
(
page_fault
)
{
if
(
GetExceptionCode
()
==
EXCEPTION_ACCESS_VIOLATION
||
GetExceptionCode
()
==
EXCEPTION_PRIV_INSTRUCTION
)
return
EXCEPTION_EXECUTE_HANDLER
;
return
EXCEPTION_CONTINUE_SEARCH
;
}
extern
const
char
**
debug_snoop_excludelist
;
extern
const
char
**
debug_snoop_includelist
;
#ifdef __i386__
extern
void
WINAPI
SNOOP_Entry
();
extern
void
WINAPI
SNOOP_Return
();
#include "pshpack1.h"
typedef
struct
tagSNOOP_FUN
{
/* 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
;
FARPROC
origfun
;
const
char
*
name
;
}
SNOOP_FUN
;
typedef
struct
tagSNOOP_DLL
{
HMODULE
hmod
;
SNOOP_FUN
*
funs
;
DWORD
ordbase
;
DWORD
nrofordinals
;
struct
tagSNOOP_DLL
*
next
;
char
name
[
1
];
}
SNOOP_DLL
;
typedef
struct
tagSNOOP_RETURNENTRY
{
/* 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
;
DWORD
*
args
;
/* saved args across a stdcall */
}
SNOOP_RETURNENTRY
;
typedef
struct
tagSNOOP_RETURNENTRIES
{
SNOOP_RETURNENTRY
entry
[
4092
/
sizeof
(
SNOOP_RETURNENTRY
)];
struct
tagSNOOP_RETURNENTRIES
*
next
;
}
SNOOP_RETURNENTRIES
;
#include "poppack.h"
static
SNOOP_DLL
*
firstdll
=
NULL
;
static
SNOOP_RETURNENTRIES
*
firstrets
=
NULL
;
/***********************************************************************
* SNOOP_ShowDebugmsgSnoop
*
* Simple function to decide if a particular debugging message is
* wanted.
*/
int
SNOOP_ShowDebugmsgSnoop
(
const
char
*
dll
,
int
ord
,
const
char
*
fname
)
{
if
(
debug_snoop_excludelist
||
debug_snoop_includelist
)
{
const
char
**
listitem
;
char
buf
[
80
];
int
len
,
len2
,
itemlen
,
show
;
if
(
debug_snoop_excludelist
)
{
show
=
1
;
listitem
=
debug_snoop_excludelist
;
}
else
{
show
=
0
;
listitem
=
debug_snoop_includelist
;
}
len
=
strlen
(
dll
);
assert
(
len
<
64
);
sprintf
(
buf
,
"%s.%d"
,
dll
,
ord
);
len2
=
strlen
(
buf
);
for
(;
*
listitem
;
listitem
++
)
{
itemlen
=
strlen
(
*
listitem
);
if
((
itemlen
==
len
&&
!
strncasecmp
(
*
listitem
,
buf
,
len
))
||
(
itemlen
==
len2
&&
!
strncasecmp
(
*
listitem
,
buf
,
len2
))
||
!
strcasecmp
(
*
listitem
,
fname
))
{
show
=
!
show
;
break
;
}
}
return
show
;
}
return
1
;
}
void
SNOOP_SetupDLL
(
HMODULE
hmod
)
{
SNOOP_DLL
**
dll
=
&
firstdll
;
char
*
p
,
*
name
;
void
*
addr
;
SIZE_T
size
;
IMAGE_EXPORT_DIRECTORY
*
exports
;
exports
=
RtlImageDirectoryEntryToData
(
hmod
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_EXPORT
,
&
size
);
if
(
!
exports
)
return
;
name
=
(
char
*
)
hmod
+
exports
->
Name
;
TRACE
(
"hmod=%p, name=%s
\n
"
,
hmod
,
name
);
while
(
*
dll
)
{
if
((
*
dll
)
->
hmod
==
hmod
)
{
/* another dll, loaded at the same address */
addr
=
(
*
dll
)
->
funs
;
size
=
(
*
dll
)
->
nrofordinals
*
sizeof
(
SNOOP_FUN
);
NtFreeVirtualMemory
(
GetCurrentProcess
(),
&
addr
,
&
size
,
MEM_RELEASE
);
break
;
}
dll
=
&
((
*
dll
)
->
next
);
}
*
dll
=
RtlReAllocateHeap
(
ntdll_get_process_heap
(),
HEAP_ZERO_MEMORY
,
*
dll
,
sizeof
(
SNOOP_DLL
)
+
strlen
(
name
));
(
*
dll
)
->
hmod
=
hmod
;
(
*
dll
)
->
ordbase
=
exports
->
Base
;
(
*
dll
)
->
nrofordinals
=
exports
->
NumberOfFunctions
;
strcpy
(
(
*
dll
)
->
name
,
name
);
p
=
(
*
dll
)
->
name
+
strlen
((
*
dll
)
->
name
)
-
4
;
if
(
p
>
(
*
dll
)
->
name
&&
!
strcasecmp
(
p
,
".dll"
))
*
p
=
0
;
size
=
exports
->
NumberOfFunctions
*
sizeof
(
SNOOP_FUN
);
NtAllocateVirtualMemory
(
GetCurrentProcess
(),
&
addr
,
NULL
,
&
size
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
);
if
(
!
addr
)
{
RtlFreeHeap
(
ntdll_get_process_heap
(),
0
,
*
dll
);
FIXME
(
"out of memory
\n
"
);
return
;
}
(
*
dll
)
->
funs
=
addr
;
memset
((
*
dll
)
->
funs
,
0
,
size
);
}
FARPROC
SNOOP_GetProcAddress
(
HMODULE
hmod
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
DWORD
exp_size
,
FARPROC
origfun
,
DWORD
ordinal
)
{
int
i
;
const
char
*
ename
;
WORD
*
ordinals
;
DWORD
*
names
;
SNOOP_DLL
*
dll
=
firstdll
;
SNOOP_FUN
*
fun
;
IMAGE_SECTION_HEADER
*
sec
;
if
(
!
TRACE_ON
(
snoop
))
return
origfun
;
if
(
!*
(
LPBYTE
)
origfun
)
/* 0x00 is an imposs. opcode, poss. dataref. */
return
origfun
;
sec
=
RtlImageRvaToSection
(
RtlImageNtHeader
(
hmod
),
hmod
,
(
char
*
)
origfun
-
(
char
*
)
hmod
);
if
(
!
sec
||
!
(
sec
->
Characteristics
&
IMAGE_SCN_CNT_CODE
))
return
origfun
;
/* most likely a data reference */
while
(
dll
)
{
if
(
hmod
==
dll
->
hmod
)
break
;
dll
=
dll
->
next
;
}
if
(
!
dll
)
/* probably internal */
return
origfun
;
/* try to find a name for it */
ename
=
NULL
;
names
=
(
DWORD
*
)((
char
*
)
hmod
+
exports
->
AddressOfNames
);
ordinals
=
(
WORD
*
)((
char
*
)
hmod
+
exports
->
AddressOfNameOrdinals
);
if
(
names
)
for
(
i
=
0
;
i
<
exports
->
NumberOfNames
;
i
++
)
{
if
(
ordinals
[
i
]
==
ordinal
)
{
ename
=
(
char
*
)
hmod
+
names
[
i
];
break
;
}
}
if
(
!
SNOOP_ShowDebugmsgSnoop
(
dll
->
name
,
ordinal
,
ename
))
return
origfun
;
assert
(
ordinal
<
dll
->
nrofordinals
);
fun
=
dll
->
funs
+
ordinal
;
if
(
!
fun
->
name
)
{
fun
->
name
=
ename
;
fun
->
lcall
=
0xe8
;
/* NOTE: origreturn struct member MUST come directly after snoopentry */
fun
->
snoopentry
=
(
char
*
)
SNOOP_Entry
-
((
char
*
)(
&
fun
->
nrofargs
));
fun
->
origfun
=
origfun
;
fun
->
nrofargs
=
-
1
;
}
return
(
FARPROC
)
&
(
fun
->
lcall
);
}
static
void
SNOOP_PrintArg
(
DWORD
x
)
{
int
i
,
nostring
;
DPRINTF
(
"%08lx"
,
x
);
if
(
!
HIWORD
(
x
)
||
TRACE_ON
(
seh
))
return
;
/* trivial reject to avoid faults */
__TRY
{
LPBYTE
s
=
(
LPBYTE
)
x
;
i
=
0
;
nostring
=
0
;
while
(
i
<
80
)
{
if
(
s
[
i
]
==
0
)
break
;
if
(
s
[
i
]
<
0x20
)
{
nostring
=
1
;
break
;}
if
(
s
[
i
]
>=
0x80
)
{
nostring
=
1
;
break
;}
i
++
;
}
if
(
!
nostring
&&
i
>
5
)
DPRINTF
(
" %s"
,
debugstr_an
((
LPSTR
)
x
,
i
));
else
/* try unicode */
{
LPWSTR
s
=
(
LPWSTR
)
x
;
i
=
0
;
nostring
=
0
;
while
(
i
<
80
)
{
if
(
s
[
i
]
==
0
)
break
;
if
(
s
[
i
]
<
0x20
)
{
nostring
=
1
;
break
;}
if
(
s
[
i
]
>
0x100
)
{
nostring
=
1
;
break
;}
i
++
;
}
if
(
!
nostring
&&
i
>
5
)
DPRINTF
(
" %s"
,
debugstr_wn
((
LPWSTR
)
x
,
i
));
}
}
__EXCEPT
(
page_fault
)
{
}
__ENDTRY
}
#define CALLER1REF (*(DWORD*)context->Esp)
void
WINAPI
SNOOP_DoEntry
(
CONTEXT86
*
context
)
{
DWORD
ordinal
=
0
,
entry
=
context
->
Eip
-
5
;
SNOOP_DLL
*
dll
=
firstdll
;
SNOOP_FUN
*
fun
=
NULL
;
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
;
}
if
(
!
dll
)
{
FIXME
(
"entrypoint 0x%08lx not found
\n
"
,
entry
);
return
;
/* oops */
}
/* guess cdecl ... */
if
(
fun
->
nrofargs
<
0
)
{
/* Typical cdecl return frame is:
* add esp, xxxxxxxx
* which has (for xxxxxxxx up to 255 the opcode "83 C4 xx".
* (after that 81 C2 xx xx xx xx)
*/
LPBYTE
reteip
=
(
LPBYTE
)
CALLER1REF
;
if
(
reteip
)
{
if
((
reteip
[
0
]
==
0x83
)
&&
(
reteip
[
1
]
==
0xc4
))
fun
->
nrofargs
=
reteip
[
2
]
/
4
;
}
}
while
(
*
rets
)
{
for
(
i
=
0
;
i
<
sizeof
((
*
rets
)
->
entry
)
/
sizeof
((
*
rets
)
->
entry
[
0
]);
i
++
)
if
(
!
(
*
rets
)
->
entry
[
i
].
origreturn
)
break
;
if
(
i
!=
sizeof
((
*
rets
)
->
entry
)
/
sizeof
((
*
rets
)
->
entry
[
0
]))
break
;
rets
=
&
((
*
rets
)
->
next
);
}
if
(
!*
rets
)
{
SIZE_T
size
=
4096
;
VOID
*
addr
;
NtAllocateVirtualMemory
(
GetCurrentProcess
(),
&
addr
,
NULL
,
&
size
,
MEM_COMMIT
|
MEM_RESERVE
,
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
->
dll
=
dll
;
ret
->
args
=
NULL
;
ret
->
ordinal
=
ordinal
;
ret
->
origESP
=
context
->
Esp
;
context
->
Eip
=
(
DWORD
)
fun
->
origfun
;
if
(
fun
->
name
)
DPRINTF
(
"%04lx:CALL %s.%s("
,
GetCurrentThreadId
(),
dll
->
name
,
fun
->
name
);
else
DPRINTF
(
"%04lx:CALL %s.%ld("
,
GetCurrentThreadId
(),
dll
->
name
,
dll
->
ordbase
+
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
));
if
(
i
<
fun
->
nrofargs
-
1
)
DPRINTF
(
","
);
}
if
(
max
!=
fun
->
nrofargs
)
DPRINTF
(
" ..."
);
}
else
if
(
fun
->
nrofargs
<
0
)
{
DPRINTF
(
"<unknown, check return>"
);
ret
->
args
=
RtlAllocateHeap
(
ntdll_get_process_heap
(),
0
,
16
*
sizeof
(
DWORD
));
memcpy
(
ret
->
args
,(
LPBYTE
)(
context
->
Esp
+
4
),
sizeof
(
DWORD
)
*
16
);
}
DPRINTF
(
") ret=%08lx
\n
"
,(
DWORD
)
ret
->
origreturn
);
}
void
WINAPI
SNOOP_DoReturn
(
CONTEXT86
*
context
)
{
SNOOP_RETURNENTRY
*
ret
=
(
SNOOP_RETURNENTRY
*
)(
context
->
Eip
-
5
);
SNOOP_FUN
*
fun
=
&
ret
->
dll
->
funs
[
ret
->
ordinal
];
/* 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
* will be the difference between orig and current ESP
* 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
;
if
(
ret
->
args
)
{
int
i
,
max
;
if
(
fun
->
name
)
DPRINTF
(
"%04lx:RET %s.%s("
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
fun
->
name
);
else
DPRINTF
(
"%04lx:RET %s.%ld("
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
ret
->
dll
->
ordbase
+
ret
->
ordinal
);
max
=
fun
->
nrofargs
;
if
(
max
>
16
)
max
=
16
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
SNOOP_PrintArg
(
ret
->
args
[
i
]);
if
(
i
<
max
-
1
)
DPRINTF
(
","
);
}
DPRINTF
(
") retval=%08lx ret=%08lx
\n
"
,
context
->
Eax
,(
DWORD
)
ret
->
origreturn
);
RtlFreeHeap
(
ntdll_get_process_heap
(),
0
,
ret
->
args
);
ret
->
args
=
NULL
;
}
else
{
if
(
fun
->
name
)
DPRINTF
(
"%04lx:RET %s.%s() retval=%08lx ret=%08lx
\n
"
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
fun
->
name
,
context
->
Eax
,
(
DWORD
)
ret
->
origreturn
);
else
DPRINTF
(
"%04lx:RET %s.%ld() retval=%08lx ret=%08lx
\n
"
,
GetCurrentThreadId
(),
ret
->
dll
->
name
,
ret
->
dll
->
ordbase
+
ret
->
ordinal
,
context
->
Eax
,
(
DWORD
)
ret
->
origreturn
);
}
ret
->
origreturn
=
NULL
;
/* mark as empty */
}
/* assembly wrappers that save the context */
__ASM_GLOBAL_FUNC
(
SNOOP_Entry
,
"call "
__ASM_NAME
(
"__wine_call_from_32_regs"
)
"
\n\t
"
".long "
__ASM_NAME
(
"SNOOP_DoEntry"
)
",0"
);
__ASM_GLOBAL_FUNC
(
SNOOP_Return
,
"call "
__ASM_NAME
(
"__wine_call_from_32_regs"
)
"
\n\t
"
".long "
__ASM_NAME
(
"SNOOP_DoReturn"
)
",0"
);
#else
/* !__i386__ */
void
SNOOP_SetupDLL
(
HMODULE
hmod
)
{
FIXME
(
"snooping works only on i386 for now.
\n
"
);
}
FARPROC
SNOOP_GetProcAddress
(
HMODULE
hmod
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
DWORD
exp_size
,
FARPROC
origfun
,
DWORD
ordinal
)
{
return
origfun
;
}
#endif
/* !__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