Ik ben even wat bezig met Linux kernel modules programming. In Linux 2.0, 2.2 en 2.4 maakte ik graag gebruik van syscall hooks, maar dat werkt in 2.6 niet meer.
Uit het archief graven wij op:
Ieder programma wat vervolgens uid 51 heeft, krijgt een foutieve tijd voorgeschoteld, namelijk 0 = 1 jan 1970 0:00. (Dit is overigens niet de actual patch die ik wil uitvoeren, maar het is zo een simpel voorbeeldje.)
De zelfde code voor de Linux 2.6 kernel zou zijn:
ware het niet dat Linux 2.6 de sys_call_table niet exporteert. Make (andere makefile) gaat prima, maar modprobe niet, omdat er unknown symbols zijn. Spreekt voor zich.
Ik heb nu de volgende oplossingen gevonden:
Uit het archief graven wij op:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| #define PATCHUID 51
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <asm/segment.h>
#include <asm/unistd.h>
#include <linux/dirent.h>
#include <sys/syscall.h>
#include <sys/sysmacros.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
MODULE_AUTHOR("uid0");
MODULE_LICENSE("GPL");
extern void* sys_call_table[];
time_t (*orig_time) (time_t *t);
time_t new_time (time_t *t);
time_t new_time(time_t *t)
time_t new_time(time_t *t)
{
if (current->uid==PATCHUID) {
return (time_t *)0;
}
return orig_time(t);
}
int init_module(void) {
printk("Applying time() patch for uid %d\n",PATCHUID);
orig_time=sys_call_table[SYS_time];
sys_call_table[SYS_time]=new_time;
return 0;
}
void cleanup_module(void) {
sys_call_table[SYS_time]=orig_time;
printk("Removed time() patch from uid %d\n",PATCHUID);
} |
Ieder programma wat vervolgens uid 51 heeft, krijgt een foutieve tijd voorgeschoteld, namelijk 0 = 1 jan 1970 0:00. (Dit is overigens niet de actual patch die ik wil uitvoeren, maar het is zo een simpel voorbeeldje.)
De zelfde code voor de Linux 2.6 kernel zou zijn:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| #define PATCHUID 51
#include <linux/config.h>
#include <linux/stddef.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/dirent.h>
#include <linux/sched.h>
#include <sys/syscall.h>
#include <asm/segment.h>
#include <asm/unistd.h>
#include <sys/sysmacros.h>
MODULE_AUTHOR("uid0");
MODULE_LICENSE("GPL");
extern void* sys_call_table[];
static time_t (*orig_time) (time_t *t);
time_t new_time (time_t *t);
time_t new_time(time_t *t)
{
if (current->uid==PATCHUID) {
return (time_t *)0;
}
return orig_time(t);
}
static int __init xinit_module(void) {
printk("Applying time() patch for uid %d\n",PATCHUID);
orig_time=sys_call_table[SYS_time];
sys_call_table[SYS_time]=new_time;
return 0;
}
static void __exit xcleanup_module(void) {
sys_call_table[SYS_time]=orig_time;
printk("Removed time() patch from uid %d\n",PATCHUID);
}
module_init(xinit_module);
module_exit(xcleanup_module); |
ware het niet dat Linux 2.6 de sys_call_table niet exporteert. Make (andere makefile) gaat prima, maar modprobe niet, omdat er unknown symbols zijn. Spreekt voor zich.
Ik heb nu de volgende oplossingen gevonden:
- patch de kernel, zodat deze weer wel sys_call_table exporteert. Heel simpel, maar breekt de compatibiliteit met ongepatchte distro's. Daarnaast is het niet voor niets verwijderd uit 2.6, deze methode van hooken kan namelijk race condities en andere smp problemen opleveren.
- kernel hacking, zie http://www.phrack.org/phrack/58/p58-0x08 . Leuk, maar eigenlijk heel ranzig.