- Performance reasons.
*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();
/**
- * 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
* 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 {
#include <string.h> /* for built-in: strncmp,memmove,strncpy */
+extern gboolean captive_debug_messages_disabled;
+
HERE
for my $symbol (sort keys(%symbol)) {
"\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
}
# 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)
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";
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;
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);
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);