Added possibility to filter relay traces based on the module that
called the function. Cleaned up a few traces.
This commit is contained in:
parent
065ac4de85
commit
f130f8099a
|
@ -57,6 +57,7 @@ static WINE_EXCEPTION_FILTER(page_fault)
|
||||||
|
|
||||||
static CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" );
|
static CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" );
|
||||||
static WINE_MODREF *cached_modref;
|
static WINE_MODREF *cached_modref;
|
||||||
|
static WINE_MODREF *current_modref;
|
||||||
|
|
||||||
static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm );
|
static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm );
|
||||||
static FARPROC find_named_export( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
static FARPROC find_named_export( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||||
|
@ -114,8 +115,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward )
|
||||||
|
|
||||||
if (!(wm = MODULE_FindModule( mod_name )))
|
if (!(wm = MODULE_FindModule( mod_name )))
|
||||||
{
|
{
|
||||||
WINE_MODREF *user = get_modref( module );
|
ERR("module not found for forward '%s' used by '%s'\n", forward, current_modref->filename );
|
||||||
ERR("module not found for forward '%s' used by '%s'\n", forward, user->filename );
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((exports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
if ((exports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
||||||
|
@ -124,10 +124,9 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward )
|
||||||
|
|
||||||
if (!proc)
|
if (!proc)
|
||||||
{
|
{
|
||||||
WINE_MODREF *user = get_modref( module );
|
|
||||||
ERR("function not found for forward '%s' used by '%s'."
|
ERR("function not found for forward '%s' used by '%s'."
|
||||||
" If you are using builtin '%s', try using the native one instead.\n",
|
" If you are using builtin '%s', try using the native one instead.\n",
|
||||||
forward, user->filename, user->modname );
|
forward, current_modref->filename, current_modref->modname );
|
||||||
}
|
}
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +143,6 @@ static FARPROC find_ordinal_export( HMODULE module, IMAGE_EXPORT_DIRECTORY *expo
|
||||||
DWORD exp_size, int ordinal )
|
DWORD exp_size, int ordinal )
|
||||||
{
|
{
|
||||||
FARPROC proc;
|
FARPROC proc;
|
||||||
WORD *ordinals = get_rva( module, exports->AddressOfNameOrdinals );
|
|
||||||
DWORD *functions = get_rva( module, exports->AddressOfFunctions );
|
DWORD *functions = get_rva( module, exports->AddressOfFunctions );
|
||||||
|
|
||||||
if (ordinal >= exports->NumberOfFunctions)
|
if (ordinal >= exports->NumberOfFunctions)
|
||||||
|
@ -162,19 +160,11 @@ static FARPROC find_ordinal_export( HMODULE module, IMAGE_EXPORT_DIRECTORY *expo
|
||||||
|
|
||||||
if (TRACE_ON(snoop))
|
if (TRACE_ON(snoop))
|
||||||
{
|
{
|
||||||
/* try to find a name for it */
|
proc = SNOOP_GetProcAddress( module, exports, exp_size, proc, ordinal );
|
||||||
int i;
|
|
||||||
char *ename = "@";
|
|
||||||
DWORD *name = get_rva( module, exports->AddressOfNames );
|
|
||||||
if (name) for (i = 0; i < exports->NumberOfNames; i++)
|
|
||||||
{
|
|
||||||
if (ordinals[i] == ordinal)
|
|
||||||
{
|
|
||||||
ename = get_rva( module, name[i] );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
if (TRACE_ON(relay) && current_modref)
|
||||||
proc = SNOOP_GetProcAddress( module, ename, ordinal, proc );
|
{
|
||||||
|
proc = RELAY_GetProcAddress( module, exports, exp_size, proc, current_modref->modname );
|
||||||
}
|
}
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
@ -235,12 +225,12 @@ static WINE_MODREF *import_dll( HMODULE module, IMAGE_IMPORT_DESCRIPTOR *descr )
|
||||||
status = load_dll( name, 0, &wmImp );
|
status = load_dll( name, 0, &wmImp );
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
WINE_MODREF *user = get_modref( module );
|
|
||||||
if (status == STATUS_NO_SUCH_FILE)
|
if (status == STATUS_NO_SUCH_FILE)
|
||||||
ERR("Module (file) %s (which is needed by %s) not found\n", name, user->filename);
|
ERR("Module (file) %s (which is needed by %s) not found\n",
|
||||||
|
name, current_modref->filename);
|
||||||
else
|
else
|
||||||
ERR("Loading module (file) %s (which is needed by %s) failed (error %ld).\n",
|
ERR("Loading module (file) %s (which is needed by %s) failed (error %ld).\n",
|
||||||
name, user->filename, status);
|
name, current_modref->filename, status);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,9 +256,8 @@ static WINE_MODREF *import_dll( HMODULE module, IMAGE_IMPORT_DESCRIPTOR *descr )
|
||||||
ordinal - exports->Base );
|
ordinal - exports->Base );
|
||||||
if (!thunk_list->u1.Function)
|
if (!thunk_list->u1.Function)
|
||||||
{
|
{
|
||||||
WINE_MODREF *user = get_modref( module );
|
|
||||||
ERR("No implementation for %s.%d imported from %s, setting to 0xdeadbeef\n",
|
ERR("No implementation for %s.%d imported from %s, setting to 0xdeadbeef\n",
|
||||||
name, ordinal, user->filename );
|
name, ordinal, current_modref->filename );
|
||||||
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
|
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,9 +270,8 @@ static WINE_MODREF *import_dll( HMODULE module, IMAGE_IMPORT_DESCRIPTOR *descr )
|
||||||
pe_name->Name, pe_name->Hint );
|
pe_name->Name, pe_name->Hint );
|
||||||
if (!thunk_list->u1.Function)
|
if (!thunk_list->u1.Function)
|
||||||
{
|
{
|
||||||
WINE_MODREF *user = get_modref( module );
|
|
||||||
ERR("No implementation for %s.%s imported from %s, setting to 0xdeadbeef\n",
|
ERR("No implementation for %s.%s imported from %s, setting to 0xdeadbeef\n",
|
||||||
name, pe_name->Name, user->filename );
|
name, pe_name->Name, current_modref->filename );
|
||||||
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
|
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,6 +292,7 @@ DWORD PE_fixup_imports( WINE_MODREF *wm )
|
||||||
{
|
{
|
||||||
int i, nb_imports;
|
int i, nb_imports;
|
||||||
IMAGE_IMPORT_DESCRIPTOR *imports;
|
IMAGE_IMPORT_DESCRIPTOR *imports;
|
||||||
|
WINE_MODREF *prev;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
||||||
|
@ -328,11 +317,14 @@ DWORD PE_fixup_imports( WINE_MODREF *wm )
|
||||||
/* load the imported modules. They are automatically
|
/* load the imported modules. They are automatically
|
||||||
* added to the modref list of the process.
|
* added to the modref list of the process.
|
||||||
*/
|
*/
|
||||||
|
prev = current_modref;
|
||||||
|
current_modref = wm;
|
||||||
for (i = 0; i < nb_imports; i++)
|
for (i = 0; i < nb_imports; i++)
|
||||||
{
|
{
|
||||||
if (!(wm->deps[i] = import_dll( wm->ldr.BaseAddress, &imports[i] ))) return 1;
|
if (!(wm->deps[i] = import_dll( wm->ldr.BaseAddress, &imports[i] ))) break;
|
||||||
}
|
}
|
||||||
return 0;
|
current_modref = prev;
|
||||||
|
return (i < nb_imports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -403,6 +395,7 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
|
||||||
{
|
{
|
||||||
static const char * const typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
|
static const char * const typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
|
||||||
"THREAD_ATTACH", "THREAD_DETACH" };
|
"THREAD_ATTACH", "THREAD_DETACH" };
|
||||||
|
char mod_name[32];
|
||||||
BOOL retv = TRUE;
|
BOOL retv = TRUE;
|
||||||
DLLENTRYPROC entry = wm->ldr.EntryPoint;
|
DLLENTRYPROC entry = wm->ldr.EntryPoint;
|
||||||
void *module = wm->ldr.BaseAddress;
|
void *module = wm->ldr.BaseAddress;
|
||||||
|
@ -412,22 +405,25 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
|
||||||
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return TRUE;
|
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return TRUE;
|
||||||
if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return TRUE;
|
if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return TRUE;
|
||||||
|
|
||||||
TRACE("(%p (%s),%s,%p) - CALL\n", module, wm->modname, typeName[type], lpReserved );
|
|
||||||
|
|
||||||
if (TRACE_ON(relay))
|
if (TRACE_ON(relay))
|
||||||
DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p,type=%ld,res=%p)\n",
|
{
|
||||||
GetCurrentThreadId(), entry, module, type, lpReserved );
|
size_t len = max( strlen(wm->modname), sizeof(mod_name)-1 );
|
||||||
|
memcpy( mod_name, wm->modname, len );
|
||||||
|
mod_name[len] = 0;
|
||||||
|
DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p (%s),type=%ld,res=%p)\n",
|
||||||
|
GetCurrentThreadId(), entry, module, mod_name, type, lpReserved );
|
||||||
|
}
|
||||||
|
else TRACE("(%p (%s),%s,%p) - CALL\n", module, wm->modname, typeName[type], lpReserved );
|
||||||
|
|
||||||
retv = entry( module, type, lpReserved );
|
retv = entry( module, type, lpReserved );
|
||||||
|
|
||||||
if (TRACE_ON(relay))
|
|
||||||
DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p,type=%ld,res=%p) retval=%x\n",
|
|
||||||
GetCurrentThreadId(), entry, module, type, lpReserved, retv );
|
|
||||||
|
|
||||||
/* The state of the module list may have changed due to the call
|
/* The state of the module list may have changed due to the call
|
||||||
to the dll. We cannot assume that this module has not been
|
to the dll. We cannot assume that this module has not been
|
||||||
deleted. */
|
deleted. */
|
||||||
TRACE("(%p,%s,%p) - RETURN %d\n", module, typeName[type], lpReserved, retv );
|
if (TRACE_ON(relay))
|
||||||
|
DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p (%s),type=%ld,res=%p) retval=%x\n",
|
||||||
|
GetCurrentThreadId(), entry, module, mod_name, type, lpReserved, retv );
|
||||||
|
else TRACE("(%p,%s,%p) - RETURN %d\n", module, typeName[type], lpReserved, retv );
|
||||||
|
|
||||||
return retv;
|
return retv;
|
||||||
}
|
}
|
||||||
|
@ -494,9 +490,11 @@ BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
|
||||||
/* Call DLL entry point */
|
/* Call DLL entry point */
|
||||||
if ( retv )
|
if ( retv )
|
||||||
{
|
{
|
||||||
|
WINE_MODREF *prev = current_modref;
|
||||||
|
current_modref = wm;
|
||||||
retv = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
|
retv = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
|
||||||
if ( retv )
|
if (retv) wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
|
||||||
wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
|
current_modref = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-insert MODREF at head of list */
|
/* Re-insert MODREF at head of list */
|
||||||
|
|
|
@ -34,6 +34,12 @@ extern void NTDLL_get_server_timeout( abs_time_t *when, const LARGE_INTEGER *tim
|
||||||
/* module handling */
|
/* module handling */
|
||||||
extern WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename );
|
extern WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename );
|
||||||
|
|
||||||
|
extern FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||||
|
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 );
|
||||||
|
|
||||||
static inline HANDLE ntdll_get_process_heap(void)
|
static inline HANDLE ntdll_get_process_heap(void)
|
||||||
{
|
{
|
||||||
HANDLE *pdb = (HANDLE *)NtCurrentTeb()->process;
|
HANDLE *pdb = (HANDLE *)NtCurrentTeb()->process;
|
||||||
|
|
|
@ -207,6 +207,8 @@ WINE REGISTRY Version 2
|
||||||
[Debug]
|
[Debug]
|
||||||
;"RelayExclude" = "RtlEnterCriticalSection;RtlLeaveCriticalSection"
|
;"RelayExclude" = "RtlEnterCriticalSection;RtlLeaveCriticalSection"
|
||||||
;"RelayInclude" = "user32.CreateWindowA"
|
;"RelayInclude" = "user32.CreateWindowA"
|
||||||
|
;"RelayFromExclude" = "user32;x11drv"
|
||||||
|
;"RelayFromInclude" = "sol.exe"
|
||||||
;"SnoopExclude" = "RtlEnterCriticalSection;RtlLeaveCriticalSection"
|
;"SnoopExclude" = "RtlEnterCriticalSection;RtlLeaveCriticalSection"
|
||||||
;"SpyExclude" = "WM_SIZE;WM_TIMER;"
|
;"SpyExclude" = "WM_SIZE;WM_TIMER;"
|
||||||
|
|
||||||
|
|
|
@ -277,28 +277,40 @@ default: none
|
||||||
.br
|
.br
|
||||||
default: none
|
default: none
|
||||||
.br
|
.br
|
||||||
Used to specify which function will be excluded from a relay debuglog.
|
Used to specify which functions will be excluded from a relay debug log.
|
||||||
.PP
|
.PP
|
||||||
.I format: """RelayInclude""=""<message names separated by semicolons>"""
|
.I format: """RelayInclude""=""<function or dll.functions separated by semicolons>"""
|
||||||
|
.br
|
||||||
|
default: include all functions
|
||||||
|
.br
|
||||||
|
Used to specify which functions will be included in a relay debug log.
|
||||||
|
.PP
|
||||||
|
.I format: """RelayFromExclude""=""<module names separated by semicolons>"""
|
||||||
.br
|
.br
|
||||||
default: none
|
default: none
|
||||||
.br
|
.br
|
||||||
Used to specify which function will be included in relay debuglog.
|
Used to specify a set of modules whose calls are excluded from a relay debug log.
|
||||||
|
.PP
|
||||||
|
.I format: """RelayFromInclude""=""<module names separated by semicolons>"""
|
||||||
|
.br
|
||||||
|
default: include all modules
|
||||||
|
.br
|
||||||
|
Used to specify the set of modules whose calls are included in a relay debug log.
|
||||||
.PP
|
.PP
|
||||||
.I format: """SnoopExclude""=""<message names separated by semicolons>"""
|
.I format: """SnoopExclude""=""<message names separated by semicolons>"""
|
||||||
.br
|
.br
|
||||||
default: none
|
default: none
|
||||||
.br
|
.br
|
||||||
Used to specify which function will be included in snoop debuglog.
|
Used to specify which functions will be included in snoop debug log.
|
||||||
.PP
|
.PP
|
||||||
.I format: """SnoopInclude""=""<message names separated by semicolons>"""
|
.I format: """SnoopInclude""=""<message names separated by semicolons>"""
|
||||||
.br
|
.br
|
||||||
default: none
|
default: include all functions
|
||||||
.br
|
.br
|
||||||
Used to specify which function will be included in snoop debuglog.
|
Used to specify which functions will be included in snoop debug log.
|
||||||
.PP
|
.PP
|
||||||
For Relay and Snoop <dllname>.* includes or excludes the whole dll. Exclude
|
For Relay and Snoop <dllname>.* includes or excludes the whole dll. Exclude
|
||||||
entries overwrite Include Entries.
|
entries overwrite Include entries.
|
||||||
.br
|
.br
|
||||||
.PP
|
.PP
|
||||||
.B [Tweak.Layout]
|
.B [Tweak.Layout]
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
|
||||||
extern void SNOOP_RegisterDLL(HMODULE,LPCSTR,DWORD,DWORD);
|
extern void SNOOP_RegisterDLL(HMODULE,LPCSTR,DWORD,DWORD);
|
||||||
extern FARPROC SNOOP_GetProcAddress(HMODULE,LPCSTR,DWORD,FARPROC);
|
|
||||||
extern void SNOOP16_RegisterDLL(NE_MODULE*,LPCSTR);
|
extern void SNOOP16_RegisterDLL(NE_MODULE*,LPCSTR);
|
||||||
extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16);
|
extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16);
|
||||||
extern int SNOOP_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname);
|
extern int SNOOP_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname);
|
||||||
|
|
|
@ -42,8 +42,6 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(module);
|
WINE_DEFAULT_DEBUG_CHANNEL(module);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
|
|
||||||
extern void RELAY_SetupDLL( const char *module );
|
|
||||||
|
|
||||||
static HMODULE main_module;
|
static HMODULE main_module;
|
||||||
static NTSTATUS last_status; /* use to gather all errors in callback */
|
static NTSTATUS last_status; /* use to gather all errors in callback */
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,9 @@ const char **debug_relay_includelist = NULL;
|
||||||
const char **debug_snoop_excludelist = NULL;
|
const char **debug_snoop_excludelist = NULL;
|
||||||
const char **debug_snoop_includelist = NULL;
|
const char **debug_snoop_includelist = NULL;
|
||||||
|
|
||||||
|
static const char **debug_from_relay_excludelist;
|
||||||
|
static const char **debug_from_relay_includelist;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* build_list
|
* build_list
|
||||||
*
|
*
|
||||||
|
@ -103,6 +106,8 @@ void RELAY_InitDebugLists(void)
|
||||||
static const WCHAR RelayExcludeW[] = {'R','e','l','a','y','E','x','c','l','u','d','e',0};
|
static const WCHAR RelayExcludeW[] = {'R','e','l','a','y','E','x','c','l','u','d','e',0};
|
||||||
static const WCHAR SnoopIncludeW[] = {'S','n','o','o','p','I','n','c','l','u','d','e',0};
|
static const WCHAR SnoopIncludeW[] = {'S','n','o','o','p','I','n','c','l','u','d','e',0};
|
||||||
static const WCHAR SnoopExcludeW[] = {'S','n','o','o','p','E','x','c','l','u','d','e',0};
|
static const WCHAR SnoopExcludeW[] = {'S','n','o','o','p','E','x','c','l','u','d','e',0};
|
||||||
|
static const WCHAR RelayFromIncludeW[] = {'R','e','l','a','y','F','r','o','m','I','n','c','l','u','d','e',0};
|
||||||
|
static const WCHAR RelayFromExcludeW[] = {'R','e','l','a','y','F','r','o','m','E','x','c','l','u','d','e',0};
|
||||||
|
|
||||||
attr.Length = sizeof(attr);
|
attr.Length = sizeof(attr);
|
||||||
attr.RootDirectory = 0;
|
attr.RootDirectory = 0;
|
||||||
|
@ -143,6 +148,20 @@ void RELAY_InitDebugLists(void)
|
||||||
debug_snoop_excludelist = build_list( str );
|
debug_snoop_excludelist = build_list( str );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString( &name, RelayFromIncludeW );
|
||||||
|
if (!NtQueryValueKey( hkey, &name, KeyValuePartialInformation, buffer, sizeof(buffer), &count ))
|
||||||
|
{
|
||||||
|
TRACE("RelayFromInclude = %s\n", debugstr_w(str) );
|
||||||
|
debug_from_relay_includelist = build_list( str );
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString( &name, RelayFromExcludeW );
|
||||||
|
if (!NtQueryValueKey( hkey, &name, KeyValuePartialInformation, buffer, sizeof(buffer), &count ))
|
||||||
|
{
|
||||||
|
TRACE( "RelayFromExclude = %s\n", debugstr_w(str) );
|
||||||
|
debug_from_relay_excludelist = build_list( str );
|
||||||
|
}
|
||||||
|
|
||||||
NtClose( hkey );
|
NtClose( hkey );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +218,40 @@ static BOOL check_relay_include( const char *module, const char *func )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* check_relay_from_module
|
||||||
|
*
|
||||||
|
* Check if calls from a given module must be included in the relay output.
|
||||||
|
*/
|
||||||
|
static BOOL check_relay_from_module( const char *module )
|
||||||
|
{
|
||||||
|
const char **listitem;
|
||||||
|
BOOL show;
|
||||||
|
|
||||||
|
if (!debug_from_relay_excludelist && !debug_from_relay_includelist) return TRUE;
|
||||||
|
if (debug_from_relay_excludelist)
|
||||||
|
{
|
||||||
|
show = TRUE;
|
||||||
|
listitem = debug_from_relay_excludelist;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
show = FALSE;
|
||||||
|
listitem = debug_from_relay_includelist;
|
||||||
|
}
|
||||||
|
for(; *listitem; listitem++)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!strcasecmp( *listitem, module )) return !show;
|
||||||
|
len = strlen( *listitem );
|
||||||
|
if (!strncasecmp( *listitem, module, len ) && !strcasecmp( module + len, ".dll" ))
|
||||||
|
return !show;
|
||||||
|
}
|
||||||
|
return show;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* find_exported_name
|
* find_exported_name
|
||||||
*
|
*
|
||||||
|
@ -547,6 +600,26 @@ static BOOL is_register_entry_point( const BYTE *addr )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RELAY_GetProcAddress
|
||||||
|
*
|
||||||
|
* Return the proc address to use for a given function.
|
||||||
|
*/
|
||||||
|
FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||||
|
DWORD exp_size, FARPROC proc, const char *user )
|
||||||
|
{
|
||||||
|
DEBUG_ENTRY_POINT *debug = (DEBUG_ENTRY_POINT *)proc;
|
||||||
|
DEBUG_ENTRY_POINT *list = (DEBUG_ENTRY_POINT *)((char *)exports + exp_size);
|
||||||
|
|
||||||
|
if (debug < list || debug >= list + exports->NumberOfFunctions) return proc;
|
||||||
|
if (list + (debug - list) != debug) return proc; /* not a valid address */
|
||||||
|
if (check_relay_from_module( user )) return proc; /* we want to relay it */
|
||||||
|
if (!debug->call) return proc; /* not a normal function */
|
||||||
|
if (debug->call != 0xe8 && debug->call != 0xe9) return proc; /* not a debug thunk at all */
|
||||||
|
return debug->orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RELAY_SetupDLL
|
* RELAY_SetupDLL
|
||||||
*
|
*
|
||||||
|
@ -602,6 +675,12 @@ void RELAY_SetupDLL( const char *module )
|
||||||
|
|
||||||
#else /* __i386__ */
|
#else /* __i386__ */
|
||||||
|
|
||||||
|
FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||||
|
DWORD exp_size, FARPROC proc, const char *user )
|
||||||
|
{
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
void RELAY_SetupDLL( const char *module )
|
void RELAY_SetupDLL( const char *module )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ typedef struct tagSNOOP_FUN {
|
||||||
/* unreached */
|
/* unreached */
|
||||||
int nrofargs;
|
int nrofargs;
|
||||||
FARPROC origfun;
|
FARPROC origfun;
|
||||||
char *name;
|
const char *name;
|
||||||
} SNOOP_FUN;
|
} SNOOP_FUN;
|
||||||
|
|
||||||
typedef struct tagSNOOP_DLL {
|
typedef struct tagSNOOP_DLL {
|
||||||
|
@ -180,8 +180,13 @@ SNOOP_RegisterDLL(HMODULE hmod,LPCSTR name,DWORD ordbase,DWORD nrofordinals) {
|
||||||
memset((*dll)->funs,0,size);
|
memset((*dll)->funs,0,size);
|
||||||
}
|
}
|
||||||
|
|
||||||
FARPROC
|
FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
|
||||||
SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) {
|
FARPROC origfun, DWORD ordinal )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *ename;
|
||||||
|
WORD *ordinals;
|
||||||
|
DWORD *names;
|
||||||
SNOOP_DLL *dll = firstdll;
|
SNOOP_DLL *dll = firstdll;
|
||||||
SNOOP_FUN *fun;
|
SNOOP_FUN *fun;
|
||||||
IMAGE_SECTION_HEADER *sec;
|
IMAGE_SECTION_HEADER *sec;
|
||||||
|
@ -202,14 +207,26 @@ SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) {
|
||||||
}
|
}
|
||||||
if (!dll) /* probably internal */
|
if (!dll) /* probably internal */
|
||||||
return origfun;
|
return origfun;
|
||||||
if (!SNOOP_ShowDebugmsgSnoop(dll->name,ordinal,name))
|
|
||||||
|
/* 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;
|
return origfun;
|
||||||
assert(ordinal < dll->nrofordinals);
|
assert(ordinal < dll->nrofordinals);
|
||||||
fun = dll->funs+ordinal;
|
fun = dll->funs+ordinal;
|
||||||
if (!fun->name)
|
if (!fun->name)
|
||||||
{
|
{
|
||||||
fun->name = RtlAllocateHeap(ntdll_get_process_heap(),0,strlen(name)+1);
|
fun->name = ename;
|
||||||
strcpy( fun->name, name );
|
|
||||||
fun->lcall = 0xe8;
|
fun->lcall = 0xe8;
|
||||||
/* NOTE: origreturn struct member MUST come directly after snoopentry */
|
/* NOTE: origreturn struct member MUST come directly after snoopentry */
|
||||||
fun->snoopentry = (char*)SNOOP_Entry-((char*)(&fun->nrofargs));
|
fun->snoopentry = (char*)SNOOP_Entry-((char*)(&fun->nrofargs));
|
||||||
|
@ -330,7 +347,8 @@ void WINAPI SNOOP_DoEntry( CONTEXT86 *context )
|
||||||
|
|
||||||
context->Eip = (DWORD)fun->origfun;
|
context->Eip = (DWORD)fun->origfun;
|
||||||
|
|
||||||
DPRINTF("%04lx:CALL %s.%ld: %s(",GetCurrentThreadId(),dll->name,dll->ordbase+ordinal,fun->name);
|
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) {
|
if (fun->nrofargs>0) {
|
||||||
max = fun->nrofargs; if (max>16) max=16;
|
max = fun->nrofargs; if (max>16) max=16;
|
||||||
for (i=0;i<max;i++)
|
for (i=0;i<max;i++)
|
||||||
|
@ -353,6 +371,7 @@ void WINAPI SNOOP_DoEntry( CONTEXT86 *context )
|
||||||
void WINAPI SNOOP_DoReturn( CONTEXT86 *context )
|
void WINAPI SNOOP_DoReturn( CONTEXT86 *context )
|
||||||
{
|
{
|
||||||
SNOOP_RETURNENTRY *ret = (SNOOP_RETURNENTRY*)(context->Eip - 5);
|
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
|
/* 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
|
* function it is too late anyway and we can just set '0' (which
|
||||||
|
@ -365,10 +384,13 @@ void WINAPI SNOOP_DoReturn( CONTEXT86 *context )
|
||||||
if (ret->args) {
|
if (ret->args) {
|
||||||
int i,max;
|
int i,max;
|
||||||
|
|
||||||
DPRINTF("%04lx:RET %s.%ld: %s(",
|
if (fun->name)
|
||||||
GetCurrentThreadId(),
|
DPRINTF("%04lx:RET %s.%s(", GetCurrentThreadId(), ret->dll->name, fun->name);
|
||||||
ret->dll->name,ret->dll->ordbase+ret->ordinal,ret->dll->funs[ret->ordinal].name);
|
else
|
||||||
max = ret->dll->funs[ret->ordinal].nrofargs;
|
DPRINTF("%04lx:RET %s.%ld(", GetCurrentThreadId(),
|
||||||
|
ret->dll->name,ret->dll->ordbase+ret->ordinal);
|
||||||
|
|
||||||
|
max = fun->nrofargs;
|
||||||
if (max>16) max=16;
|
if (max>16) max=16;
|
||||||
|
|
||||||
for (i=0;i<max;i++)
|
for (i=0;i<max;i++)
|
||||||
|
@ -380,11 +402,19 @@ void WINAPI SNOOP_DoReturn( CONTEXT86 *context )
|
||||||
context->Eax,(DWORD)ret->origreturn );
|
context->Eax,(DWORD)ret->origreturn );
|
||||||
RtlFreeHeap(ntdll_get_process_heap(),0,ret->args);
|
RtlFreeHeap(ntdll_get_process_heap(),0,ret->args);
|
||||||
ret->args = NULL;
|
ret->args = NULL;
|
||||||
} else
|
}
|
||||||
DPRINTF("%04lx:RET %s.%ld: %s() retval = %08lx ret=%08lx\n",
|
else
|
||||||
|
{
|
||||||
|
if (fun->name)
|
||||||
|
DPRINTF("%04lx:RET %s.%s() retval=%08lx ret=%08lx\n",
|
||||||
GetCurrentThreadId(),
|
GetCurrentThreadId(),
|
||||||
ret->dll->name,ret->dll->ordbase+ret->ordinal,ret->dll->funs[ret->ordinal].name,
|
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);
|
context->Eax, (DWORD)ret->origreturn);
|
||||||
|
}
|
||||||
ret->origreturn = NULL; /* mark as empty */
|
ret->origreturn = NULL; /* mark as empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +432,9 @@ void SNOOP_RegisterDLL(HMODULE hmod,LPCSTR name,DWORD nrofordinals, DWORD dw) {
|
||||||
FIXME("snooping works only on i386 for now.\n");
|
FIXME("snooping works only on i386 for now.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
FARPROC SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) {
|
FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
|
||||||
|
FARPROC origfun, DWORD ordinal )
|
||||||
|
{
|
||||||
return origfun;
|
return origfun;
|
||||||
}
|
}
|
||||||
#endif /* !__i386__ */
|
#endif /* !__i386__ */
|
||||||
|
|
Loading…
Reference in New Issue