alexandernst / monks

Procmon alternative for Linux
71 stars 34 forks source link

Remove (UN)HOOK macros, simplifying code #13

Closed alexandernst closed 11 years ago

alexandernst commented 11 years ago

I'm trying to remove the (UN)HOOK macros and instead hook/unhook all the syscalls iterating over a section with the relevant data.

I made a patch that should work, but it's failing for some strange reason.

This is the patch:

diff --git a/procmon_kmodule/hookfns.c b/procmon_kmodule/hookfns.c
index 2984afd..5faec86 100644
--- a/procmon_kmodule/hookfns.c
+++ b/procmon_kmodule/hookfns.c
@@ -10,13 +10,25 @@
 asm(".section .counters, \"aw\""); //set section allocatable and writable

 void hook_calls(void){
+
+   counter_info_t *iter;
+
    if(get_sct() && set_sct_rw()){

-/* __NR_read / __NR32_read */
-       HOOK(read);
-#ifdef __NR32_read
-       HOOK_IA32(read);
-#endif
+       iter = __start_counters;
+       for(; iter < __stop_counters; ++iter){
+           DEBUG(KERN_INFO "ITER DIR %p\n", iter);
+           if(iter->is32){
+               DEBUG(KERN_INFO "HOOK_IA32 %s\n", iter->name);
+               iter->rf = (void *)ia32_sys_call_table[iter->__NR_];
+               ia32_sys_call_table[iter->__NR_] = (void *)iter->ff;
+           }else{
+               DEBUG(KERN_INFO "HOOK %s\n", iter->name);
+               iter->rf = (void *)sys_call_table[iter->__NR_];
+               sys_call_table[iter->__NR_] = (void *)iter->ff;
+
+           }
+       }

        set_sct_ro();
    }
@@ -33,13 +45,21 @@ void hook_calls(void){
 \*****************************************************************************/

 void unhook_calls(void){
+
+   counter_info_t *iter;
+
    if(get_sct() && set_sct_rw()){

-/* __NR_read / __NR_read32 */
-       UNHOOK(read);
-#ifdef __NR32_read
-       UNHOOK_IA32(read);
-#endif
+       iter = __start_counters;
+       for(; iter < __stop_counters; ++iter){
+           if(iter->is32){
+               DEBUG(KERN_INFO "UNHOOK_IA32 %s\n", iter->name);
+               ia32_sys_call_table[iter->__NR_] = (void *)iter->rf;
+           }else{
+               DEBUG(KERN_INFO "UNHOOK %s\n", iter->name);
+               sys_call_table[iter->__NR_] = (void *)iter->rf;
+           }
+       }

        set_sct_ro();
    }
diff --git a/procmon_kmodule/hookfns.h b/procmon_kmodule/hookfns.h
index 79c4ecb..d61dadc 100644
--- a/procmon_kmodule/hookfns.h
+++ b/procmon_kmodule/hookfns.h
@@ -6,6 +6,10 @@
 typedef struct counter_info {
    atomic_t counter;
    char *name;
+   int is32;
+   int __NR_;
+   void *ff;
+   void *rf;
 } __attribute__((packed)) counter_info_t;

 extern counter_info_t __start_counters[];
@@ -19,20 +23,14 @@ extern counter_info_t __stop_counters[];
 | hooked_sys_##F = FAKE FUNCTION as in the function which we'll be using to fake __NR_##F |
 \*****************************************************************************************/

-#define HOOK(F)                                                    \
-   DEBUG(KERN_INFO "HOOK __NR_" #F "\n");                      \
-   real_sys_##F = (void *)sys_call_table[__NR_##F];            \
-   sys_call_table[__NR_##F] = (void *)hooked_sys_##F;
-
-#define UNHOOK(F)                                              \
-   DEBUG(KERN_INFO "UNHOOK __NR_" #F "\n");                    \
-   sys_call_table[__NR_##F] = (void *)real_sys_##F;
-
 #define REGISTER_SYSCALL(F)                                        \
    static counter_info_t __counter_info___NR_##F               \
-   __attribute((unused, section(".counters"))) = {             \
+   __attribute((section(".counters"))) = {                     \
        .counter = ATOMIC_INIT(0),                              \
        .name = "__NR_" #F,                                     \
+       .is32 = 0,                                              \
+       .__NR_ = __NR_##F,                                      \
+       .ff = hooked_sys_##F,                                   \
    };

 #define __INCR(F)  \
@@ -43,20 +41,14 @@ extern counter_info_t __stop_counters[];

 #ifdef CONFIG_IA32_EMULATION

-#define HOOK_IA32(F)                                           \
-   DEBUG(KERN_INFO "HOOK_IA32 __NR32_" #F "\n");               \
-   real_sys32_##F = (void *)ia32_sys_call_table[__NR32_##F];   \
-   ia32_sys_call_table[__NR32_##F] = (void *)hooked_sys32_##F;
-
-#define UNHOOK_IA32(F)                                         \
-   DEBUG(KERN_INFO "UNHOOK_IA32 __NR32_" #F "\n");             \
-   ia32_sys_call_table[__NR32_##F] = (void *)real_sys32_##F;
-
 #define REGISTER_SYSCALL32(F)                                  \
    static counter_info_t __counter_info___NR32_##F             \
-   __attribute((unused, section(".counters"))) = {             \
+   __attribute((section(".counters"))) = {                     \
        .counter = ATOMIC_INIT(0),                              \
-       .name = "__NR32_" #F "_32",                             \
+       .name = "__NR32_" #F,                                   \
+       .is32 = 1,                                              \
+       .__NR_ = __NR32_##F,                                    \
+       .ff = hooked_sys32_##F,                                 \
    };

 #define __INCR32(F)    \

It seems that the loop iterates 3 times but there are only 2 structs saved in the section. I have noticed that if I remove the __NR_ element from the struct, the loop iterates only 2 times.

@milabs Any ideas?

milabs commented 11 years ago

I can't apply a patch on top of yours repository. Can you create a branch with the modification instead?

alexandernst commented 11 years ago

@milabs Yes, give me a few minutes, please :)

alexandernst commented 11 years ago

@milabs Done, please have a look at https://github.com/alexandernst/procmon/tree/test

milabs commented 11 years ago

milabs@1d3e33cb80d97c424b147b035c0fa7ee1cf502d9 milabs@8169ddafdcc0c58ad9be65c4e7cc9949ef4b7d29

alexandernst commented 11 years ago

Fixed by https://github.com/alexandernst/procmon/commit/825b2d3fa80fca0c95dc4c426b2fc5ce7785fba0, https://github.com/alexandernst/procmon/commit/8169ddafdcc0c58ad9be65c4e7cc9949ef4b7d29, https://github.com/alexandernst/procmon/commit/1d3e33cb80d97c424b147b035c0fa7ee1cf502d9, https://github.com/alexandernst/procmon/commit/73a0d531fcaebb6d59775b1f1f85072e6b4bf557 and https://github.com/alexandernst/procmon/commit/05664123a53354d9569d155d6c8863bb98dfc612