smbd of samba-3.0.23b internal

samba FreeBSD/ Linux 使用者廣為使用的 Netbios server,使 windows 得以存取/分享 FreeBSD/ Linux box 的檔案資料。 samba 提供包括 name service 、file access ......等服務,本文分析的 smbd 就是提供 file access 服務。

smbd

要 trace 一個程式,首先要了解這個程式到底是做什麼的,其功能為何。smbd 就如前面說的,提供 file access 的功能。samba 的兩個主要 daemon 是:

  • nmbd 提供 name service,
  • smbd file access、print ...... 等等的 service。
samba 提供的 server 端功能,幾乎都由 smbd 提供了,這也是為什麼本文針對 smbd 而不是 nmbd 進行分析。

工具

分析一個程式,可以使用最簡單的 joe、jed、vi 等 editor 來蠻幹。雖然這些都是 powerful 的工具,但卻無法直接提供有用的資訊。我們必需分心去組合這些工具所提供的服務,才能分析得到有用資訊。

以往我也是熱忠於使用簡單工具的人,相信這些工具的功能強大,能做到任何我想做事,事實上也是如此。然而,隨了工作越來越多,我發覺時間越來越不夠用時,我發覺好的工具能讓我在相同的一天 24 小時裡,有更多的產能。我不再需要花時間去進行一再重複的動作,只為了得到一些資訊。電腦的偉大之處,不就是幫我們進行日常一再重複的工作嗎?身為 hacker 和工程師,為何讚嘆徒手完成繁雜而重複工作的行為呢?外界認為為,軟體工程師是自動化的推手,但我認為是自動化層度最低的行業。是到了改善的時侯了。

分析軟體時,有幾個工具可用,如: ctags、cflow、doxygen 等。傳統上,我們使用 ctags,為 source code 產生 index。配合 tags 的使用,editor 可以幫我們快速找到 function 和 variable 的定義,而穿梭在程式碼之間。而 cflow 可以幫我們找分析出程式的流程,讓我們了解 function 的 static 行為、相依性和呼叫過程。配合 cflow2vcg,能以 tree 呈現程式流程。cflow 配合 cflow2vcg,能讓我們一目了然,快速的了解程式的架構。然而,巨細彌遺的內容,往往使我們失去了焦點。我建議配合 cflow2vcg 產生的圖,trace 程式碼,並刪減 cflow 產生的旁支末節,以得到一張大綱,作為以後進一步了解細節的 guide line。

doxygen 其實是一個產生文件的工具,幫助軟體工程師產生程式碼的文件。然而,doxygen 會為 source code 產生 HTML 檔,為每一個 function 和 variable 產生 hyperlink,並列出 refer 或被 refer 的位置。透過 doxygen 產生的 hyperlink,我可以使用 mouse,直覺的穿梭在程式碼之間。雖然我還是比較喜歡使用 keyboard,但是卻不是那麼直覺。分析程式碼本來就是一種腦力密集的工作,何以我還要分析去使用不夠直覺的工具?因而,使用 doxygen 產生的文件,似乎能更快完成工作。然而 doxygen 也非完美,無法自動記錄 trace 的過程。

進行分式

samba 已經有 Doxyfile,可直接拿來產生文件。透過 hyperlink,得以穿梭在 source code 之間,颯沓如流星

主要架構

smbd 的進入點是在 source/smbd/server.c 裡的 main(),其主要流程如下:

main() {smbd/server.c}
  open_sockets_smbd()
    or
      open_sockets_inetd()
        smbd_set_server_fd()
      loop
        accept new connection
        fork()
        child?
          smbd_set_server_fd()
          return
  smbd_process() {smbd/process.c}
    loop
      setup_select_timeout()
        blocking_locks_timeout() {smbd/blocking.c}
        set_change_notify_timeout() {smbd/notify.c}
      !timeout_processing()? /* process 一直沒有收到新的 conneciton */
        return; /* idle for a while */
      run_events() {lib/events.c}
      receive_message_or_smb() /* 根據 timeout 時間,select socket */
        message_dispatch() {lib/messages.c}
          ref var dispatch_fns
      process_smb()
        construct_reply()
          msg_type != 0?
            yes
              reply_special() {smbd/reply.c} /* 處理和 session 有關 */
            no
              construct_reply_common()
              switch_message() /* 依 smb_com 執行對應的 smb_messages */
        send_smb() {lib/util_sock.c}

main 的前半段是在進行 initialize,直到 open_sockets_smbd()。open_sockets_smbd() 接受 connection request,並 fork process。由於 smbd 有不同的執行方式,可當 stand-alone daemon,也可透過 inetd 執行,open_sockets_smbd() 依據情況,採取不同的處理方式。例如:透過 inetd 執行的情況,就直接使用 inetd pass 過來的 socket,而非 accept 新的 socket。

smbd_process() 主要的工作,就是接收來自 socket 的 SMB message,依據分類,呼叫對應的 function 進行 service。smbd_process() 的主要動作為:

  1. 呼叫 receive_message_or_smb() 以接收來自網路的 SMB message
  2. 執行 process_smb() 以處理 SMB message 所撘載的 request
針對每一種 smb command, samba 都在 smb_messages 這個 array 有對應的 function 可以處理。若想分析某一 command 的處理流理,可以透過 smbd/process.c 的下面 array,找到該 command 的處理函數。
static const struct smb_message_struct {
00582         const char *name;
00583         int (*fn)(connection_struct *conn, char *, char *, int, int);
00584         int flags;
00585 } smb_messages[256] = {
00586 
00587 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
00588 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
00589 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
00590 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
00591 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },

結論

分析 source code,首要就是了解主要的架構。製作出如上面列出的主要流程後,再依據分析的目的,參考主要流程,進行更深入的了解,以便在骨架上填上血和肉。透過這樣的方式,能分析的更快、更好。

若是一開始就栽入 source code 的細節裡,往往是陷入見樹不見林的窘境。因此,首要務是掌握大綱、抑制對細節的渴望,才能快速、正確的了解系統的精神。

REFERENCEs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值