亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 65935 | 回復: 102
打印 上一主題 下一主題

Linux下實現(xiàn)劫持系統(tǒng)調用的總結 [復制鏈接]

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-12-02 13:20 |只看該作者 |倒序瀏覽
原文鏈接:http://blog.chinaunix.net/u/33048/showart_2109264.html


目錄
一、代碼及實現(xiàn)
(一) 劫持open系統(tǒng)調用的代碼
(二) 編譯及實踐
二、實現(xiàn)原理分析
(一)中斷向量表地址的獲取
(二)系統(tǒng)調用中斷向量地址的獲取
(三)系統(tǒng)調用處理例程地址的獲取
(四)系統(tǒng)調用表地址的獲取
(五)系統(tǒng)調用的替換
參考鏈接



Linux內核版本2.6中已經(jīng)不再導出系統(tǒng)調用符號表了。因此,如果想實現(xiàn)劫持系統(tǒng)調用,就得想辦法找到系統(tǒng)調用表的地址。網(wǎng)上應該可以搜到相關的實現(xiàn)。我這里找到了albcamus兄的精華文章,并在內核版本2.6.18.3上實踐了其中的代碼。這里總結一下。

本文歡迎自由轉載,但請標明出處和本文鏈接,并保持本文的完整性。
CU: Godbach
Blog:http://blog.chinaunix.net/u/33048/index.html
Dec 2, 2009


