• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-161  評(píng)論-223  文章-30  trackbacks-0
             
               為了減少程序中的硬編碼,靈活按需管理字符串空間,使用了ATL中的CString類(lèi),代碼如下
             1         CString bstrComPathName;
             2         WCHAR componentPathName[1];
             3         DWORD dwNameLen = 1;    
             4 
             5         if (!GetComputerNameEx(ComputerNamePhysicalDnsFullyQualified, componentPathName, &dwNameLen))
             6         { 
             7             DWORD dwErr = GetLastError();
             8             if(ERROR_MORE_DATA==dwErr)
             9             {            
            10                 if (!GetComputerNameEx(ComputerNamePhysicalDnsFullyQualified, bstrComPathName.GetBuffer(dwNameLen), &dwNameLen))
            11                 { 
            12                     zlog_error(g_zc, "GetComputerNameEx with ComputerNamePhysicalDnsFullyQualified fail: %d", GetLastError());
            13                     return -1;
            14                 }
            15             }
            16             else
            17             {
            18                 zlog_error(g_zc, "GetComputerNameEx with ComputerNamePhysicalDnsFullyQualified for fail: %d", dwErr);
            19                 return -1;
            20             }
            21         }                
            22         bstrComPathName.ReleaseBuffer(); 
                需要注意的是,GetBuffer方法雖提供方便了直接修改CString對(duì)象的內(nèi)部緩沖區(qū),但違背了面向?qū)ο笤O(shè)計(jì)的原則(由公開(kāi)方法修改內(nèi)部數(shù)據(jù)),因此不保證對(duì)象的完整性,在操作完成后一定要調(diào)用ReleaseBuffer
            posted @ 2019-07-31 12:51 春秋十二月 閱讀(7985) | 評(píng)論 (0)編輯 收藏
              在GNU make中文手冊(cè)這本書(shū)中,3.14節(jié)講到了依賴(lài)文件的自動(dòng)生成,如下圖


              圖中的規(guī)則對(duì)C源文件和Makefile在同一目錄,是正確的。但是不在同一目錄的又希望依賴(lài)文件在對(duì)應(yīng)的目錄下,比如src/log/log_file.c,希望依賴(lài)文件log_file.d生成在src/log/下。因?yàn)間cc(aix平臺(tái)xlc編譯器亦如此)生成的依賴(lài)文件內(nèi)容中目標(biāo)文件名沒(méi)有帶路徑,例如下所示
            log_file.o: src/log/log_file.c src/log/log_file.h src/log/log_type.h \
             src/log/../base/io_ext.h

              所以sed就找不到src/log/log_file.o而替換了,改正后的規(guī)則如下
            %.d: %.c
                $(CC) $(CFLAGS) $(INCS) $< $(MFLAGS) $@.$$$$;\
                sed 's,$(*F).o[ :]*,$*.o $@: ,g' < $@.$$$$ > $@;\
                $(RM) $@.$$$$

              該規(guī)則對(duì)C源文件和Makefile在同一目錄也適合,生成后的依賴(lài)文件內(nèi)容如下
            src/log/log_file.o src/log/log_file.d: src/log/log_file.c src/log/log_file.h src/log/log_type.h \
             src/log/../base/io_ext.h
            posted @ 2018-11-16 12:08 春秋十二月 閱讀(867) | 評(píng)論 (0)編輯 收藏
            由于traceroute只能診斷UDP通信的包路由,不能確定TCP通信的實(shí)際路由(可能變換),因此編寫(xiě)了本文。為方便描述,下面的IP、MAC和端口均為示例,實(shí)際診斷中可更換為具體的值

            1. 如何判斷客戶端到服務(wù)器的TCP包,是否經(jīng)過(guò)了網(wǎng)關(guān)
                 在客戶端執(zhí)行 tcpdump -i eno16777728 ether dst b0:b9:8a:69:65:3e and host 192.168.0.26 and tcp port 80  抓取經(jīng)過(guò)網(wǎng)關(guān)且往返服務(wù)器的TCP端口為80的包
                 eno16777728 接口名稱(chēng);ether 以太網(wǎng)鏈路,dst 目標(biāo)(src表示源);b0:b9:8a:69:65:3e 網(wǎng)關(guān)MAC地址;192.168.0.26 服務(wù)器IP地址,80 監(jiān)聽(tīng)端口

                 輸出結(jié)果分析
                   ● 有輸出,則表示經(jīng)過(guò)了網(wǎng)關(guān)
                   ● 有部分輸出而TCP通信還在進(jìn)行,則表示先前的包經(jīng)過(guò)了網(wǎng)關(guān),后來(lái)路由表項(xiàng)緩存被重定向更新,沒(méi)經(jīng)過(guò)網(wǎng)關(guān)了
                   ● 不斷輸出,則表示一直經(jīng)過(guò)網(wǎng)關(guān)

            2. 如何判斷路由表項(xiàng)緩存被重定向更新
                 在客戶端執(zhí)行 tcpdump -i eno16777728 src 192.168.1.1 and dst 192.168.1.45 and icmp  抓取來(lái)自網(wǎng)關(guān)和到達(dá)客戶端的所有icmp包
                 192.168.1.1 網(wǎng)關(guān)IP;192.168.1.45 客戶端(出口)IP

                 輸出結(jié)果分析
                   ● 沒(méi)有輸出,則表示沒(méi)有收到rerdirect包,路由表項(xiàng)緩存不變
                   ● 有輸出類(lèi)似ICMP redirect 192.168.0.26 to host 192.168.0.26(前面一個(gè)IP表示到達(dá)服務(wù)器的直接路由IP,后一個(gè)表示服務(wù)器IP)
                   ● 則表示收到了ICMP重定向包,內(nèi)核會(huì)更新路由表項(xiàng)及緩存網(wǎng)關(guān)為192.168.0.26,下次通信時(shí)就直接發(fā)往192.168.0.26了

            3. 如何控制接收ICMP重定向
                  ● echo 0 | tee /proc/sys/net/ipv4/conf/*/accept_redirects    禁止所有網(wǎng)卡接收,可避免路由表項(xiàng)緩存被修改
                  ● echo 1 | tee /proc/sys/net/ipv4/conf/*/accept_redirects    啟用所有網(wǎng)卡接收ICMP重定向消息

            4. 查看、刷新路由表項(xiàng)緩存
                  ● ip route get 192.168.0.26    可以從輸出中看到通住目標(biāo)IP的實(shí)際路由
                  ● ip route flush cache             清空路由表項(xiàng)緩存,下次通信時(shí)內(nèi)核會(huì)查main表(即命令route輸出的表)以確定路由
            posted @ 2017-12-29 17:24 春秋十二月 閱讀(1985) | 評(píng)論 (0)編輯 收藏
            前言
               近期有機(jī)會(huì),深入了SSL/TLS協(xié)議原理與細(xì)節(jié),并分析了相關(guān)密碼學(xué)內(nèi)容,心得頗多,歷經(jīng)半月,終于寫(xiě)成了這份文檔。
               本人水平尚有限,錯(cuò)誤難免,歡迎指正,不勝感激。

            目錄
                     

            部分章節(jié)預(yù)覽
               第3章


               第5章第4節(jié)


               第11章第3節(jié)

            全文
               下載地址:深入理解SSL/TLS技術(shù)內(nèi)幕
            posted @ 2016-12-15 17:16 春秋十二月 閱讀(1641) | 評(píng)論 (0)編輯 收藏
            算法描述
            【公開(kāi)密鑰】    
               p是512到1024位的素?cái)?shù)
               q是160位長(zhǎng),并與p-1互素的因子
               g = h^((p-1)/q) mod p,其中h<p-1且g>1
               y = g^x mod p
            【私有密鑰】
               x < q,長(zhǎng)160位
            【簽名】
               k為小于q的隨機(jī)數(shù),k^-1為k模q的逆元,m為消息,H為單向散列函數(shù)
               r = (g^k mod p) mod q
               s = (k^-1(H(m)+xr)) mod q
            【驗(yàn)證】
               w = s^-1 mod q
               u1 = (H(m)w) mod q
               u2 = (rw) mod q
               v = ((g^u1 * y^u2) mod p) mod q
               若v = r,則簽名被驗(yàn)證

            驗(yàn)簽推導(dǎo)
               1. 先證明兩個(gè)中間結(jié)論
                  因(h,p)=1(p為素?cái)?shù)且h<p,(a1,a1)是數(shù)論中的符號(hào),記為a1與a2的最大公約數(shù)),故依費(fèi)馬小定理有h^(p-1)=1 mod p,則對(duì)任意整數(shù)n,有
                  g^(nq) mod p = (h^((p-1)/q))^(nq) mod p
                                      = h^(n(p-1)) mod p
                                      = (h^(p-1) mod p)^n  mod p
                                      = (1^n) mod p = 1     (1)
                  對(duì)任意整數(shù)t、n,可表示為t=nq+z,其中z>0,則有
                  g^t mod p = g^(nq+z) mod p
                                  = (g^(nq) mod p * (g^z mod p)) mod p
                                  = g^z mod p
                                  = g^(t mod q) mod p    (2)

              2. 再假設(shè)簽名{r,s}和消息m均沒(méi)被修改,令H(m)=h,開(kāi)始推導(dǎo)v
                  v = ((g^u1 * y^u2) mod p) mod q
                     = (g^(hw mod q) * ((g^x mod p)^(rw mod q) mod p)) mod q
                     = ((g^(hw mod q) mod p * ((g^x mod p)^(rw mod q) mod p)) mod p) mod q
                     = ((g^(hw mod q) mod p * (g^(x * (rw mod q)) mod p)) mod p) mod q
                     = ((g^(hw) mod p * ((g^(rw mod q) mod p)^x mod p)) mod p) mod q
                     = ((g^(hw) mod p * ((g^(rw) mod p)^x mod p)) mod p) mod q
                     = ((g^(hw) mod p * (g^(rwx) mod p)) mod p) mod q
                     = (g^(hw+rwx) mod p) mod q
                     = (g^((h+rx)w) mod p) mod q    (3)

                  又因w = s^-1 mod q
                     故(sw) mod q = 1
                       =>(((k^-1(h+xr)) mod q)w) mod q = 1
                       =>((k^-1(h+xr))w) mod q = 1
                       =>(h+xr)w = k mod q    (4)

                  將(4)式代入(3)式中得
                  v = (g^(k mod q) mod p) mod q
                     = (g^k mod p) mod q
                     = r

              3. 最后由(4)式知,若h、r和s任一個(gè)有變化(s變化導(dǎo)致w變化),則v ≠ r
            posted @ 2016-11-24 19:39 春秋十二月 閱讀(5357) | 評(píng)論 (0)編輯 收藏
            算法描述    
               隨機(jī)選擇兩個(gè)大的素?cái)?shù) p、q ,且p ≠ q,計(jì)算n = pq、r = (p-1)(q-1),依歐拉定理,r即為與n互質(zhì)的素?cái)?shù)個(gè)數(shù);選擇一個(gè)小于r的整數(shù)e(即加密指數(shù)),求得e關(guān)于模r的逆元d(即解密指數(shù)),則{n,e}為公鑰、{n,d}為私鑰;根據(jù)模的逆元性質(zhì)有ed ≡ 1 (mod r);設(shè)m為明文,則加密運(yùn)算為m^e ≡ c (mod n), c即為密文;則解密過(guò)程 c^d ≡ m (mod n)。
               證明會(huì)用到費(fèi)馬小定理,即 若y為素?cái)?shù)且x不為y的倍數(shù), 則 x^(y-1) ≡ 1 (mod y)(費(fèi)馬小定理的證明需先證明歐拉定理,此處略)。符號(hào)≡表示同余,^表示,|表示整除,*表示相乘。

            算法證明
             第一種證明途徑   
               因 ed ≡ 1 (mod (p-1)(q-1)),令 ed = k(p-1)(q-1) + 1,其中 k 是整數(shù)
               則 c^d = (m^e)^d = m^(ed) = m^(k(p-1)(q-1)+1)
               1.若m不是p的倍數(shù),也不是q的倍數(shù)
                  則 m^(p-1) ≡ 1 (mod p) (費(fèi)馬小定理)
                     => m^(k(p-1)(q-1)) ≡ 1 (mod p)
                  m^(q-1) ≡ 1 (mod q) (費(fèi)馬小定理)
                     => m^(k(p-1)(q-1)) ≡ 1 (mod q)
                  故 p、q 均能整除 m^(k(p-1)(q-1)) - 1
                     => pq | m^(k(p-1)(q-1)) - 1
                  即 m^(k(p-1)(q-1)) ≡ 1 (mod pq)   
                     => m^(k(p-1)(q-1)+1) ≡ m (mod n)   

               2.若m是p的倍數(shù),但不是q的倍數(shù)
                  則 m^(q-1) ≡ 1 (mod q) (費(fèi)馬小定理)
                     => m^(k(p-1)(q-1)) ≡ 1 (mod q)
                     => m^(k(p-1)(q-1)+1) ≡ m (mod q)
                  因 p | m
                     => m^(k(p-1)(q-1)+1) ≡ 0 (mod p)
                     => m^(k(p-1)(q-1)+1) ≡ m (mod p)
                  故 m^(k(p-1)(q-1)+1) ≡ m (mod pq) 
                  即 m^(k(p-1)(q-1)+1) ≡ m (mod n)

               3.若m是q的倍數(shù),但不是p的倍數(shù),證明同上

               4.若m同為p和q的倍數(shù)時(shí)
                  則 pq | m
                     => m^(k(p-1)(q-1)+1) ≡ 0 (mod pq)
                     => m^(k(p-1)(q-1)+1) ≡ m (mod pq)
                  即 m^(k(p-1)(q-1)+1) ≡ m (mod n)

             第二種證明途徑
               先證明m^ed ≡ m (mod p)恒成立
               1.若p為m的因子,則p | m^ed - m顯然成立,即m^ed ≡ m (mod p)
               2.若p不為m的因子,令ed = k(p-1)(q-1) + 1,則 m^(ed-1) - 1 = m^(k(p-1)(q-1)) - 1
                   m^(p-1) ≡ 1 (mod p) (費(fèi)馬小定理)
                    => m^(k(p-1)) ≡ 1 (mod p)
                    => m^(k(p-1)(q-1)) ≡ 1 (mod p)
                    => m^(ed-1) ≡ 1 (mod p)
                    => m^ed ≡ m (mod p)
               同理可證m^ed ≡ m (mod q)
               故m^ed ≡ m (mod pq),即m^ed ≡ m (mod n)
               又因 c^d = m^e^d = m^(ed)
               故 c^d ≡ m (mod n),證畢
               
            總結(jié)
             第二種比第一種簡(jiǎn)單直觀,以上證明途徑對(duì)RSA私鑰簽名與驗(yàn)簽同樣適合。
            posted @ 2016-11-18 17:05 春秋十二月 閱讀(2654) | 評(píng)論 (0)編輯 收藏
            腳本源碼
               由于很多應(yīng)用項(xiàng)目依賴(lài)諸多第三方開(kāi)源庫(kù),這些開(kāi)源庫(kù)各有不同的核心目錄、庫(kù)目標(biāo)和輸出位置,這里的核心目錄是指僅產(chǎn)生so庫(kù)的工程目錄,庫(kù)目標(biāo)是指僅產(chǎn)生so庫(kù)的make目標(biāo),輸出位置是相對(duì)于核心目錄的,但不必是子目錄,可用..來(lái)回溯到父目錄的某位置,更高層目錄的位置,依次類(lèi)推。為了統(tǒng)一支持它們,使用了一些技巧,詳見(jiàn)示例腳本如下
             1.PHONY: all clean lib core
             2
             3thirdlib=openssl-1.0.1u?build_ssl ACE_wrappers/ace json ncurses-6.0??lib
             4coremod=main
             5
             6dir = `echo $@ | awk -F? '{print $$1}'`
             7aim = `echo $@ | awk -F? '{print $$2}'`
             8out = `echo $@ | awk -F? '{print $$3}'`
             9
            10copy=\cp -Pf ${dir}/${out}/*.so* output
            11
            12define MAKE_SUBDIR
            13echo "${dir},${aim},${out}"\
            14if [ "$(MAKECMDGOALS)" != "clean" ]; then \
            15$(MAKE) ${aim} -${dir}\
            16if [ "$$is_cp" -eq "1" ]; then \
            17$(copy); \
            18fi \
            19else \
            20$(MAKE) clean -C ${dir}; \
            21fi 
            22endef
            23
            24all: lib core
            25
            26lib: $(thirdlib)
            27
            28$(thirdlib)::
            29    @is_cp=1; $(MAKE_SUBDIR)
            30
            31core: $(coremod)
            32
            33$(coremod)::
            34    @is_cp=0; $(MAKE_SUBDIR)
            35
            36clean: $(thirdlib) $(coremod)

            實(shí)現(xiàn)技巧
               1)使用?作為分隔符,所分隔的3個(gè)域依次為核心目錄、庫(kù)目標(biāo)、輸出位置;使用awk來(lái)獲取各域,分別為dir、aim和out;在運(yùn)行過(guò)程中,值dir一定非空,而aim為空則表示默認(rèn)目標(biāo),out為空表示輸出位置即為dir目錄。
               2)copy為命令變量,功能為每當(dāng)一個(gè)庫(kù)編譯完成后,將輸出的so庫(kù)拷貝到output下,并保持軟鏈接;對(duì)于有的開(kāi)源庫(kù),需在編譯前,使用對(duì)應(yīng)的選項(xiàng)來(lái)調(diào)用configure,使其生成so庫(kù)。
               3)為了重用代碼,定義了MAKE_SUBDIR命令包,參數(shù)變量為is_cp,當(dāng)is_cp為1時(shí),表示當(dāng)前編譯的是依賴(lài)庫(kù),否則是主程序。 
               4)thirdlib和coremod為依賴(lài)文件,使用了雙冒號(hào)規(guī)則,這樣一來(lái),只要在thirdlib中加入新的依賴(lài)庫(kù),指定核心目錄、庫(kù)目標(biāo)和輸出位置即可,其它地方不用改。
            posted @ 2016-10-19 15:11 春秋十二月 閱讀(3264) | 評(píng)論 (0)編輯 收藏
            腳本概述
               當(dāng)需要在很多(比如幾十至幾百)臺(tái)機(jī)器上編譯同一程序時(shí),如果一個(gè)個(gè)地手工拷貝源碼、再編譯,那么效率就很低,為了能大量節(jié)省手工、并行地編譯,因此寫(xiě)了一個(gè)腳本,該腳本基于自動(dòng)化腳本語(yǔ)言expect(expect基于tcl)實(shí)現(xiàn),基本原理是針對(duì)每個(gè)遠(yuǎn)程主機(jī),創(chuàng)建一個(gè)子進(jìn)程,在該子進(jìn)程內(nèi)先調(diào)用scp拷貝源碼到遠(yuǎn)程主機(jī),再用ssh登錄到遠(yuǎn)程主機(jī)、發(fā)送cd、configure和make命令,交互期間的命令輸出多用正則分析,最終的編譯輸出保存到當(dāng)前目錄output子目錄下。其命令行參數(shù)說(shuō)明如下:
                第1參數(shù)為遠(yuǎn)程主機(jī)配置文件:一個(gè)多行文本文件,每行格式為IP 用戶名 密碼,空格符分隔,支持#注釋。
                第2參數(shù)為本地主機(jī)源碼目錄:要求該目錄存在Makefile和configure文件。
                第3參數(shù)為遠(yuǎn)程主機(jī)目標(biāo)目錄:用于存放源碼的位置。

            腳本實(shí)現(xiàn)
               拷貝源碼
             1proc copy_file {host user srcdir dstdir passwd {to 10} } {
             2    if [catch "spawn scp -rq $srcdir $user@$host:$dstdir" msg] {
             3        send_error "failed to spawn scp: $msg\n"
             4        exit 1
             5    }
             6    
             7    set timeout $to
             8    expect_after eof { 
             9        send_error "$host scp died unexpectedly\n"
            10        exit 1
            11    }
            12    expect {
            13        "(yes/no)?" { send "yes\r"; exp_continue }
            14        -re "(?:P|p)assword:" { send "$passwd\r" }
            15        timeout { do_timeout "$host scp" }
            16    }
            17
            18    expect {
            19        full_buffer { exp_continue }
            20        timeout { exp_continue }
            21        eof 
            22    }
            23}
               第2行調(diào)用spawn命令執(zhí)行scp命令,并用catch捕捉錯(cuò)誤;當(dāng)執(zhí)行成功后,第12行用expect等待遠(yuǎn)端輸出(超時(shí)默認(rèn)為10秒),第13、14行自動(dòng)輸入用戶名和密碼,當(dāng)過(guò)程中網(wǎng)絡(luò)連接斷開(kāi)時(shí),會(huì)匹配到第8行的eof;當(dāng)輸出完成連接關(guān)閉時(shí),會(huì)匹配到第21行的eof;如果輸出太多超過(guò)expect內(nèi)部的buffer時(shí),會(huì)匹配到第19行的full_buffer,這里由于為了提高效率,使用了靜默方式的scp,因些實(shí)際會(huì)匹配到第20行的timeout,不管匹配到哪種情況,都要繼續(xù)直到eof。
             
               執(zhí)行編譯
             1proc do_make {host user passwd subdir {to 10} } {
             2    if [catch {spawn ssh $user@$host} msg ] {
             3        send_error "failed to spawn ssh: $msg\n"
             4        exit 1
             5    }
             6    
             7    set timeout $to
             8    expect_after eof { 
             9        send_error "$host ssh died unexpectedly\n"
            10        exit 1
            11    }
            12    
            13    expect {  
            14        "*yes/no" { send "yes\r"; exp_continue }
            15        -re "(?:P|p)assword:" { send "$passwd\r" }  
            16        timeout { do_timeout "$host ssh" }
            17    }  
            18    wait_cmd $spawn_id passwd
            19
            20    send "cd $subdir\r"  
            21    wait_cmd $spawn_id cd
            22    
            23    send "source configure\r"
            24    wait_cmd $spawn_id configure
            25
            26    send "make\r"  
            27    wait_cmd $spawn_id make
            28
            29    send "exit\r"  
            30    expect eof  
            31}
               關(guān)于spawn和expect的解釋與上節(jié)拷貝源碼相同,不同的是依次發(fā)送命令cd、source configure、make,每個(gè)命令須等到命令提示符后(調(diào)用自定義函數(shù)wait_cmd)再發(fā)下一個(gè),最后發(fā)送exit退出ssh、導(dǎo)致連接關(guān)閉,匹配到最后一行的eof。對(duì)于有的項(xiàng)目源碼,可能沒(méi)有或不用配置,那么configure文件可以不存在或內(nèi)容為空,如果不存在導(dǎo)致報(bào)錯(cuò)也沒(méi)關(guān)系,不影響make;如果configure出錯(cuò),那么make也會(huì)出錯(cuò)。這里使用source是為了使配置在當(dāng)前shell中生效。
               
               主循環(huán)
             1set f [open $file r]
             2set curtime [clock seconds]
             3
             4log_user 0
             5set s {[:blank:]}
             6set pattern "^(\[^#$s]+)\[$s]+(\[^$s]+)\[$s]+(\[^$s]+)"
             7
             8while { [gets $f line] != -1 } {
             9    if { ![regexp $pattern [string trimleft $line] ? host user passwd] } {
            10        continue
            11    }
            12    send_user "$host $user $passwd\n"
            13    if { ![fork] } {
            14        
            15        set filename output/${host}_[clock format $curtime -format %y.%m.%d_%H.%M.%S].log
            16        log_file -noappend -a $filename
            17
            18        copy_file $host $user $srcdir $dstdir $passwd 30
            19        do_make $host $user $passwd $subdir 30
            20
            21        send_user "$host finish\n"
            22        exit
            23    }
            24}
               打開(kāi)遠(yuǎn)程主機(jī)配置文件,讀取每一行直到文件尾,忽略注釋行,用正則提取IP、用戶名和密碼,創(chuàng)建子進(jìn)程,按IP和當(dāng)前時(shí)間命名log文件(由于前面調(diào)用log_user 0關(guān)閉了控制臺(tái)輸出,因此為了能記錄輸出到日志文件,一定要加-a選項(xiàng)),最后調(diào)用函數(shù)copy_file和do_make。
               
               完整腳本下載:autobuild.zip
            posted @ 2016-09-28 11:04 春秋十二月 閱讀(3856) | 評(píng)論 (0)編輯 收藏
            描述
               云查殺平臺(tái)以nginx作為反向代理服務(wù)器,作為安全終端與云查詢服務(wù)的橋梁。當(dāng)安全終端需要查詢黑文件時(shí),HTTP請(qǐng)求及其響應(yīng)都會(huì)經(jīng)過(guò)nginx,為了獲取并統(tǒng)計(jì)一天24小時(shí)查詢的黑文件數(shù)量,就得先截獲經(jīng)過(guò)nginx的HTTP響應(yīng),再做數(shù)據(jù)分析。截獲HTTP數(shù)據(jù)流有多種方法,為了簡(jiǎn)單高效,這里使用了掛接HTTP過(guò)濾模塊的方法,另外為了不影響nginx本身的IO處理,將HTTP響應(yīng)實(shí)體發(fā)送到另一個(gè)進(jìn)程即統(tǒng)計(jì)服務(wù),由統(tǒng)計(jì)服務(wù)來(lái)接收并分析HTTP響應(yīng),架構(gòu)如下圖
               統(tǒng)計(jì)服務(wù)由1個(gè)接收線程和1個(gè)存儲(chǔ)線程構(gòu)成,其中接收線程負(fù)責(zé)接收從nginx過(guò)濾模塊發(fā)來(lái)的HTTP響應(yīng)實(shí)體,解析它并提取黑文件MD5,加入共享環(huán)形隊(duì)列;而存儲(chǔ)線程從共享環(huán)形隊(duì)列移出黑文件MD5,插入到臨時(shí)內(nèi)存映射文件,于每天定時(shí)同步到磁盤(pán)文件。

            特點(diǎn)
               這種架構(gòu)減少了nginx IO延遲,保證了nginx的穩(wěn)定高效運(yùn)行,從而不影響用戶的業(yè)務(wù)運(yùn)行;本地連接為非阻塞的,支持了統(tǒng)計(jì)服務(wù)的獨(dú)立運(yùn)行與升級(jí)。

            實(shí)現(xiàn)
               nginx過(guò)濾模塊
                  該流程運(yùn)行在nginx工作進(jìn)程。
                  由于nginx采用了異步IO機(jī)制,因此僅當(dāng)截獲到HTTP響應(yīng)實(shí)體也就是有數(shù)據(jù)經(jīng)過(guò)時(shí),才有后面的操作;若沒(méi)有數(shù)據(jù),則什么也不用做。這里每次發(fā)送前先判斷是否連接了統(tǒng)計(jì)服務(wù),是為了支持統(tǒng)計(jì)服務(wù)的獨(dú)立運(yùn)行與升級(jí),換句話說(shuō),不管統(tǒng)計(jì)服務(wù)是否運(yùn)行或崩潰,都不影響nginx的運(yùn)行。

            統(tǒng)計(jì)服務(wù)
               接收線程
                  這里的接收線程也就是主線程。
              
               存儲(chǔ)線程
                  存儲(chǔ)線程為另一個(gè)工作線程。
                  同步文件定時(shí)器的時(shí)間間隔要比新建文件定時(shí)器的短,由于定時(shí)器到期的事件處理是一種異步執(zhí)行流,所以將它們當(dāng)做并行,與“從q頭移出黑文件MD5”操作畫(huà)在了同一水平方向。
            posted @ 2016-08-25 11:10 春秋十二月 閱讀(1102) | 評(píng)論 (0)編輯 收藏
            描述
               攔截Linux動(dòng)態(tài)庫(kù)API的常規(guī)方法,是基于動(dòng)態(tài)符號(hào)鏈接覆蓋技術(shù)實(shí)現(xiàn)的,基本步驟是
                1. 重命名要攔截的目標(biāo)動(dòng)態(tài)庫(kù)。
                2. 創(chuàng)建新的同名動(dòng)態(tài)庫(kù),定義要攔截的同名API,在API內(nèi)部調(diào)用原動(dòng)態(tài)庫(kù)對(duì)應(yīng)的API。這里的同名是指與重命名前動(dòng)態(tài)庫(kù)前的名稱(chēng)相同。
               顯而易見(jiàn),如果要攔截多個(gè)不同動(dòng)態(tài)庫(kù)中的API,那么必須創(chuàng)建多個(gè)對(duì)應(yīng)的同名動(dòng)態(tài)庫(kù),這樣一來(lái)不僅繁瑣低效,還必須被優(yōu)先鏈接到客戶二進(jìn)制程序中(根據(jù)動(dòng)態(tài)庫(kù)鏈接原理,對(duì)重復(fù)ABI符號(hào)的處理是選擇優(yōu)先鏈接的那個(gè)動(dòng)態(tài)庫(kù))。 另外在鉤子函數(shù)的實(shí)現(xiàn)中,若某調(diào)用鏈調(diào)用到了原API,則會(huì)引起死循環(huán)而崩潰。本方法通過(guò)直接修改ELF文件中的動(dòng)態(tài)庫(kù)API入口表項(xiàng),解決了常規(guī)方法的上述問(wèn)題。

            特點(diǎn)
               1. 不依賴(lài)于動(dòng)態(tài)庫(kù)鏈接順序。
               2. 能攔截多個(gè)不同動(dòng)態(tài)庫(kù)中的多個(gè)API。
               3. 支持運(yùn)行時(shí)動(dòng)態(tài)鏈接的攔截。
               4. 鉤子函數(shù)內(nèi)的實(shí)現(xiàn)體,若調(diào)用到原API,則不會(huì)死循環(huán)。


            實(shí)現(xiàn)
               攔截映射表
                  為了支持特點(diǎn)2和3,建立了一個(gè)攔截映射表,這個(gè)映射表有2級(jí)。第1級(jí)為ELF文件到它的API鉤子映射表,鍵為ELF文件句柄,值為API鉤子映射表;第2級(jí)為API到它的鉤子函數(shù)映射表,鍵為API名稱(chēng),值為包含最老原函數(shù)地址和最新鉤子函數(shù)地址的結(jié)構(gòu)體,如下圖
                  當(dāng)最先打開(kāi)ELF文件成功時(shí),會(huì)在第1級(jí)映射表中插入記錄;反之當(dāng)最后關(guān)閉同一ELF文件時(shí),就會(huì)從中移除對(duì)應(yīng)的記錄。當(dāng)?shù)谝淮螔煦^動(dòng)態(tài)庫(kù)API時(shí),就會(huì)在第2級(jí)映射表插入記錄;反之卸鉤同一API時(shí),就會(huì)從中刪除對(duì)應(yīng)的記錄。

               計(jì)算ELF文件的映像基地址
                  計(jì)算映像基地址是為了得到ELF中動(dòng)態(tài)符號(hào)表和重定位鏈接過(guò)程表的內(nèi)容,因?yàn)檫@些表的位置都是相對(duì)于基地址的偏移量,該算法在打開(kāi)ELF文件時(shí)執(zhí)行,如下圖
                  EXE文件為可執(zhí)行文件,DYN文件為動(dòng)態(tài)庫(kù)。對(duì)于可執(zhí)行文件,映射基地址為可執(zhí)行裝載段的虛擬地址;對(duì)于動(dòng)態(tài)庫(kù),可通過(guò)任一API的地址減去它的偏移量得到,任一API的地址可通過(guò)調(diào)用libdl.so庫(kù)API dlsym得到,偏移量通過(guò)查詢動(dòng)態(tài)鏈接符號(hào)表得到。

               打開(kāi)ELF文件
                  為了支持特點(diǎn)2即攔截不同動(dòng)態(tài)庫(kù)的多個(gè)API,節(jié)省每次掛鉤API前要打開(kāi)并讀文件的開(kāi)銷(xiāo),獨(dú)立提供了打開(kāi)ELF文件的接口操作,流程如下圖
                  若輸入ELF文件名為空,則表示打開(kāi)當(dāng)前進(jìn)程的可執(zhí)行文件,此時(shí)要從偽文件系統(tǒng)/proc/self/exe讀取文件路徑名,以正確調(diào)用系統(tǒng)調(diào)用open。當(dāng)同一ELF文件被多次打開(kāi)時(shí),只須遞增結(jié)構(gòu)elf的引用計(jì)數(shù)。

               掛鉤API
                  當(dāng)打開(kāi)ELF文件后,就可掛鉤API了,流程如下圖
                  當(dāng)?shù)谝淮螔煦^時(shí),需要保存原函數(shù)以供后面卸鉤;第二次以后繼續(xù)掛鉤同一API時(shí),更新鉤子函數(shù),但原函數(shù)不變。   
               
               卸鉤API
                  當(dāng)打開(kāi)ELF文件后,就可卸鉤API了,流程如下圖

               關(guān)閉ELF文件
                  因?yàn)樘峁┝舜蜷_(kāi)ELF文件的接口操作,所以得配有關(guān)閉ELF文件的接口操作。當(dāng)不需要掛鉤API的時(shí)候,就可以關(guān)閉ELF文件了,流程如下圖


            運(yùn)行時(shí)動(dòng)態(tài)攔截裝置
               在初始化模塊中打開(kāi)當(dāng)前可執(zhí)行文件,掛鉤libdl.so庫(kù)的API dlopen和dlsym;在轉(zhuǎn)換模塊中,按動(dòng)態(tài)庫(kù)句柄和API名稱(chēng)在攔截映射表中查找鉤子函數(shù),若找到則返回鉤子函數(shù),否則返回調(diào)用dlsym的結(jié)果;在銷(xiāo)毀模塊中,卸鉤dlopen和dlsym。
            當(dāng)動(dòng)態(tài)庫(kù)被進(jìn)程加載的時(shí)候,會(huì)調(diào)用初始化模塊;當(dāng)被進(jìn)程卸載或進(jìn)程退出的時(shí)候,會(huì)調(diào)用銷(xiāo)毀模塊;當(dāng)通過(guò)dlsym調(diào)用API時(shí),則會(huì)在dlsym的鉤子函數(shù)中調(diào)用轉(zhuǎn)換模塊。通過(guò)環(huán)境變量LD_PRELOAD將動(dòng)態(tài)庫(kù)libhookapi.so設(shè)為預(yù)加載庫(kù),這樣就能攔截到所有進(jìn)程對(duì)dlopen及dlsym的調(diào)用,進(jìn)而攔截到已掛鉤動(dòng)態(tài)庫(kù)API的調(diào)用。
            posted @ 2016-08-25 11:10 春秋十二月 閱讀(2287) | 評(píng)論 (0)編輯 收藏
            僅列出標(biāo)題
            共17頁(yè): First 4 5 6 7 8 9 10 11 12 Last 
            狠狠色丁香久久婷婷综合_中| 久久精品天天中文字幕人妻| 72种姿势欧美久久久久大黄蕉| 少妇熟女久久综合网色欲| 亚洲成色www久久网站夜月| 久久亚洲精品无码VA大香大香| 久久91综合国产91久久精品| 国产精品亚洲综合专区片高清久久久| 久久亚洲国产成人影院网站| 精品久久久久久亚洲精品 | 久久久久久免费视频| 亚洲AV无码成人网站久久精品大| 99久久精品免费观看国产| 亚洲午夜精品久久久久久app| av午夜福利一片免费看久久| 久久只有这里有精品4| 超级碰久久免费公开视频| 久久精品国产亚洲AV不卡| 99久久亚洲综合精品网站| 亚洲色婷婷综合久久| 久久99久久成人免费播放| 久久99精品国产自在现线小黄鸭| 久久久精品久久久久久 | 久久久久久久国产免费看| 久久综合给合久久狠狠狠97色69 | 亚洲国产婷婷香蕉久久久久久| 国产精品一区二区久久不卡| 亚洲乱码精品久久久久..| 欧美国产精品久久高清| 久久久久亚洲AV成人网| 久久精品国产亚洲麻豆| 久久狠狠高潮亚洲精品| 亚洲AV日韩AV永久无码久久| 99精品国产免费久久久久久下载| 欧美精品丝袜久久久中文字幕 | 久久精品国产亚洲精品| 久久99精品九九九久久婷婷| 亚洲国产成人久久综合碰碰动漫3d| 久久国产精品77777| 久久久国产精品亚洲一区| 久久久精品人妻一区二区三区蜜桃|