You are not logged in.
Pages: 1
[Cross posted at rohitab.com.]
Basically from what I understand. Kernels afer 2.4 have stopped exporting sys_call_table to the global namespace as doing so makes it harder to hook sys_calls. This is a problem for me as I have decided to start on a project where hooking syscalls is pretty important. Work arounds for this have already been documented, like http://mail.nl.linux.org/kernelnewbies/ … 00266.html and http://www.phrack.org/issues.html?issue=58&id=7#article.
I however have tried something different. Basically, the system.map file mirrors the /proc/kallsyms file which has all the symbols in the kernel namespace. The difference is that the system.map file seems to contain the symbols that have been left out of /proc/kallsyms (like sys_call_table). So basically, I have just read the value associated with sys_call_table out of the system.map file and then used it to set a pointer to the sys_call_table.
Thought some people might be interested in it or have opinions on it.
This file gets and returns the address associated with sys_call_table.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
long read_system_map(char * path, char ** buffer);
void * get_sct_addr(char * buffer, long file_size);
int main(int argc, char ** argv)
{
char * map_file;
void * addr;
long file_bytes;
if (argc == 2) {
if (file_bytes = read_system_map(argv[1], &map_file)) {
if (addr = get_sct_addr(map_file, file_bytes)) {
printf("%X\n", (long)addr);
return 0;
}
}
}
return 1;
}
long read_system_map(char * path, char ** buffer)
{
FILE * fp;
long size = 0;
if (fp = fopen(path, "r")) {
if (!fseek(fp, 0, SEEK_END)) {
if ((size = ftell(fp)) != -1L) {
rewind(fp);
if (*buffer = malloc(sizeof(char) * size + 1)) {
if (fread(*buffer, 1, size, fp) == size) {
fclose(fp);
(*buffer)[size] = 0;
return size;
}
free (*buffer);
}
}
}
fclose(fp);
}
return 0;
}
void * get_sct_addr(char * buffer, long file_size)
{
char addr[15];
unsigned long number;
char * loc = strstr(buffer, "sys_call_table");
while (loc[0] != '\n') loc--;
loc++;
sscanf(loc, "%s", addr);
return (void*)strtoul(addr, NULL, 16);
}
This one sets up the pointer (keep in mind this is a module).
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("meth0dz");
MODULE_DESCRIPTION("Exports a pointer to sys_call_table to the kernel namespace.");
static long sct = 0;
void *** ptr_sct;
EXPORT_SYMBOL(ptr_sct);
module_param(sct, long, 0);
int init_module(void)
{
ptr_sct = (void***)sct;
return 0;
}
void cleanup_module(void)
{
return;
}
Example useage.
[meth0dz@myhost export-sys-call-table]$ ./get_addr /boot/System.map26
C130B2F0
[meth0dz@myhost export-sys-call-table]$ sudo insmod export_table.ko sct=0xC130B2F0
[meth0dz@myhost export-sys-call-table]$ cat /proc/kallsyms | grep ptr_sct
...
f815053c B ptr_sct [export_table]
[meth0dz@myhost export-sys-call-table]$
It seems to be working properly, but I could be completely off.
Last edited by meth0dz (2009-10-19 02:50:54)
Offline
i've recently taken up some interest in hooking syscalls as system call development is a part of one of my courses in school.
have you actually managed to do something with this? i might be reading this all wrong, but aren't you just exporting the address? i thought the problem was that the sys_call_table was read-only?
Offline
Pages: 1