instruction_length(): Extended for 0xF0 (lock prefix).
[captive.git] / src / libcaptive / ldr / loader.c
index 9829310..48fe811 100644 (file)
@@ -220,7 +220,9 @@ NTSTATUS err;
 
        /* initialize the module */
        DriverEntry=(PDRIVER_INITIALIZE)(*ModuleObjectp)->EntryPoint;
-       err=(*DriverEntry)(DriverEntry_DriverObject,DriverEntry_RegistryPath);
+       err=(NTSTATUS)captive_stdcall_call_8((CaptiveStdCallFunc8)DriverEntry,
+                       DriverEntry_DriverObject,
+                       DriverEntry_RegistryPath);
        if (!NT_SUCCESS(err))
                goto err_LdrUnloadModule;
 
@@ -429,6 +431,8 @@ static gsize instruction_length(const guint8 *instr)
                        return 1+2;
                case 0xCC:      /* int $0x3 */
                        return 1;
+               case 0xF0:      /* lock prefix */
+                       return 1+instruction_length(instr+1);
                case 0xFA:      /* cli */
                        return 1;
                case 0xFB:      /* sti */
@@ -503,7 +507,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;
 
@@ -548,6 +552,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);
@@ -567,24 +572,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);