From d54cff4aa7c6de615bd7125a675addba3ea902e2 Mon Sep 17 00:00:00 2001 From: short <> Date: Tue, 28 Oct 2003 18:58:46 +0000 Subject: [PATCH] Do not SIGSEGV patch 'pass' functions of W32 code in non--debug-messages mode. - Performance reasons. --- src/libcaptive/client/init.c | 9 ++++--- src/libcaptive/include/captive/ldr_exports.h | 20 ++++++++++++++-- src/libcaptive/ke/captivesym.pl | 35 +++++++++++++++++++++------- src/libcaptive/ldr/loader.c | 35 +++++++++++++++------------- 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/libcaptive/client/init.c b/src/libcaptive/client/init.c index a2459e4..e20eda6 100644 --- a/src/libcaptive/client/init.c +++ b/src/libcaptive/client/init.c @@ -167,14 +167,17 @@ NTSTATUS err; *KeNumberProcessorsp=KeNumberProcessors; g_assert(*KeNumberProcessorsp==1); } - /* Apply captive_kernel_patches() AFTER any symbols sanity checks above! */ - captive_kernel_patches(); + /* Apply AFTER any symbols sanity checks above! */ + if (captive_options->debug_messages) + captive_kernel_patches_debug(); + else + captive_kernel_patches_nondebug(); _local_unwind2_addr=captive_Module_GetExportAddress("ntoskrnl.exe","_local_unwind2"); /* Initialize 'FsRtlLegalAnsiCharacterArray'. * It requires 'ntoskrnl.exe' loaded by 'captive_options->load_module' above; - * captive_kernel_patches() should not be needed. + * captive_kernel_patches_debug()/captive_kernel_patches_nondebug() should not be needed. */ captive_FsRtlLegalAnsiCharacterArray_init(); diff --git a/src/libcaptive/include/captive/ldr_exports.h b/src/libcaptive/include/captive/ldr_exports.h index 72c777a..280e04c 100644 --- a/src/libcaptive/include/captive/ldr_exports.h +++ b/src/libcaptive/include/captive/ldr_exports.h @@ -49,7 +49,7 @@ gboolean captive_kernel_exports(void); /** - * captive_kernel_patches: + * captive_kernel_patches_debug: * * Patches W32 libraries by libcaptive functions. It is done by *.def files used * by dlltool(1) of Mingw32 compiler suite. We use native host OS compiler and @@ -60,11 +60,27 @@ gboolean captive_kernel_exports(void); * This function is generated automatically from #exports.captivesym file * by #captivesym.pl script. * + * This function is used in --debug-messages mode as it also patches 'pass' + * functions to be successfuly debug dumped. + * * Multiple calls of this function are forbidden. See also captive_kernel_exports(). * * Returns: %TRUE if the export was successful. */ -gboolean captive_kernel_patches(void); +gboolean captive_kernel_patches_debug(void); + + +/** + * captive_kernel_patches_nondebug: + * + * Function equivalent to captive_kernel_patches_debug() but it does not patch + * 'pass' functions as they are not needed to be traced if no --debug-messages + * was specified. See captive_kernel_patches_debug() for the description + * of this function. + * + * Returns: %TRUE if the export was successful. + */ +gboolean captive_kernel_patches_nondebug(void); struct captive_ModuleList_patchpoint { diff --git a/src/libcaptive/ke/captivesym.pl b/src/libcaptive/ke/captivesym.pl index 5811ba4..f37f9be 100755 --- a/src/libcaptive/ke/captivesym.pl +++ b/src/libcaptive/ke/captivesym.pl @@ -108,6 +108,8 @@ print <<"HERE"; #include /* for built-in: strncmp,memmove,strncpy */ +extern gboolean captive_debug_messages_disabled; + HERE for my $symbol (sort keys(%symbol)) { @@ -195,8 +197,20 @@ HERE "\tg_return_val_if_fail(${symbol}_patchpoint.orig_w32_func!=NULL,0);\n", "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n", "\t${symbol}_patchpoint.through_w32_func=TRUE;\n", - "\tr=(*(${symbol}_t_attrib *)${symbol}_patchpoint.orig_w32_func)(".join(",",@args_in).");\n", - "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n"; + "\tr=(*(${symbol}_t_attrib *)${symbol}_patchpoint.orig_w32_func)(".join(",",@args_in).");\n"; + if (!$def->{"pass"}) { + print + "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n"; + } + else { + print + "\tif (!captive_debug_messages_disabled)\n", + "\t\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n", + "\telse {\n", + "\t\tg_assert(${symbol}_patchpoint.through_w32_func==TRUE);\n", + "\t\t${symbol}_patchpoint.through_w32_func=FALSE;\n", + "\t\t}\n"; + } } else { print @@ -215,7 +229,7 @@ HERE } # write function captive_kernel_{exports,patches}() -for my $functype ("exports","patches") { +for my $functype ("exports","patches_debug","patches_nondebug") { print <<"HERE"; gboolean captive_kernel_$functype(void) @@ -225,17 +239,20 @@ gboolean errbool; HERE for my $module (sort keys(%module)) { my $moduleref=$module{$module}; - next if ($functype eq "patches") != defined $patch{$module}; + next if ($functype=~/^patches/) != defined $patch{$module}; print "\t\terrbool=" - .($functype eq "patches" ? "captive_ModuleList_patch" : "captive_ModuleList_add_builtin") + .($functype=~/^patches/ ? "captive_ModuleList_patch" : "captive_ModuleList_add_builtin") ."(\"$module\",\n"; for my $symbol (sort keys(%$moduleref)) { - next if $functype eq "patches" && !$def{$symbol}; + next if $functype=~/^patches/ && !$def{$symbol}; (my $symbol_outer=$symbol)=~s/^captive_reactos_//; - print "\t\t\t\"$symbol_outer\",",(($functype eq "patches" && "data" eq $def{$symbol}{"type"} - && ($def{$symbol}{"pass"} || $def{$symbol}{"wrap"})) ? ("NULL") + print "\t\t\t\"$symbol_outer\",",(($functype=~/^patches/ && "data" eq $def{$symbol}{"type"} + && ($def{$symbol}{"pass"} || $def{$symbol}{"wrap"})) ? ("NULL") : ("&${symbol}_",($def{$symbol}{"type"} || "undef"))), - (($functype ne "patches") ? () : (",".("data" eq $def{$symbol}{"type"} ? "NULL" : "&${symbol}_patchpoint"))), + (($functype!~/^patches/) ? () : + (",".("data" eq $def{$symbol}{"type"} ? "NULL,NULL" : + ($functype eq "patches_nondebug" && $def{$symbol}{"pass"} ? "&${symbol}_patchpoint,NULL" : + "&${symbol}_patchpoint,&${symbol}_patchpoint")))), ",\n"; } print <<"HERE"; diff --git a/src/libcaptive/ldr/loader.c b/src/libcaptive/ldr/loader.c index 8629e22..a030a1f 100644 --- a/src/libcaptive/ldr/loader.c +++ b/src/libcaptive/ldr/loader.c @@ -505,7 +505,7 @@ USHORT Idx; PVOID ExportAddress,*ExportAddressp; const gchar *sym_name; void (*sym_val)(void); -struct captive_ModuleList_patchpoint *patchpoint; +struct captive_ModuleList_patchpoint *patchpoint,*patchpointpatch; GHashTable *exportdir_hash; gboolean errbool; @@ -550,6 +550,7 @@ CHAR *funcname=MODULEOBJECT_BASE_OFFSET_PLUS(NameList[Idx]); captive_va_arg(sym_val ,ap); /* 'sym_val' may be NULL if 'data' type && "pass"ed */ captive_va_arg(patchpoint,ap); /* 'data' type if ==NULL */ + captive_va_arg(patchpointpatch,ap); /* 'data' type or 'pass' in non-debug mode if ==NULL */ ExportAddressp=g_hash_table_lookup(exportdir_hash,sym_name); if (ExportAddressp==NULL) { g_message("%s: Function not found for patchpoint (ignoring): %s",G_STRLOC,sym_name); @@ -569,24 +570,26 @@ CHAR *funcname=MODULEOBJECT_BASE_OFFSET_PLUS(NameList[Idx]); if (!patchpoint) /* 'data' type && !"pass"ed => do not corrupt it by 0xF4 */ continue; patchpoint->orig_w32_func=ExportAddress; - if (0xF4 /* hlt */ ==*patchpoint->orig_w32_func) /* Already patched by name-aliased function? */ + if (!patchpointpatch) /* 'pass' in non-debug mode */ continue; - g_assert(0xF4 /* hlt */ !=*patchpoint->orig_w32_func); - patchpoint->orig_w32_2ndinstr=patchpoint->orig_w32_func - +instruction_length((guint8 *)patchpoint->orig_w32_func); - g_assert(0xF4 /* hlt */ !=*patchpoint->orig_w32_2ndinstr); - patchpoint->wrap_wrap_func=sym_val; - patchpoint->orig_w32_func_byte=*patchpoint->orig_w32_func; - patchpoint->orig_w32_2ndinstr_byte=*patchpoint->orig_w32_2ndinstr; - patchpoint->through_w32_func=FALSE; - g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpoint->orig_w32_func)); + if (0xF4 /* hlt */ ==*patchpointpatch->orig_w32_func) /* Already patched by name-aliased function? */ + continue; + g_assert(0xF4 /* hlt */ !=*patchpointpatch->orig_w32_func); + patchpointpatch->orig_w32_2ndinstr=patchpointpatch->orig_w32_func + +instruction_length((guint8 *)patchpointpatch->orig_w32_func); + g_assert(0xF4 /* hlt */ !=*patchpointpatch->orig_w32_2ndinstr); + patchpointpatch->wrap_wrap_func=sym_val; + patchpointpatch->orig_w32_func_byte=*patchpointpatch->orig_w32_func; + patchpointpatch->orig_w32_2ndinstr_byte=*patchpointpatch->orig_w32_2ndinstr; + patchpointpatch->through_w32_func=FALSE; + g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpointpatch->orig_w32_func)); g_hash_table_insert(captive_ModuleList_patchpoint_hash, - patchpoint->orig_w32_func, /* key */ - patchpoint); /* value */ - g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpoint->orig_w32_2ndinstr)); + patchpointpatch->orig_w32_func, /* key */ + patchpointpatch); /* value */ + g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpointpatch->orig_w32_2ndinstr)); g_hash_table_insert(captive_ModuleList_patchpoint_hash, - patchpoint->orig_w32_2ndinstr, /* key */ - patchpoint); /* value */ + patchpointpatch->orig_w32_2ndinstr, /* key */ + patchpointpatch); /* value */ *(guint8 *)ExportAddress=0xF4; /* hlt */ } va_end(ap); -- 1.8.3.1