Giter VIP home page Giter VIP logo

linux_kernel_hacking's People

Contributors

h1wind avatar xcellerator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

linux_kernel_hacking's Issues

3.5 hiding processes - logic bug while shifting

            /* If hide_pid is contained in the first struct in the list, then we have to shift everything else up by it's size */
            if ( current_dir == dirent_ker )
            {
                ret -= current_dir->d_reclen;
                memmove(current_dir, (void *)current_dir + current_dir->d_reclen, ret);
                continue;
            }

If we try to hide first process - all linked list shifts, and kernel threads appear on bottom, while user - on top.
Don't think that this is critical bug, but, just for notice :)

Kernel panic in 3.4 caused by __user

Hi, sorry to bother, I'm kind of new to this kind of stuff.

I think I found a problem in the "Hiding a directory" section. If you load the kernel module compiled with the __user keyword in

struct linux_dirent64 __user *dirent = (struct linux_dirent64 *) regs->si;

a kernel panic happens. This can be solved by simply removing the __user keyword, or at least this worked for me.
I'll leave here my system info, in case you want to proceed with a further analysis

OS: ArchLinux
Kernel Version: 5.15.12

Plese, tell me if you need more info about this "problem".

Mattia

code fix in ftrace_helper.h

in later versions, this section of code that in ftrace_helper.h won't compile
`static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *regs)
{
struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);

#if USE_FENTRY_OFFSET
regs->ip = (unsigned long) hook->function;
#else
if(!within_module(parent_ip, THIS_MODULE))
regs->ip = (unsigned long) hook->function;
#endif
}`

her is the fix

`static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
struct pt_regs *regs = ftrace_get_regs(fregs);
struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);

#if USE_FENTRY_OFFSET
regs->ip = (unsigned long)hook->function;
#else
if (!within_module(parent_ip, THIS_MODULE))
regs->ip = (unsigned long)hook->function;
#endif`

Module 3.7_char_interfering updates

Since

torvalds/linux@22b0a22

and

torvalds/linux@1b388e7

the file_operations structs have changed read and writing functions to prefer read_iter and write_iter. These functions now take kiocb and iov_iter structs, which mucks a bit of the coding methodology in the current representation.

I have implemented an alternative solution to the issue by hooking the single function get_random_bytes_user that I plan on submitting a PR for tonight.

Endless loop on sys_mkdir hook (Linux debian 4.19.0-16-amd64)

