Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1959573
  • 博文数量: 1000
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7921
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-20 09:23
个人简介

storage R&D guy.

文章分类

全部博文(1000)

文章存档

2019年(5)

2017年(47)

2016年(38)

2015年(539)

2014年(193)

2013年(178)

分类: 服务器与存储

2015-06-11 17:41:00

转载一篇文章,smbd of samba-3.0.23b internal, 简要介绍了 Samba 中 smbd 的构架。 但是在真正介绍构架之前,首先介绍了代码分析中常用的方法和工具, 这些方法和工具的介绍很有用。
填写简介


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


smbd

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

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


工具

分析一個程式,可以使用最簡單的 joe、、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 產生 ,並列出 refer 或被 refer 的位置。透過 doxygen 產生的 , 我可以使用 mouse,直覺的穿梭在程式碼之間。雖然我還是比較喜歡使用 keyboard,但是卻不是那麼直覺。分析程式碼本來就是一種腦力密集的工作,何以我還要分析去使用不夠直覺的工具?因而,使用 doxygen 產生的文件,似乎能更快完成工作。然而 doxygen 也非完美,無法自動記錄 trace 的過程。


進行分式

 已經有 Doxyfile,可直接拿來產生文件。透過 ,得以穿梭在 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, 都在 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




原文网址: 
阅读(858) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~