posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          讀核筆記(3) - 系統(tǒng)調(diào)用

          Posted on 2008-02-18 14:35 ZelluX 閱讀(558) 評論(4)  編輯  收藏 所屬分類: LinuxSystem
          _syscall 宏:
          最簡單的沒有參數(shù)的系統(tǒng)調(diào)用的實現(xiàn):
          /*?XXX?-?_foo?needs?to?be?__foo,?while?__NR_bar?could?be?_NR_bar.?*/
          #define?_syscall0(type,name)?\
          type?name(
          void)?\
          {?\
          long?__res;?\
          __asm__?
          volatile?("int?$0x80"?\
          ????:?
          "=a"?(__res)?\
          ????:?
          "0"?(__NR_##name));?\
          __syscall_return(type,__res);?\
          }

          以getuid()為例,_syscall0(int, getuid)展開后就變成
          int?getuid(void)
          {
          ????
          long?__res;
          ????__asm__?
          volatile("int?$0x80"
          ????????????????????:
          "=a"?(__res)
          ????????????????????:
          "0"??(__NR_getuid));
          ????__syscall_return(
          int,?__res);
          }

          程序把系統(tǒng)調(diào)用號__NR_getuid放入eax寄存器,然后調(diào)用軟中斷。
          include/asm-i386/hw_irq.h中的定義:
          00025?? #define SYSCALL_VECTOR??0x80;

          arch/i386/kernel/traps.c中把該中斷號綁定到system_call函數(shù):
          00944?? set_system_gate(SYSCALL_VECTOR,&system_call);

          system_call函數(shù)在arch/i386/kernel/entry.S中:
          ENTRY(system_call)
          ????pushl?%eax????????????#?save?orig_eax
          ????SAVE_ALL
          ????GET_CURRENT(%ebx)
          ????testb?$0x02
          ,tsk_ptrace(%ebx)????#?PT_TRACESYS
          ????jne?tracesys
          ????cmpl?$(NR_syscalls)
          ,%eax
          ????jae?badsys
          ????call?*SYMBOL_NAME(sys_call_table)(
          ,%eax,4)
          ????movl?%eax
          ,EAX(%esp)????????#?save?the?return?value
          ENTRY(ret_from_sys_call)
          ????cli????????????????#?need_resched?and?signals?atomic?test
          ????cmpl?$
          0,need_resched(%ebx)
          ????jne?reschedule
          ????cmpl?$
          0,sigpending(%ebx)
          ????jne?signal_return
          restore_all:
          ????RESTORE_ALL
          主要步驟:
          1. 保留一份系統(tǒng)調(diào)用號的最初拷貝
          2. 保存堆棧環(huán)境(SAVE_ALL)
          3. 得到當(dāng)前task_struct的地址,保存到ebx中
          4. 檢查系統(tǒng)調(diào)用號
          5. 根據(jù)%eax調(diào)用號計算地址,調(diào)用相應(yīng)函數(shù)
          6. 在entry.S后面可以看到,
          .data
          ENTRY(sys_call_table)
          ????.long?SYMBOL_NAME(sys_ni_syscall)????/*?
          0??-??old?"setup()"?system?call*/
          ????????
          ????.long?SYMBOL_NAME(sys_getuid16)
          ????.long?SYMBOL_NAME(sys_stime)????????/*?
          25?*/
          ????.long?SYMBOL_NAME(sys_ptrace)
          ????????
          sys_call_table + %eax * 4是sys_getuid16地址,kernel/uid16.c中:
          asmlinkage?long?sys_getuid16(void)
          {
          ????
          return?high2lowuid(current->uid);
          }
          很簡單的處理代碼,返回當(dāng)前進(jìn)程的uid。這里asmlinkage修飾符表示函數(shù)必須從堆棧中,而不是從寄存器中拿參數(shù)(防止gcc用寄存器傳參優(yōu)化)。
          7. 保存返回值eax到堆棧中的eax
          8. RESTORE_ALL

          另外這里再提一下GET_CURRENT的實現(xiàn)
          #define?GET_CURRENT(reg)?\
          ????movl?$-
          8192,?reg;?\
          ????andl?%esp,?reg
          很巧妙的實現(xiàn),把棧指針與掩碼-8192做與操作,末尾13位清零,就是當(dāng)前的進(jìn)程的task_struct地址了。


          接下來是利用內(nèi)核模塊動態(tài)添加一個系統(tǒng)調(diào)用的例程,由于2.4.20以后sys_call_table符號不再被導(dǎo)出了,要獲得這個地址得手動hack。尚未成功,下次回過頭來看看。

          評論

          # re: 讀核筆記(3) - 系統(tǒng)調(diào)用  回復(fù)  更多評論   

          2008-02-18 16:07 by overboming
          版主,代碼高亮怎么做方便來著?

          # re: 讀核筆記(3) - 系統(tǒng)調(diào)用  回復(fù)  更多評論   

          2008-02-18 16:09 by ZelluX
          @overboming
          這個博客網(wǎng)站的編輯器有相關(guān)的功能

          # re: 讀核筆記(3) - 系統(tǒng)調(diào)用  回復(fù)  更多評論   

          2008-02-26 16:03 by luohandsome
          水木的kerneltech板5507講系統(tǒng)調(diào)用劫持的:
          LKM Rootkits on Linux x86 v2.6

          # re: 讀核筆記(3) - 系統(tǒng)調(diào)用  回復(fù)  更多評論   

          2008-02-26 16:18 by ZelluX
          @luohandsome
          恩,多謝啦~~
          主站蜘蛛池模板: 怀仁县| 襄城县| 青岛市| 杨浦区| 柳州市| 偃师市| 蓝山县| 合江县| 岐山县| 黄冈市| 佳木斯市| 漾濞| 苍山县| 石家庄市| 河间市| 师宗县| 岢岚县| 都昌县| 丰镇市| 栾川县| 韶山市| 科技| 绥棱县| 洛阳市| 渭南市| 固原市| 娄烦县| 大港区| 凤台县| 宜城市| 遵义县| 盐亭县| 益阳市| 竹山县| 池州市| 昆山市| 邢台县| 塔城市| 会同县| 海盐县| 隆尧县|