Hi! I was playing around with the LKMs from the project (which is awesome btw) and I came across a bug while trying to reproduce the hooking of "sys_mkdir" from the code at linux_kernel_hacking/3_RootkitTechniques/3.1_syscall_hooking/rootkit.c (I didn't modify any part of the code)

I made it work in my own repo (you can check my code if you want). I was testing on a VM Linux debian 4.19.0-16-amd64 and my hook doesn't use the pt_regs and it works. I didn't understand why, because as mentioned on the blog post (and the linux docs says that this change affects the versions 4.17.0 and above):

With (64-bit) kernel version 4.17.0, this changed. The arguments that are first stored in registers by the user are copied into a special struct called pt_regs, and then this is the only thing passed to the syscall. The syscall is then responsible for pulling the arguments it needs out of this struct.

Any idea why this is happening?

here is my dmesg output:

/* more looping stuff */
[  286.237562] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237575] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237622] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237635] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237688] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237703] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237754] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237767] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237789] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237802] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237849] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237863] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237896] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237912] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237963] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237977] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.237999] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238012] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238060] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238073] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238094] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238107] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238154] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238168] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238189] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238202] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238249] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238262] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238453] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238469] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238524] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238537] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238560] rootkit: Trying to create directory with name: /var/log/journal/d967f76ed69a437e9a38b474a9001292
[  286.238561] rootkit: restoring mkdir syscall
[  286.238564] rootkit: Unloaded :-(

Seg fault with custom proc device

I decided to make a simple input/output proc device using https://xcellerator.github.io/posts/docker_escape/ and editing the code.
https://gist.github.com/ninjamar/fbf236cc09d3a00460b880d0220054b3
The idea is you echo text to /proc/input and it the text is read from /proc/output

vagrant@ubuntu2004:~/proc$ echo 'foo' > /proc/input
vagrant@ubuntu2004:~/proc$ cat /proc/output
foo

Instead of foo I get segmentation fault

vagrant@ubuntu2004:~/proc$ sudo dmesg
[   46.930281] proc: module verification failed: signature and/or required key missing - tainting kernel
[   46.930668] input: loaded
[   46.930669] output: loaded
[   72.082289] Echoing to /proc/output
[   76.900432] general protection fault: 0000 [#1] SMP PTI
[   76.900509] CPU: 0 PID: 1530 Comm: cat Tainted: G           OE     5.4.0-122-generic #138-Ubuntu
[   76.900555] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[   76.900628] RIP: 0010:proc_reg_release+0x3f/0x70
[   76.900658] Code: 4d 8d 6c 24 18 4c 89 ef e8 9e 61 78 00 49 8b 44 24 08 48 8d 70 f8 4c 39 e6 75 0f eb 23 48 8b 76 08 48 83 ee 08 4c 39 e6 74 16 <48> 39 1e 75 ee 4c 89 e7 e8 a4 fe ff ff 31 c0 5b 41 5c 41 5d 5d c3
[   76.900763] RSP: 0018:ffffa7f78053fe38 EFLAGS: 00010207
[   76.900797] RAX: 7074756f2f636f72 RBX: ffff8ac6f57adf00 RCX: 0000000000000001
[   76.900837] RDX: 0000000000000001 RSI: 7074756f2f636f6a RDI: ffff8ac6f25233d8
[   76.900875] RBP: ffffa7f78053fe50 R08: 0000000000000000 R09: 0000000000000000
[   76.900912] R10: 0000000000000010 R11: ffff8ac6f9044d90 R12: ffff8ac6f25233c0
[   76.900956] R13: ffff8ac6f25233d8 R14: ffff8ac6fcd702a0 R15: ffff8ac6f911d6c0
[   76.900994] FS:  00007ff192d4e580(0000) GS:ffff8ac6fda00000(0000) knlGS:0000000000000000
[   76.901037] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   76.901068] CR2: 00007ff1925c9000 CR3: 0000000070f22005 CR4: 00000000000606f0
[   76.901111] Call Trace:
[   76.901136]  __fput+0xcc/0x260
[   76.901158]  ____fput+0xe/0x10
[   76.901182]  task_work_run+0x8f/0xb0
[   76.901208]  exit_to_usermode_loop+0x131/0x160
[   76.901236]  do_syscall_64+0x163/0x190
[   76.901271]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   76.901302] RIP: 0033:0x7ff192c69817
[   76.901326] Code: ff ff e8 7c 12 02 00 66 2e 0f 1f 84 00 00 00 00 00 66 90 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 b3 5d f8 ff
[   76.901417] RSP: 002b:00007ffe37cad108 EFLAGS: 00000246 ORIG_RAX: 0000000000000003
[   76.901458] RAX: 0000000000000000 RBX: 00007ff1925ca000 RCX: 00007ff192c69817
[   76.901496] RDX: 000000000000000f RSI: 0000000000022000 RDI: 0000000000000003
[   76.901534] RBP: 0000000000000001 R08: 00007ff1925c9000 R09: 0000000000000000
[   76.901572] R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000000000
[   76.901610] R13: 0000000000000fff R14: 0000000000020000 R15: 0000000000020000
[   76.901649] Modules linked in: proc(OE) vboxsf(O) dm_multipath scsi_dh_rdac scsi_dh_emc scsi_dh_alua input_leds vboxguest(O) serio_raw mac_hid sch_fq_codel ipmi_devintf ipmi_msghandler msr ip_tables x_tables autofs4 btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear crct10dif_pclmul vboxvideo crc32_pclmul drm_vram_helper ttm ghash_clmulni_intel drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops aesni_intel crypto_simd cryptd glue_helper ahci psmouse pata_acpi video libahci drm e1000 i2c_piix4
[   76.901967] ---[ end trace 6f242403edf302ec ]---
[   76.902006] RIP: 0010:proc_reg_release+0x3f/0x70
[   76.902035] Code: 4d 8d 6c 24 18 4c 89 ef e8 9e 61 78 00 49 8b 44 24 08 48 8d 70 f8 4c 39 e6 75 0f eb 23 48 8b 76 08 48 83 ee 08 4c 39 e6 74 16 <48> 39 1e 75 ee 4c 89 e7 e8 a4 fe ff ff 31 c0 5b 41 5c 41 5d 5d c3
[   76.902126] RSP: 0018:ffffa7f78053fe38 EFLAGS: 00010207
[   76.902157] RAX: 7074756f2f636f72 RBX: ffff8ac6f57adf00 RCX: 0000000000000001
[   76.902194] RDX: 0000000000000001 RSI: 7074756f2f636f6a RDI: ffff8ac6f25233d8
[   76.902232] RBP: ffffa7f78053fe50 R08: 0000000000000000 R09: 0000000000000000
[   76.903913] R10: 0000000000000010 R11: ffff8ac6f9044d90 R12: ffff8ac6f25233c0
[   76.905237] R13: ffff8ac6f25233d8 R14: ffff8ac6fcd702a0 R15: ffff8ac6f911d6c0
[   76.906543] FS:  00007ff192d4e580(0000) GS:ffff8ac6fda00000(0000) knlGS:0000000000000000
[   76.908201] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   76.909520] CR2: 00007ff1925c9000 CR3: 0000000070f22005 CR4: 00000000000606f0

compile [3.9_hiding_logged_in_users] failed

qgb@ubuntu:~/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users$ make
make -C /lib/modules/4.4.0-142-generic/build M=/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged
_in_users modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-142-generic'
  CC [M]  /home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.o
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:170:62: error: type default
s to ‘int’ in declaration of ‘buf’ [-Werror=implicit-int]
 static asmlinkage long (*orig_pread64)(int fd, const __user *buf, size_t count, loff_t pos);
                                                              ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c: In function ‘hook_openat’:
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:189:28: error: ‘regs’ undec
lared (first use in this function)
         return orig_openat(regs);
                            ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:189:28: note: each undeclar
ed identifier is reported only once for each function it appears in
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:189:16: error: too few argu
ments to function ‘orig_openat’
         return orig_openat(regs);
                ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:196:16: error: too few argu
ments to function ‘orig_openat’
         return orig_openat(regs);
                ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:206:21: error: too few argu
ments to function ‘orig_openat’
         tamper_fd = orig_openat(regs);
                     ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:215:12: error: too few argu
ments to function ‘orig_openat’
     return orig_openat(regs);
            ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c: At top level:
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:226:58: error: type default
s to ‘int’ in declaration of ‘buf’ [-Werror=implicit-int]
 static asmlinkage int hook_pread64(int fd, const __user *buf, size_t count, loff_t pos)
                                                          ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c: In function ‘hook_pread64’
:
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:244:33: error: ‘regs’ undec
lared (first use in this function)
             return orig_pread64(regs);
                                 ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:244:20: error: too few argu
ments to function ‘orig_pread64’
             return orig_pread64(regs);
                    ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:249:15: error: too few argu
ments to function ‘orig_pread64’
         ret = orig_pread64(regs);
               ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:275:34: warning: passing ar
gument 1 of ‘copy_to_user’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
             error = copy_to_user(buf, kbuf, count);
                                  ^
In file included from include/linux/poll.h:11:0,
                 from include/linux/ring_buffer.h:7,
                 from include/linux/trace_events.h:5,
                 from include/trace/syscall.h:6,
                 from include/linux/syscalls.h:81,
                 from /home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:4:
./arch/x86/include/asm/uaccess.h:764:1: note: expected ‘void *’ but argument is of type ‘const int *’
 copy_to_user(void __user *to, const void *from, unsigned long n)
 ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:292:12: error: too few argu
ments to function ‘orig_pread64’
     return orig_pread64(regs);
            ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:293:1: warning: control rea
ches end of non-void function [-Wreturn-type]
 }
 ^
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c: In function ‘hook_openat’:
/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.c:216:1: warning: control rea
ches end of non-void function [-Wreturn-type]
 }
 ^
cc1: some warnings being treated as errors
scripts/Makefile.build:291: recipe for target '/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged
_in_users/rootkit.o' failed
make[2]: *** [/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users/rootkit.o] Error 1
Makefile:1454: recipe for target '_module_/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_u
sers' failed
make[1]: *** [_module_/home/qgb/github/linux_kernel_hacking/3_RootkitTechniques/3.9_hiding_logged_in_users] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-142-generic'
Makefile:4: recipe for target 'all' failed
make: *** [all] Error 2

How do you bring all the modules together?

I want to integrate all the functions in one file, but, I meet lots of bug,
For example,
static struct ftrace_hook hooks[] = {
HOOK("sys_getdents64", hook_getdents64, &orig_getdents64),
HOOK("sys_getdents", hook_getdents, &orig_getdents),
HOOK("tcp4_seq_show", hook_tcp4_seq_show, &orig_tcp4_seq_show),
};

this will lead to
printk(KERN_DEBUG "rootkit: unresolved symbol: %s\n", hook->name);

I don't know why , can you help me ??? thank you !!!!

qeustion about rootkit?

First of all thank you so much because of Rootkit article.
Regarding the tutorial you made, do you have a video explaining it step by step?
And can you please introduce me a good educational video?
Thank you for your kindness!

Hi, I am having problems with getdents...

I have been enjoying reading your articles on https://xcellerator.github.io/posts/linux_rootkits_06/ , thank you for them :)

I am having problems with getdents... even when i copy the code excatly as you have done. I have the syscalls hooked fine and so on but the compare doesnt work with the PREFIX. I printed out the d_name to see what it was seeing and i get this....


[42483.162289] rootkit init...
[42483.169124] orig_getdents64 table entry successfully stored
[42483.169124] orig_kill table entry successfully stored
[42483.169129] unprotected memory
[42483.169129] hack_getdents64 successfully overwritten to table entry
[42483.169130] hack_kill successfully overwritten to table entry
[42483.169132] protected memory
[42495.120329] ***** hacked kill syscall *****
[42499.988370] ***** hacked kill syscall *****
[42500.028880] ***** hacked kill syscall *****
[42510.162327] ***** hacked kill syscall *****
[42510.164126] rootkit: d_name .
[42510.164128] rootkit: d_name ..
[42510.164129] rootkit: d_name 0
[42510.164130] rootkit: d_name 1
[42510.164130] rootkit: d_name 2
[42510.164131] rootkit: d_name 3
[42510.164132] rootkit: d_name 4
[42510.164133] rootkit: d_name 5
[42510.164134] rootkit: d_name 6
[42510.164134] rootkit: d_name 8
[42510.164135] rootkit: d_name 10
[42510.164136] ***** hacked getdents64 syscall *****
[42510.167389] rootkit: d_name .
[42510.167390] rootkit: d_name ..
[42510.167391] rootkit: d_name 0
[42510.167391] rootkit: d_name 1
[42510.167391] rootkit: d_name 2
[42510.167392] rootkit: d_name 3
[42510.167392] rootkit: d_name 4
[42510.167393] rootkit: d_name 5
[42510.167393] rootkit: d_name 6
[42510.167394] rootkit: d_name 8
[42510.167394] rootkit: d_name 10
[42510.167395] ***** hacked getdents64 syscall *****

Do you know what is happening?

ubuntu 20.04 kernel 5.11

Hi
emmm,i try it on kernel<5.11.0-27-generic>.Threr two problems in ftrace_helper.h:
/home/test/kernel/ftrace_helper.h:121:20: error: assignment to ‘ftrace_func_t’ {aka ‘void (*)(long unsigned int, long unsigned int, struct ftrace_ops *, struct ftrace_regs )’} from incompatible pointer type ‘void ()(long unsigned int, long unsigned int, struct ftrace_ops *, struct pt_regs *)’ [-Werror=incompatible-pointer-types]
121 | hook->ops.func = fh_ftrace_thunk;
| ^

void (*)(long unsigned int, long unsigned int, struct ftrace_ops *, struct ftrace_regs )’} from incompatible pointer type ‘
void (
)(long unsigned int, long unsigned int, struct ftrace_ops *, struct pt_regs *)’

could you give me some idea about the second problem.Thanks very much!

kallsyms_lookup_name is not exported anymore in kernels > 5.7

Issue

In newer kernel versions (> 5.7.0) the function kallsyms_lookup_name, used in your ftrace_helper.h library, is not exported anymore by default. This means that compiling the code provided by you (also found here) on newer kernels will fail throwing: ERROR: modpost: "kallsyms_lookup_name" undefined!

More references:

https://lkml.org/lkml/2020/2/25/576
https://lwn.net/Articles/813350/

Solution

I've done some research online and found this workaround, which compiles and works on Manjaro with kernel 5.9.16; so I have decided to link this awesome solution to your library.

patch.c - here's the solution wrote by @zizzu0 and modified by me

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>

// added by me
#include "inc/patch.h"

#define KPROBE_PRE_HANDLER(fname) static int __kprobes fname(struct kprobe *p, struct pt_regs *regs)

long unsigned int kln_addr = 0;
unsigned long (*kln_pointer)(const char* name) = NULL;

static struct kprobe kp0, kp1;

KPROBE_PRE_HANDLER(handler_pre0) {
    kln_addr = (--regs->ip);

    return 0;
}

KPROBE_PRE_HANDLER(handler_pre1) {
    return 0;
}

static int do_register_kprobe(struct kprobe* kp, char* symbol_name, void* handler) {
    int ret;

    kp->symbol_name = symbol_name;
    kp->pre_handler = handler;

    ret = register_kprobe(kp);
    if (ret < 0) {
        pr_err("do_register_kprobe: failed to register for symbol %s, returning %d\n", symbol_name, ret);
        return ret;
    }

    pr_info("Planted krpobe for symbol %s at %p\n", symbol_name, kp->addr);

    return ret;
}

// this is the function that I have modified, as the name suggests it returns a pointer to the extracted kallsyms_lookup_name function
kln_p get_kln_p(void) {
    int status;

    status = do_register_kprobe(&kp0, "kallsyms_lookup_name", handler_pre0);

    if (status < 0) return NULL;

    status = do_register_kprobe(&kp1, "kallsyms_lookup_name", handler_pre1);

    if (status < 0) {
        // cleaning initial krpobe
        unregister_kprobe(&kp0);
        return NULL;
    }

    unregister_kprobe(&kp0);
    unregister_kprobe(&kp1);

    pr_info("kallsyms_lookup_name address = 0x%lx\n", kln_addr);

    kln_pointer = (unsigned long (*)(const char* name)) kln_addr;

    return kln_pointer;
}

usable by including patch.h

#ifndef PATCH_H
#define PATCH_H

typedef unsigned long (*kln_p)(const char*);
kln_p get_kln_p(void);

#endif

And finally, the patched function in the lib ftracer_hekper.h

#include "patch.h"

static int fh_resolve_hook_address(struct ftrace_hook* hook) {
    // new method
    kln_p kln = get_kln_p();
    if (kln == NULL) return -1;

    hook->address = kln(hook->name);

    if (!hook->address) {
        printk(KERN_DEBUG "rootkit: unresolved symbol: %s\n", hook->name);
        return -ENOENT;
    }

#if USE_FENTRY_OFFSET
    * ((unsigned long*)hook->original) = hook->address + MCOUNT_INSN_SIZE;
#else
    * ((unsigned long*)hook->original) = hook->address;
#endif

    return 0;
}

Conclusion

The described methods works also on older kernels, like in the 5.4.0-58 used in the Vagrant instance provided by your blog. It works by extracting the dynamic address from the kernel.
I haven't opened a pull request because I couldn't find the ftracer_helper lib here (I have only found it as a gist) and especially because I am a begginner in kernel land, my code could have been written and integrated better. It was a cool exercise for a beginner like me, hope you will find it useful!

Sorry for my English, I ain't a native speaker :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.