diff --git a/khook/x86/Makefile b/khook/x86/Makefile index aabf0aa..22b18e2 100644 --- a/khook/x86/Makefile +++ b/khook/x86/Makefile @@ -1,8 +1,13 @@ STUB = stub.S -stub: FORCE +-: FORCE + @echo "Run make stub or make stub32" + +stub.inc: FORCE gcc $(CFLAGS) -nostdlib -Wl,-e0 $(STUB) -o stub objcopy --dump-section .text=/dev/stdout stub | xxd -i - >stub.inc + +stub32: FORCE gcc $(CFLAGS) -m32 -nostdlib -Wl,-e0 $(STUB) -o stub32 objcopy --dump-section .text=/dev/stdout stub32 | xxd -i - >stub32.inc diff --git a/khook/x86/hook.c b/khook/x86/hook.c index 3f82386..442bb39 100644 --- a/khook/x86/hook.c +++ b/khook/x86/hook.c @@ -1,5 +1,23 @@ #include "../internal.h" +#ifdef __i686__ + +#define kernel_write_enter() asm volatile ( \ + "cli\n\t" \ + "mov %%cr0, %%eax\n\t" \ + "and $0xfffeffff, %%eax\n\t" \ + "mov %%eax, %%cr0\n\t" \ + ::: "%eax" ) + +#define kernel_write_leave() asm volatile ( \ + "mov %%cr0, %%eax\n\t" \ + "or $0x00010000, %%eax\n\t" \ + "mov %%eax, %%cr0\n\t" \ + "sti\n\t" \ + ::: "%eax" ) + +#else + #define kernel_write_enter() asm volatile ( \ "cli\n\t" \ "mov %%cr0, %%rax\n\t" \ @@ -14,6 +32,8 @@ "sti\n\t" \ ::: "%rax" ) +#endif + //////////////////////////////////////////////////////////////////////////////// // IN-kernel length disassembler engine (x86 only, 2.6.33+) //////////////////////////////////////////////////////////////////////////////// diff --git a/khook/x86/stub.S b/khook/x86/stub.S index 5e68dca..b9e451b 100644 --- a/khook/x86/stub.S +++ b/khook/x86/stub.S @@ -21,7 +21,11 @@ KHOOK_STUB_orig: # make a local copy of all arguments starting from N as they are # passed through the stack as per the ABI. # -# TODO: x86-32 implementation of CALL_COPY_N_ARGS macro +# On the Intel 386, the regparm attribute causes the compiler to +# pass up to number integer arguments in registers EAX, EDX, and +# ECX instead of on the stack. Functions that take a variable number +# of arguments will continue to be passed all of their arguments +# on the stack. # #ifdef __x86_64__ @@ -43,14 +47,27 @@ KHOOK_STUB_hook: lock decl KHOOK_STUB_atomic_use_count(%rip) ret #else +.macro CALL_COPY_N_ARGS n + sub $(\n * 4), %esp + .set i, 0 + .rept \n + mov ((\n + i + 1) * 4)(%esp), %ebx + mov %ebx, (i * 4)(%esp) + .set i, i + 1 + .endr + mov $0xcacacaca, %ebx + call *%ebx + add $(\n * 4), %esp +.endm KHOOK_STUB_hook: + push %ebx call 1f -1: pop %eax - lock incl -(1b - KHOOK_STUB_atomic_use_count)(%eax) - mov $0xcacacaca, %eax - call *%eax +1: pop %ebx + lock incl -(1b - KHOOK_STUB_atomic_use_count)(%ebx) + CALL_COPY_N_ARGS 10 call 1f -1: pop %ecx - lock decl -(1b - KHOOK_STUB_atomic_use_count)(%ecx) +1: pop %ebx + lock decl -(1b - KHOOK_STUB_atomic_use_count)(%ebx) + pop %ebx ret #endif diff --git a/khook/x86/stub32.inc b/khook/x86/stub32.inc index 468c057..2c124ae 100644 --- a/khook/x86/stub32.inc +++ b/khook/x86/stub32.inc @@ -2,6 +2,13 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58, 0xf0, 0xff, 0x40, 0xcb, 0xb8, 0xca, - 0xca, 0xca, 0xca, 0xff, 0xd0, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x59, 0xf0, - 0xff, 0x49, 0xba, 0xc3 + 0x53, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf0, 0xff, 0x43, 0xca, 0x83, + 0xec, 0x28, 0x8b, 0x5c, 0x24, 0x2c, 0x89, 0x1c, 0x24, 0x8b, 0x5c, 0x24, + 0x30, 0x89, 0x5c, 0x24, 0x04, 0x8b, 0x5c, 0x24, 0x34, 0x89, 0x5c, 0x24, + 0x08, 0x8b, 0x5c, 0x24, 0x38, 0x89, 0x5c, 0x24, 0x0c, 0x8b, 0x5c, 0x24, + 0x3c, 0x89, 0x5c, 0x24, 0x10, 0x8b, 0x5c, 0x24, 0x40, 0x89, 0x5c, 0x24, + 0x14, 0x8b, 0x5c, 0x24, 0x44, 0x89, 0x5c, 0x24, 0x18, 0x8b, 0x5c, 0x24, + 0x48, 0x89, 0x5c, 0x24, 0x1c, 0x8b, 0x5c, 0x24, 0x4c, 0x89, 0x5c, 0x24, + 0x20, 0x8b, 0x5c, 0x24, 0x50, 0x89, 0x5c, 0x24, 0x24, 0xbb, 0xca, 0xca, + 0xca, 0xca, 0xff, 0xd3, 0x83, 0xc4, 0x28, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0xf0, 0xff, 0x8b, 0x64, 0xff, 0xff, 0xff, 0x5b, 0xc3