一、代碼及實現(xiàn)
(一) 劫持open系統(tǒng)調用的代碼
內核態(tài)實現(xiàn)劫持系統(tǒng)調用的代碼如下,來自參考鏈接1,即albcamus兄提供的代碼。我這里屏蔽了一些代碼,僅實現(xiàn)了劫持open系統(tǒng)調用。
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/kprobes.h>
  5. #include <linux/kallsyms.h>
  6. #include <linux/sched.h>
  7. #include <linux/ptrace.h>
  8. #include <linux/mm.h>
  9. #include <linux/smp.h>
  10. #include <linux/user.h>
  11. #include <linux/errno.h>
  12. #include <linux/cpu.h>
  13. #include <asm/uaccess.h>
  14. #include <asm/fcntl.h>
  15. #include <asm/unistd.h>

  16. MODULE_DESCRIPTION("Intercept the system call table in Linux");
  17. MODULE_AUTHOR("alert7 ([email]alert7@xfocus.org[/email]) \n\t\talbcamus <[email]albcamus@gmail.com[/email]>");
  18. MODULE_LICENSE("GPL");


  19. /* comment the following line to shut me up */
  20. #define INTERCEPT_DEBUG

  21. #ifdef INTERCEPT_DEBUG
  22.     #define dbgprint(format,args...) \
  23.         printk("intercept: function:%s-L%d: "format, __FUNCTION__, __LINE__, ##args);
  24. #else
  25.     #define dbgprint(format,args...)  do {} while(0);
  26. #endif


  27. /**
  28. * the system call table
  29. */
  30. void **my_table;

  31. unsigned int orig_cr0;

  32. /**
  33. * the original syscall functions
  34. */
  35. asmlinkage long (*old_open) (char __user *filename, int flags, int mode);
  36. asmlinkage int  (*old_execve) (struct pt_regs regs);



  37. /** do_execve and do_fork */
  38. unsigned int can_exec_fork = 0;
  39. int    (*new_do_execve) (char * filename,
  40.             char __user *__user *argv,
  41.             char __user *__user *envp,
  42.             struct pt_regs * regs);


  43. struct idtr {
  44.     unsigned short limit;
  45.     unsigned int base;
  46. } __attribute__ ((packed));


  47. struct idt {
  48.     unsigned short off1;
  49.     unsigned short sel;
  50.     unsigned char none, flags;
  51.     unsigned short off2;
  52. } __attribute__ ((packed));


  53. #if 0
  54. /**
  55. *  check if we can intercept fork/vfork/clone/execve or not
  56. *
  57. *  return : 0 for no, 1 for yes
  58. */
  59. struct kprobe kp_exec;
  60. unsigned int can_intercept_fork_exec(void)
  61. {
  62.     int ret = 0;

  63. #ifndef CONFIG_KPROBES
  64.     return ret;
  65. #endif

  66.     kp_exec.symbol_name = "do_execve";

  67.     ret = register_kprobe(&kp_exec);
  68.     if (ret != 0 ) {
  69.         dbgprint("cannot find do_execve by kprobe.\n");
  70.         return 0;
  71.     }
  72.     new_do_execve = ( int (*)
  73.              (char *,
  74.               char __user * __user *,
  75.               char __user * __user *,
  76.               struct pt_regs *
  77.              )
  78.             ) kp_exec.addr;

  79.     dbgprint("do_execve at %p\n", (void *)kp_exec.addr);
  80.     unregister_kprobe(&kp_exec);


  81.     return 1;
  82. }

  83. #endif

  84. /**
  85. * clear WP bit of CR0, and return the original value
  86. */
  87. unsigned int clear_and_return_cr0(void)
  88. {
  89.     unsigned int cr0 = 0;
  90.     unsigned int ret;

  91.     asm volatile ("movl %%cr0, %%eax"
  92.               : "=a"(cr0)
  93.               );
  94.     ret = cr0;

  95.     /* clear the 16 bit of CR0, a.k.a WP bit */
  96.     cr0 &= 0xfffeffff;

  97.     asm volatile ("movl %%eax, %%cr0"
  98.               :
  99.               : "a"(cr0)
  100.               );
  101.     return ret;
  102. }

  103. /** set CR0 with new value
  104. *
  105. * @val : new value to set in cr0
  106. */
  107. void setback_cr0(unsigned int val)
  108. {
  109.     asm volatile ("movl %%eax, %%cr0"
  110.               :
  111.               : "a"(val)
  112.               );
  113. }


  114. /**
  115. * Return the first appearence of NEEDLE in HAYSTACK.  
  116. * */
  117. static void *memmem(const void *haystack, size_t haystack_len,
  118.             const void *needle, size_t needle_len)
  119. {/*{{{*/
  120.     const char *begin;
  121.     const char *const last_possible
  122.         = (const char *) haystack + haystack_len - needle_len;

  123.     if (needle_len == 0)
  124.         /* The first occurrence of the empty string is deemed to occur at
  125.            the beginning of the string.  */
  126.         return (void *) haystack;

  127.     /* Sanity check, otherwise the loop might search through the whole
  128.        memory.  */
  129.     if (__builtin_expect(haystack_len < needle_len, 0))
  130.         return NULL;

  131.     for (begin = (const char *) haystack; begin <= last_possible;
  132.          ++begin)
  133.         if (begin[0] == ((const char *) needle)[0]
  134.             && !memcmp((const void *) &begin[1],
  135.                    (const void *) ((const char *) needle + 1),
  136.                    needle_len - 1))
  137.             return (void *) begin;

  138.     return NULL;
  139. }/*}}}*/


  140. /**
  141. * Find the location of sys_call_table
  142. */
  143. static unsigned long get_sys_call_table(void)
  144. {/*{{{*/
  145. /* we'll read first 100 bytes of int $0x80 */
  146. #define OFFSET_SYSCALL 100        

  147.     struct idtr idtr;
  148.     struct idt idt;
  149.     unsigned sys_call_off;
  150.     unsigned retval;
  151.     char sc_asm[OFFSET_SYSCALL], *p;

  152.     /* well, let's read IDTR */
  153.     asm("sidt %0":"=m"(idtr)
  154.              :
  155.              :"memory" );

  156.     dbgprint("idtr base at 0x%X, limit at 0x%X\n", (unsigned int)idtr.base,(unsigned short)idtr.limit);

  157.     /* Read in IDT for vector 0x80 (syscall) */
  158.     memcpy(&idt, (char *) idtr.base + 8 * 0x80, sizeof(idt));

  159.     sys_call_off = (idt.off2 << 16) | idt.off1;

  160.     dbgprint("idt80: flags=%X sel=%X off=%X\n",
  161.                  (unsigned) idt.flags, (unsigned) idt.sel, sys_call_off);

  162.     /* we have syscall routine address now, look for syscall table
  163.        dispatch (indirect call) */
  164.     memcpy(sc_asm, (void *)sys_call_off, OFFSET_SYSCALL);

  165.     /**
  166.      * Search opcode of `call sys_call_table(,eax,4)'
  167.      */
  168.     p = (char *) memmem(sc_asm, OFFSET_SYSCALL, "\xff\x14\x85", 3);
  169.     if (p == NULL)
  170.         return 0;

  171.     retval = *(unsigned *) (p + 3);
  172.     if (p) {
  173.         dbgprint("sys_call_table at 0x%x, call dispatch at 0x%x\n",
  174.              retval, (unsigned int) p);
  175.     }
  176.     return retval;
  177. #undef OFFSET_SYSCALL
  178. }/*}}}*/



  179. /**
  180. * new_open - replace the original sys_open when initilazing,
  181. *           as well as be got rid of when removed
  182. */
  183. asmlinkage long new_open(char *filename, int flags, int mode)
  184. {
  185.     dbgprint("call open()\n");
  186.     return old_open (filename, flags, mode);
  187. }


  188. /**
  189. * new_execve - you should change this function whenever the kernel's sys_execve()
  190. * changes
  191. */
  192. asmlinkage int new_execve(struct pt_regs regs)
  193. {
  194.     int error;
  195.     char *filename;

  196.     dbgprint("Hello\n");

  197.     filename = getname( (char __user *) regs.ebx );
  198.     error = PTR_ERR(filename);
  199.     if ( IS_ERR(filename) )
  200.         goto out;
  201.     dbgprint("file to execve: %s\n", filename);
  202.     error = new_do_execve(filename,
  203.                   (char __user * __user *) regs.ecx,
  204.                   (char __user * __user *) regs.edx,
  205.                   &regs);
  206.     if (error == 0) {
  207.         task_lock(current);
  208.         current->ptrace &= ~PT_DTRACE;
  209.         task_unlock(current);
  210.         set_thread_flag(TIF_IRET);
  211.     }
  212.     putname (filename);
  213. out:
  214.     return error;
  215. }

  216. static int intercept_init(void)
  217. {
  218.     my_table = (void **)get_sys_call_table();
  219.     if (my_table == NULL)
  220.         return -1;

  221.     dbgprint("sys call table address %p\n", (void *) my_table);

  222. #define REPLACE(x) old_##x = my_table[__NR_##x];\
  223.     my_table[__NR_##x] = new_##x

  224.    
  225.     REPLACE(open);
  226. #if 0
  227.     can_exec_fork = can_intercept_fork_exec();
  228.     if(can_exec_fork == 1)
  229.         REPLACE(execve);
  230. #endif

  231. #undef REPLACE
  232.     return 0;
  233. }





  234. static int __init this_init(void)
  235. {
  236.     int ret;
  237.     printk("syscall intercept: Hi, poor linux!\n");

  238.     orig_cr0 = clear_and_return_cr0();   
  239.     ret = intercept_init();
  240.     setback_cr0(orig_cr0);

  241.     return ret;
  242. }

  243. static void __exit this_fini(void)
  244. {
  245.     printk("syscall intercept: bye, poor linux!\n");

  246. #define RESTORE(x) my_table[__NR_##x] = old_##x

  247.     orig_cr0 = clear_and_return_cr0();   
  248.     RESTORE(open);
  249. #if 0
  250.     if(can_exec_fork == 1)
  251.         RESTORE(execve);
  252. #endif
  253.     setback_cr0(orig_cr0);

  254. #undef RESTORE
  255. }

  256. module_init(this_init);
  257. module_exit(this_fini);
復制代碼

(二) 編譯及實踐

Makefile如下:
obj-m   :=hack_open.o
EXTRA_CFLAGS := -Dsymname=sys_call_table
KDIR   := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)
default:
    make -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
    rm -rf .*.cmd *.mod.c *.o *.ko .tmp* *.symvers

編譯之后,加載模塊,然后查看日志信息:
Sep 24 19:06:49 localhost kernel: intercept: function:get_sys_call_table-L220: sys_call_table at 0xc11f14e0, call dispatch at 0xcebeceaa
Sep 24 19:06:49 localhost kernel: intercept: function:intercept_init-L276: sys call table address c11f14e0
Sep 24 19:06:50 localhost kernel: intercept: function:new_open-L234: hello
Sep 24 19:07:00 localhost last message repeated 460 times

可見open系統(tǒng)調用執(zhí)行次數(shù)之頻繁。

[ 本帖最后由 Godbach 于 2010-1-19 11:24 編輯 ]

評分

參與人數(shù) 3可用積分 +75 收起 理由
amarant + 15 精品文章
fender0107401 + 30 精品文章
scutan + 30 精品文章

查看全部評分

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
2 [報告]
發(fā)表于 2009-12-02 13:22 |只看該作者
二、實現(xiàn)原理分析
        實現(xiàn)的方法就是通過中斷向量表,找到系統(tǒng)調用的中斷向量,再通過系統(tǒng)調用時執(zhí)行的指令,最終找到系統(tǒng)調用表的地址, 進行系統(tǒng)調用的替換。。

(一)中斷向量表地址的獲取
        中斷向量表(IDT)的入口地址是通過IDTR寄存器來確定的。IDTR寄存器的內容如下圖所示。

這就是上面代碼中定義結構體
  1. struct idtr {
  2.     unsigned short limit;
  3.     unsigned int base;
  4. } __attribute__ ((packed))
復制代碼
的原因。
idtr寄存器的內容可以通過匯編指令sidt取出,然后就可以IDT的入口地址idtr.base,即高32bit。

(二)系統(tǒng)調用中斷向量地址的獲取
下一步就通過IDT找到系統(tǒng)調用中斷即(0x80)的地址。下圖即一個中斷向量的組成。由此可以見,一個中斷向量占用8個字節(jié)。因此,系統(tǒng)調用中斷的地址可以表示為:
idt  = idtr.base + 8 * 0x80



(三)系統(tǒng)調用處理例程地址的獲取
獲取到系統(tǒng)調用中斷的地址后,同樣需要一個數(shù)據(jù)結構,將中斷向量描述符的相關內容保存。數(shù)據(jù)結構的定義如下:
  1. struct idt {
  2.     unsigned short off1;
  3.     unsigned short sel;
  4.     unsigned char none, flags;
  5.     unsigned short off2;
  6. } __attribute__ ((packed));
復制代碼
通過以上數(shù)據(jù)結構就可以得到系統(tǒng)調用中斷發(fā)生時的中斷處理例程的地址,即函數(shù)system_call()函數(shù)的地址:
  1. sys_call_off = idt.off2 << 16 | idt.off1
復制代碼
該函數(shù)是用匯編實現(xiàn)的,位于arch/i386/kernel/entry.S,下面截取該函數(shù)的部分實現(xiàn):
    # system call handler stub
ENTRY(system_call)
    RING0_INT_FRAME         # can't unwind into user space anyway
    pushl %eax          # save orig_eax
    CFI_ADJUST_CFA_OFFSET 4
    SAVE_ALL
    GET_THREAD_INFO(%ebp)
    testl $TF_MASK,EFLAGS(%esp)
    jz no_singlestep
    orl $_TIF_SINGLESTEP,TI_flags(%ebp)
no_singlestep:
                    # system call tracing in operation / emulation
    /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
    testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
    jnz syscall_trace_entry
    cmpl $(nr_syscalls), %eax
    jae syscall_badsys
syscall_call:
    call *sys_call_table(,%eax,4)
movl %eax,EAX(%esp)     # store the return value

(四)系統(tǒng)調用表地址的獲取

從上面代碼中,我們可以看到,系統(tǒng)調用表的入口地址就是上面倒數(shù)第二行中sys_call_table。那么如果獲取到sys_call_table的地址呢。由于這行代碼執(zhí)行了函數(shù)調用的指令call,該指令對應的指令碼為\xff\x14\x85。因此,我們只要在system_call函數(shù)體內搜索的前三個字節(jié)為\xff\x14\x85的內存地址,然后將該地址加3,即可獲取到sys_call_table的地址。同時,還有一個問題需要確定,就是call *sys_call_table(,%eax,4)這條指令相對于system_call函數(shù)體的偏移是多少,這樣我們可以確定內存搜索的范圍。下面是entry.o函數(shù)反匯編的部分代碼:
000000d0 <system_call>:
  d0:   50                      push   %eax
  d1:   fc                      cld   
  d2:   06                      push   %es  
  d3:   1e                      push   %ds  
  d4:   50                      push   %eax
  d5:   55                      push   %ebp
  d6:   57                      push   %edi
  d7:   56                      push   %esi
  d8:   52                      push   %edx
  d9:   51                      push   %ecx
  da:   53                      push   %ebx
  db:   ba 7b 00 00 00          mov    $0x7b,%edx
  e0:   8e da                   movl   %edx,%ds
  e2:   8e c2                   movl   %edx,%es
  e4:   bd 00 f0 ff ff          mov    $0xfffff000,%ebp
  e9:   21 e5                   and    %esp,%ebp
  eb:   f7 44 24 30 00 01 00    testl  $0x100,0x30(%esp)
  f2:   00   
  f3:   74 04                   je     f9 <no_singlestep>
  f5:   83 4d 08 10             orl    $0x10,0x8(%ebp)

000000f9 <no_singlestep>:
  f9:   66 f7 45 08 c1 01       testw  $0x1c1,0x8(%ebp)
  ff:   0f 85 bf 00 00 00       jne    1c4 <syscall_trace_entry>
105:   3d 3e 01 00 00          cmp    $0x13e,%eax
10a:   0f 83 27 01 00 00       jae    237 <syscall_badsys>

00000110 <syscall_call>:
110:   ff 14 85 00 00 00 00    call   *0x0(,%eax,4)
117:   89 44 24 18             mov    %eax,0x18(%esp)
通過以上反匯編代碼的倒數(shù)第二行可以看到,該行即執(zhí)行call *sys_call_table(,%eax,4) 的代碼。那么該執(zhí)行相對于函數(shù)體的偏移為0x110-0xd0 = 0x40。我們實際的代碼中使用偏移值100作為搜索的最大范圍。
至于反匯編出來為什么只是call *0x0(,%eax,4),個人理解應該是該模塊尚未與其他模塊進行鏈接的原因。當生成內核鏡像vmlinux之后,反匯編vmlinux,然后找到system_call函數(shù),就可以看到指令call *0x0(,%eax,4)中0x0被替換為有效的地址。本人也已經(jīng)在2.6.18.3的vmlinux上驗證過了,實際的代碼如下:
  1. c1003d04 <syscall_call>:
  2. c1003d04:   ff 14 85 e0 14 1f c1    call   *0xc11f14e0(,%eax,4)
  3. c1003d0b:   89 44 24 18             mov    %eax,0x18(%esp)
復制代碼
因此可以看出,我當前系統(tǒng)的sys_call_table的地址為0xc11f14e0。

(五)系統(tǒng)調用的替換
一旦我們獲取到了系統(tǒng)調用表的地址,需要需要替換那些系統(tǒng)調用,只需要將系統(tǒng)調用表的某個系統(tǒng)調用指向自己實現(xiàn)的系統(tǒng)調用即可。
  1. #define REPLACE(x) old_##x = my_table[__NR_##x];\
  2.     my_table[__NR_##x] = new_##x
  3.     REPLACE(open);
復制代碼
另外,需要注意的是,在替換系統(tǒng)調用的時候,要先清CR0的第20位并記錄原始值,不然在替換sys_call_table的時候會報錯。在替換完畢之后,再將CR0的原始值恢復,代碼如下:
  1. orig_cr0 = clear_and_return_cr0();   
  2. setback_cr0(orig_cr0);
復制代碼
以上為Linux劫持系統(tǒng)調用的總結。歡迎多多交流,如果不妥之處,請大家指正。


參考鏈接:
1. http://linux.chinaunix.net/bbs/viewthread.php?tid=909712
3. http://linux.chinaunix.net/bbs/thread-1135859-1-2.html

[ 本帖最后由 Godbach 于 2009-12-2 13:43 編輯 ]

評分

參與人數(shù) 2可用積分 +45 收起 理由
amarant + 15 湊齊十分
dreamice + 30 原創(chuàng)內容

查看全部評分

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
3 [報告]
發(fā)表于 2009-12-02 13:27 |只看該作者

回復 #2 scutan 的帖子

scutan兄,你回復的真快啊。

論壇徽章:
0
4 [報告]
發(fā)表于 2009-12-02 13:31 |只看該作者

回復 #3 Godbach 的帖子

呵呵,為了不影響文章的連貫性,所以我將之前那個回貼刪了。
學習學習。

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
5 [報告]
發(fā)表于 2009-12-02 13:34 |只看該作者

回復 #4 scutan 的帖子

呵呵,我應該在1樓注上未完待續(xù):wink:

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
6 [報告]
發(fā)表于 2009-12-02 16:44 |只看該作者
1樓中添加了全文的目錄結構。
其實第一部分就是使用albcamus兄的代碼。
重點內容在于第二部分,分析了劫持系統(tǒng)調用的整個過程。

論壇徽章:
0
7 [報告]
發(fā)表于 2009-12-02 20:07 |只看該作者

回復 #1 Godbach 的帖子

代碼沒有改動吧?

學習了,分析的很好啊,贊一下!
很好,很強大

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
8 [報告]
發(fā)表于 2009-12-02 21:54 |只看該作者

回復 #7 GoldenSoldier 的帖子

代碼沒有改變。

我就是拿了ablcamus兄的代碼,只保留的open系統(tǒng)調用的劫持。

如果想看完成的代碼,可以打開參考連接1.

論壇徽章:
0
9 [報告]
發(fā)表于 2009-12-02 22:24 |只看該作者
好文,棒下場。godbach 繼續(xù)發(fā)表些有益的文章

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
10 [報告]
發(fā)表于 2009-12-02 22:25 |只看該作者

回復 #9 mik 的帖子

呵呵,慚愧。還請mik兄多多指教。這樣的文章在mik面前,有點班門弄斧了。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP