陳鐵 + 原創作品轉載請註明出處 + 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000
作業的難度在增加,實驗樓的虛擬機不太穩定,經常用着用着就不能操作了。沒有細緻研究,於是就在VirtualBox下新建了虛擬機,還算順利。下載了Ubuntu的mini.iso,結果界面全是Debian的,選擇高級裏的Xfce,雖然全部下載使安裝過程有點長,不過安裝完之後沒有太多的問題,就達到了實驗樓同樣的效果。於是下載了最新的kernel,git clone了老師的最小linux的menuos。加上自己的系統程序。環境就打好了。
有圖有真相。
系統運行起來了:
重新啓動GDB,設置斷點sys_getuid.
(gdb) break sys_getuid
Breakpoint 1 at 0xc1054340: file kernel/sys.c, line 857.
代碼如下:
SYSCALL_DEFINE0(getuid)
{
/* Only we change this so SMP safe */
return from_kuid_munged(current_user_ns(), current_uid());
}
執行GDB命令finish,結果如下:
Run till exit from #0 sys_getuid () at kernel/sys.c:859
<signal handler called>
Value returned is $1 = 0
返回當前用戶的ID存在變量中是0;
顯示一下代碼
(gdb) list
424 sysenter_do_call:
425 cmpl $(NR_syscalls), %eax
426 jae sysenter_badsys
427 call *sys_call_table(,%eax,4)
428 sysenter_after_call:
429 movl %eax,PT_EAX(%esp)
430 LOCKDEP_SYS_EXIT
431 DISABLE_INTERRUPTS(CLBR_ANY)
432 TRACE_IRQS_OFF
433 movl TI_flags(%ebp), %ecx
由於getuid命令直接調用的sys_getuid系統調用例程,所以可以直接中斷到相應的函數,但是getuid-asm直接使用的中斷int 0x80.所以可以使用break sysenter_do_call。
總結,通過自己利用老師的代碼,套用一下,就可以在最小的linux系統下編寫底層的命令,雖然無法完全分析明白運行的機制,但是粗略的可以懂得系統調用的大致過程,內核將經常使用的和硬件交互的代碼封裝爲服務例程,並且對用戶提供系統調用表,只要知道相應的編號對應什麼樣的系統功能,就可以通過傳入編號給eax寄存器,使用系統調用的中斷號int0x80就可以的到想要的結果。進一步,甚至可以將自己的特定代碼保存爲內核例程,編譯在內核中,隨時供用戶調用。