??xml version="1.0" encoding="utf-8" standalone="yes"?>C++博客-<table border="0" cellspacing="0" cellpadding="0" style="margin- left:0px;display:inline;height:30px;"><tr><td style="font-weight:bold; font-size:16px; line- height:30px;">一q十二月&nbsp谁主春秋</td><td style="font-size:14px; line-height:30px;"></td></tr></table>http://www.kffa.tw/qinqing1984/专注Q互联网后台、网l、信息安?/description>zh-cnTue, 19 Mar 2019 01:05:09 GMTTue, 19 Mar 2019 01:05:09 GMT60关于make依赖文g的自动生?/title><link>http://www.kffa.tw/qinqing1984/archive/2018/11/16/216067.html</link><dc:creator>春秋十二?/dc:creator><author>春秋十二?/author><pubDate>Fri, 16 Nov 2018 04:08:00 GMT</pubDate><guid>http://www.kffa.tw/qinqing1984/archive/2018/11/16/216067.html</guid><wfw:comment>http://www.kffa.tw/qinqing1984/comments/216067.html</wfw:comment><comments>http://www.kffa.tw/qinqing1984/archive/2018/11/16/216067.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kffa.tw/qinqing1984/comments/commentRss/216067.html</wfw:commentRss><trackback:ping>http://www.kffa.tw/qinqing1984/services/trackbacks/216067.html</trackback:ping><description><![CDATA[<div>  在GNU make中文手册q本书中Q?.14节讲C依赖文g的自动生成,如下?hr /><img src="http://www.kffa.tw/images/cppblog_com/qinqing1984/gnu-make-314.png" width="1419" height="657" alt="" /><br /><br /><div>  图中的规则对C源文件和Makefile在同一目录Q是正确的。但是不在同一目录的又希望依赖文g在对应的目录下,比如src/log/log_file.cQ希望依赖文件log_file.d生成在src/log/下。因为gccQaixq_xlc~译器亦如此Q生成的依赖文g内容中目标文件名没有带\径,例如下所C?/div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #800000;"><strong>log_file.o</strong></span>: src/log/log_file.c src/log/log_file.h src/log/log_type.h \<br /> src/log/../base/io_ext.h</div><div><br />  所以sed找不到src/log/log_file.o而替换了Q改正后的规则如?br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->%.d: %.c<br />    $(CC) $(CFLAGS) $(INCS) $< $(MFLAGS) $@.$$$$<span style="color: #008000; ">;</span><span style="color: #008000; ">\</span><span style="color: #008000; "><br /></span>    sed 's,<span style="color: #ff0000;">$(*F)</span>.o<span>[</span><span> :</span><span>]</span>*,<span style="color: #ff0000;">$*</span>.o $@: ,g' < $@.$$$$ > $@<span style="color: #008000; ">;</span><span style="color: #008000; ">\</span><span style="color: #008000; "><br /></span>    $(RM) $@.$$$$</div><div><br />  该规则对C源文件和Makefile在同一目录也适合Q生成后的依赖文件内容如?br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><strong style="color: #800000;">src/log/log_file.o src/log/log_file.d</strong>: src/log/log_file.c src/log/log_file.h src/log/log_type.h \<br /> src/log/../base/io_ext.h</div></div></div></div></div><img src ="http://www.kffa.tw/qinqing1984/aggbug/216067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.kffa.tw/qinqing1984/" target="_blank">春秋十二?/a> 2018-11-16 12:08 <a href="http://www.kffa.tw/qinqing1984/archive/2018/11/16/216067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ȝ|络路由走向诊断Ҏhttp://www.kffa.tw/qinqing1984/archive/2017/12/29/215452.html春秋十二?/dc:creator>春秋十二?/author>Fri, 29 Dec 2017 09:24:00 GMThttp://www.kffa.tw/qinqing1984/archive/2017/12/29/215452.htmlhttp://www.kffa.tw/qinqing1984/comments/215452.htmlhttp://www.kffa.tw/qinqing1984/archive/2017/12/29/215452.html#Feedback0http://www.kffa.tw/qinqing1984/comments/commentRss/215452.htmlhttp://www.kffa.tw/qinqing1984/services/trackbacks/215452.html׃traceroute只能诊断UDP通信的包路由Q不能确定TCP通信的实际\由(可能变换Q,因此~写了本文。ؓ方便描述Q下面的IP、MAC和端口均为示例,实际诊断中可更换为具体的?/div>

1. 如何判断客户端到服务器的TCP包,是否l过了网?/strong>
     在客L执行 tcpdump -i eno16777728 ether dst b0:b9:8a:69:65:3e and host 192.168.0.26 and tcp port 80  抓取l过|关且往q服务器的TCP端口?0的包
     eno16777728 接口名称Qether 以太|链路,dst 目标Qsrc表示源)Qb0:b9:8a:69:65:3e |关MAC地址Q?92.168.0.26 服务器IP地址Q?0 监听端口

     输出l果分析
       ● 有输出,则表C经q了|关
       ● 有部分输TCP通信q在q行Q则表示先前的包l过了网养I后来路由表项~存被重定向更新Q没l过|关?/div>
       ● 不断输出Q则表示一直经q网?/div>

2. 如何判断路由表项~存被重定向更新
     在客L执行 tcpdump -i eno16777728 src 192.168.1.1 and dst 192.168.1.45 and icmp  抓取来自|关和到辑֮L的所有icmp?/div>
     192.168.1.1 |关IPQ?92.168.1.45 客户端(出口QIP

     输出l果分析
       ● 没有输出Q则表示没有收到rerdirect包,路由表项~存不变
       ● 有输出类?span style="color: #ff0000;">ICMP redirect 192.168.0.26 to host 192.168.0.26Q前面一个IP表示到达服务器的直接路由IPQ后一个表C服务器IPQ?/div>
       ● 则表C收CICMP重定向包Q内怼更新路由表项及缓存网关ؓ192.168.0.26Q下ơ通信时就直接发往192.168.0.26?/div>

3. 如何控制接收ICMP重定?/strong>
      ● echo 0 | tee /proc/sys/net/ipv4/conf/*/accept_redirects    止所有网卡接Ӟ可避免\p缓存被修改
      ● echo 1 | tee /proc/sys/net/ipv4/conf/*/accept_redirects    启用所有网卡接收ICMP重定向消?/div>

4. 查看、刷新\p缓?/strong>
      ● ip route get 192.168.0.26    可以从输Z看到通住目标IP的实际\?/div>
      ● ip route flush cache             清空路由表项~存Q下ơ通信时内怼查main表(卛_令route输出的表Q以定路由


]]>深入理解SSL/TLS技术内q?/title><link>http://www.kffa.tw/qinqing1984/archive/2016/12/15/214491.html</link><dc:creator>春秋十二?/dc:creator><author>春秋十二?/author><pubDate>Thu, 15 Dec 2016 09:16:00 GMT</pubDate><guid>http://www.kffa.tw/qinqing1984/archive/2016/12/15/214491.html</guid><wfw:comment>http://www.kffa.tw/qinqing1984/comments/214491.html</wfw:comment><comments>http://www.kffa.tw/qinqing1984/archive/2016/12/15/214491.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kffa.tw/qinqing1984/comments/commentRss/214491.html</wfw:commentRss><trackback:ping>http://www.kffa.tw/qinqing1984/services/trackbacks/214491.html</trackback:ping><description><![CDATA[<strong style="font-size: 12pt">前言</strong><br />    q期有机会,深入了SSL/TLS协议原理与细节,q分析了相关密码学内容,心得颇多Q历l半月,l于写成了这份文档?br />    本h水^有限,错误隑օQ欢q指正,不胜感激?br /> <br /> <strong style="font-size: 12pt">目录</strong><br />          <img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/deep-ssl-tls-catalogue.png" /><strong><br /> <br /> </strong><strong style="font-size: 12pt">部分章节预览</strong><br /> <strong>   W??/strong><br /> <div align="center"><img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/ssl-tls-protocol-stack.png" /></div> <br /> <br />    <strong>W?章第4?/strong><br /> <div align="center"><img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/ssl-tls-block-cipher.png" /></div> <br /> <br />    <strong>W?1章第3?br /> </strong> <div align="center"><img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/ssl-tls-freak-attack.png" /></div> <br /> <strong style="font-size: 12pt">全文</strong><br />    下蝲地址Q?a href="/Files/qinqing1984/深入理解SSL-TLS技术内q?zip">深入理解SSL/TLS技术内q?/a> <img src ="http://www.kffa.tw/qinqing1984/aggbug/214491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.kffa.tw/qinqing1984/" target="_blank">春秋十二?/a> 2016-12-15 17:16 <a href="http://www.kffa.tw/qinqing1984/archive/2016/12/15/214491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DSA数字{֐的推?/title><link>http://www.kffa.tw/qinqing1984/archive/2016/11/24/214439.html</link><dc:creator>春秋十二?/dc:creator><author>春秋十二?/author><pubDate>Thu, 24 Nov 2016 11:39:00 GMT</pubDate><guid>http://www.kffa.tw/qinqing1984/archive/2016/11/24/214439.html</guid><wfw:comment>http://www.kffa.tw/qinqing1984/comments/214439.html</wfw:comment><comments>http://www.kffa.tw/qinqing1984/archive/2016/11/24/214439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kffa.tw/qinqing1984/comments/commentRss/214439.html</wfw:commentRss><trackback:ping>http://www.kffa.tw/qinqing1984/services/trackbacks/214439.html</trackback:ping><description><![CDATA[<strong style="font-size: 12pt;">法描述</strong><br /> 【公开密钥?   <br />    p?12?024位的素数<br />    q?60位长Qƈ与p-1互素的因?br />    g = h^((p-1)/q) mod pQ其中h<p-1且g>1 <p-1且g><br />    y = g^x mod p<br /> 【私有密钥?br />    x<qQ长160?br /> < qQ长160?br /> 【签名?br />    k为小于q的随机数Qk^-1为k模q的逆元Qm为消息,H为单向散列函?br />    r = (g^k mod p) mod q<br />    s = (k^-1(H(m)+xr)) mod q<br /> 【验证?br />    w = s^-1 mod q<br />    u1 = (H(m)w) mod q<br />    u2 = (rw) mod q<br />    v = ((g^u1 * y^u2) mod p) mod q<br />    若v = rQ则{֐被验?br /> <br /> <strong style="font-size: 12pt">验签推导</strong><br />    <strong>1</strong>. 先证明两个中间结?br />       ?h,p)=1Qp为素Ch<pQ?a1,a1)是数Z的符PCؓa1与a2的最大公U数Q,故依<pQ根据概忉|然得知p和h除了1外,没有其它公约敎ͼ<br />贚w定理有h^(p-1)=1 mod pQ则对Q意整数nQ有<br />       g^(nq) mod p = (h^((p-1)/q))^(nq) mod p <br />                           = h^(n(p-1)) mod p <br />                           = (h^(p-1) mod p)^n  mod p <br />                           = (1^n) mod p = 1     <span style="color: red">(1)</span><br />       对Q意整数t、nQ可表示为t=nq+zQ其中z>0Q则?br /> <z<qQ有<br />       g^t mod p = g^(nq+z) mod p <br />                      = (g^(nq) mod p * (g^z mod p)) mod p <br />                      = g^z mod p<br />                      = g^(t mod q) mod p    <span style="color: red">(2)</span><br /> <br />   <strong>2</strong>. 再假讄名{r,s}和消息m均没被修改,令H(m)=hQ开始推导v<br />       v = ((g^u1 * y^u2) mod p) mod q<br />          = (g^(hw mod q) * ((g^x mod p)^(rw mod q) mod p)) mod q<br />          = ((g^(hw mod q) mod p * ((g^x mod p)^(rw mod q) mod p)) mod p) mod q<br />          = ((g^(hw mod q) mod p * (g^(x * (rw mod q)) mod p)) mod p) mod q<br />          = ((g^(hw) mod p * ((g^(rw mod q) mod p)^x mod p)) mod p) mod q<br />          = ((g^(hw) mod p * ((g^(rw) mod p)^x mod p)) mod p) mod q<br />          = ((g^(hw) mod p * (g^(rwx) mod p)) mod p) mod q<br />          = (g^(hw+rwx) mod p) mod q<br />          = (g^((h+rx)w) mod p) mod q    <span style="color: red">(3)</span> <br /> <br />       又因w = s^-1 mod q<br />          ?sw) mod q = 1<br />            =>(((k^-1(h+xr)) mod q)w) mod q = 1<br />            =>((k^-1(h+xr))w) mod q = 1<br />            =>(h+xr)w = k mod q    <span style="color: red">(4)</span><br /> <br />       ?4)式代?3)式中?br />       v = (g^(k mod q) mod p) mod q<br />          = (g^k mod p) mod q<br />          = r<br /> <br /> <strong>  3</strong>. 最后由(4)式知Q若h、r和sM个有变化Qs变化Dw变化Q,则v ≠ r </z<qQ有<br /> </pQ根据概忉|然得知p和h除了1外,没有其它公约敎ͼ<br /> </qQ长160?br /> </p-1且g><img src ="http://www.kffa.tw/qinqing1984/aggbug/214439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.kffa.tw/qinqing1984/" target="_blank">春秋十二?/a> 2016-11-24 19:39 <a href="http://www.kffa.tw/qinqing1984/archive/2016/11/24/214439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RSA加解密的证明http://www.kffa.tw/qinqing1984/archive/2016/11/18/214419.html春秋十二?/dc:creator>春秋十二?/author>Fri, 18 Nov 2016 09:05:00 GMThttp://www.kffa.tw/qinqing1984/archive/2016/11/18/214419.htmlhttp://www.kffa.tw/qinqing1984/comments/214419.htmlhttp://www.kffa.tw/qinqing1984/archive/2016/11/18/214419.html#Feedback0http://www.kffa.tw/qinqing1984/comments/commentRss/214419.htmlhttp://www.kffa.tw/qinqing1984/services/trackbacks/214419.html法描述
    
   随机选择两个大的素数 p、q Q且p ≠ qQ计n = pq、r = (p-1)(q-1)Q依Ƨ拉定理Qr即ؓ与n互质的素C敎ͼ选择一个小于r的整数eQ即加密指数Q,求得e关于模r的逆元dQ即解密指数Q,则{nQe}为公钥、{nQd}为私钥;Ҏ模的逆元性质有ed ≡ 1 (mod r)Q设m为明文,则加密运ؓm^e ≡ c (mod n)Q?c即ؓ密文Q则解密q程 c^d ≡ m (mod n)?br />   证明会用到费马小定理Q即 若y为素Cx不ؓy的倍数Q??x^(y-1) ≡ 1 (mod y)Q费马小定理的证明需先证明欧拉定理,此处略)。符?#8801;表示同余Q^表示q?/font>Q|表示整除Q?表示怹?br />
法证明
 W一U证明途径   
   ?ed ≡ 1 (mod (p-1)(q-1))Qo ed = k(p-1)(q-1) + 1Q其?k 是整?br />   ?c^d = (m^e)^d = m^(ed) = m^(k(p-1)(q-1)+1)
   1.若m不是p的倍数Q也不是q的倍数
      ?m^(p-1) ≡ 1 (mod p) (贚w定?
         => m^(k(p-1)(q-1)) ≡ 1 (mod p)
      m^(q-1) ≡ 1 (mod q) (贚w定?
         => 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的倍数Q但不是q的倍数
      ?m^(q-1) ≡ 1 (mod q) (贚w定?
         => 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的倍数Q但不是p的倍数Q证明同?br />
   4.若m同ؓp和q的倍数?br />      ?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)

 W二U证明途径
   先证明m^ed ≡ m (mod p)恒成?br />   1.若p为m的因子,则p | m^ed - m昄成立Q即m^ed ≡ m (mod p)
   2.若p不ؓm的因子,令ed = k(p-1)(q-1) + 1Q则 m^(ed-1) - 1 = m^(k(p-1)(q-1)) - 1
       m^(p-1) ≡ 1 (mod p) (贚w定?/span>)
        => 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)Q即m^ed ≡ m (mod n)
   又因 c^d = m^e^d = m^(ed)
   ?c^d ≡ m (mod n)Q证?br />   
ȝ
 W二U比W一U简单直观,以上证明途径对RSAU钥{֐与验{֐样适合?img src ="http://www.kffa.tw/qinqing1984/aggbug/214419.html" width = "1" height = "1" />

]]>Shell应用Q?0Q:支持开源库~译的Makefilehttp://www.kffa.tw/qinqing1984/archive/2016/10/19/214345.html春秋十二?/dc:creator>春秋十二?/author>Wed, 19 Oct 2016 07:11:00 GMThttp://www.kffa.tw/qinqing1984/archive/2016/10/19/214345.htmlhttp://www.kffa.tw/qinqing1984/comments/214345.htmlhttp://www.kffa.tw/qinqing1984/archive/2016/10/19/214345.html#Feedback0http://www.kffa.tw/qinqing1984/comments/commentRss/214345.htmlhttp://www.kffa.tw/qinqing1984/services/trackbacks/214345.html脚本源码

   ׃很多应用目依赖诸多W三方开源库Q这些开源库各有不同的核心目录、库目标和输Z|,q里的核心目录是?span style="color: red;">仅生so?/span>的工E目录,库目标是?span style="color: red;">仅生so?/span>的make目标Q输Z|是相对于核心目录的Q但不必是子目录Q可?.来回溯到父目录的某位|,更高层目录的位置Q依ơ类推。ؓ了统一支持它们Q用了一些技巧,详见CZ脚本如下
 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)

实现技?/strong>
   1Q?作ؓ分隔W,所分隔?个域依次为核心目录、库目标、输Z|;使用awk来获取各域,分别为dir、aim和outQ在q行q程中,值dir一定非I,而aim为空则表C默认目标,out为空表示输出位置即ؓdir目录?br />   2Qcopy为命令变量,功能为每当一个库~译完成后,输出的so库拷贝到output下,q保持Y链接Q对于有的开源库Q需在编译前Q用对应的选项来调用configureQ其生成so库?br />   3Qؓ了重用代码,定义了MAKE_SUBDIR命o包,参数变量为is_cpQ当is_cp?Ӟ表示当前~译的是依赖库,否则是主E序?nbsp;
   4Qthirdlib和coremodZ赖文Ӟ使用了双冒号规则Q这样一来,只要在thirdlib中加入新的依赖库Q指定核心目录、库目标和输Z|即可,其它地方不用攏V?img src ="http://www.kffa.tw/qinqing1984/aggbug/214345.html" width = "1" height = "1" />

]]>Shell应用Q?Q:自动化批量编?/title><link>http://www.kffa.tw/qinqing1984/archive/2016/09/28/214307.html</link><dc:creator>春秋十二?/dc:creator><author>春秋十二?/author><pubDate>Wed, 28 Sep 2016 03:04:00 GMT</pubDate><guid>http://www.kffa.tw/qinqing1984/archive/2016/09/28/214307.html</guid><wfw:comment>http://www.kffa.tw/qinqing1984/comments/214307.html</wfw:comment><comments>http://www.kffa.tw/qinqing1984/archive/2016/09/28/214307.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kffa.tw/qinqing1984/comments/commentRss/214307.html</wfw:commentRss><trackback:ping>http://www.kffa.tw/qinqing1984/services/trackbacks/214307.html</trackback:ping><description><![CDATA[<div><span style="font-size: 12pt"><strong>脚本概述</strong></span><br />   当需要在很多Q比如几十至几百Q台机器上编译同一E序Ӟ如果一个个地手工拷贝源码、再~译Q那么效率就很低Qؓ了能大量节省手工、ƈ行地~译Q因此写了一个脚本,该脚本基于自动化脚本语言expectQexpectZtclQ实玎ͼ基本原理是针Ҏ个远E主机,创徏一个子q程Q在该子q程内先调用scp拯源码到远E主机,再用sshd到远E主机、发送cd、configure和make命oQ交互期间的命o输出多用正则分析Q最l的~译输出保存到当前目录output子目录下。其命o行参数说明如下:<br />   <span style="widows: 2; text-transform: none; background-color: #ffffff; font-style: normal; text-indent: 0px; display: inline !important; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: #4b4b4b; font-size: 13px; font-weight: normal; word-spacing: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px">●</span> W?参数E主机配|文Ӟ一个多行文本文Ӟ每行格式为IP 用户?密码Q空格符分隔Q支?注释?br />   <span style="widows: 2; text-transform: none; background-color: #ffffff; font-style: normal; text-indent: 0px; display: inline !important; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: #4b4b4b; font-size: 13px; font-weight: normal; word-spacing: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px">●</span> W?参数为本C机源码目录:要求该目录存在Makefile和configure文g?br />   <span style="widows: 2; text-transform: none; background-color: #ffffff; font-style: normal; text-indent: 0px; display: inline !important; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: #4b4b4b; font-size: 13px; font-weight: normal; word-spacing: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px">●</span> W?参数E主机目标目录:用于存放源码的位|?br /><br /><span style="font-size: 12pt"><strong>脚本实现</strong></span><br />   <strong><a id="copy_file">拯源码</a></strong></div> <div align="center"></div> <div align="center"> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"> <div align="left"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080"> 1</span><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><span style="color: #000000">proc </span><span style="color: #800000"><strong>copy_file</strong></span><span style="color: #000000"> {host user srcdir dstdir passwd {</span><span style="color: #0000ff">to</span><span style="color: #000000"> </span><span style="color: #000000">10</span><span style="color: #000000">} } {<br /></span><span style="color: #008080"> 2</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> [catch </span><span style="color: #000000">"</span><span style="color: #000000">spawn scp -rq $srcdir $user@$host:$dstdir</span><span style="color: #000000">"</span><span style="color: #000000"> msg] {<br /></span><span style="color: #008080"> 3</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        send_error </span><span style="color: #000000">"</span><span style="color: #000000">failed to spawn scp: $msg\n</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080"> 4</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #0000ff">exit</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000"><br /></span><span style="color: #008080"> 5</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080"> 6</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    <br /></span><span style="color: #008080"> 7</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    </span><span style="color: #0000ff">set</span><span style="color: #000000"> timeout $</span><span style="color: #0000ff">to</span><span style="color: #000000"><br /></span><span style="color: #008080"> 8</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    </span><span style="color: #ff0000">expect_after eof</span><span style="color: #000000"> { <br /></span><span style="color: #008080"> 9</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        send_error </span><span style="color: #000000">"</span><span style="color: #000000">$host scp died unexpectedly\n</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080">10</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #0000ff">exit</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000"><br /></span><span style="color: #008080">11</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080">12</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    expect {<br /></span><span style="color: #008080">13</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #000000">"</span><span style="color: #000000">(yes/no)?</span><span style="color: #000000">"</span><span style="color: #000000"> { send </span><span style="color: #000000">"</span><span style="color: #000000">yes\r</span><span style="color: #000000">"</span><span style="color: #000000">; exp_continue }<br /></span><span style="color: #008080">14</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #000000">-</span><span style="color: #000000">re </span><span style="color: #000000">"</span><span style="color: #000000">(?:P|p)assword:</span><span style="color: #000000">"</span><span style="color: #000000"> { send </span><span style="color: #000000">"</span><span style="color: #000000">$passwd\r</span><span style="color: #000000">"</span><span style="color: #000000"> }<br /></span><span style="color: #008080">15</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        timeout { do_timeout </span><span style="color: #000000">"</span><span style="color: #000000">$host scp</span><span style="color: #000000">"</span><span style="color: #000000"> }<br /></span><span style="color: #008080">16</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080">17</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080">18</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    expect {<br /></span><span style="color: #008080">19</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #ff0000">full_buffer</span><span style="color: #000000"> { exp_continue }<br /></span><span style="color: #008080">20</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />       </span><span style="color: #ff0000"> timeou</span><span style="color: #ff0000">t</span><span style="color: #000000"> { exp_continue }<br /></span><span style="color: #008080">21</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        eof <br /></span><span style="color: #008080">22</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080">23</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />}</span></div></div></div> <div>   W?行调用spawn命o执行scp命oQƈ用catch捕捉错误Q当执行成功后,W?2行用expect{待q端输出Q超旉认ؓ10U)Q第13?4行自动输入用户名和密码,当过E中|络q接断开Ӟ会匹配到W?行的eofQ当输出完成q接关闭Ӟ会匹配到W?1行的eofQ如果输出太多超qexpect内部的bufferӞ会匹配到W?9行的full_bufferQ这里由于ؓ了提高效率,使用了静默方式的scpQ因些实际会匚w到第20行的timeoutQ不匹配到哪种情况Q都要l直到eof?br /> <br />   <strong>执行~译</strong></div> <div align="center"></div> <div align="center"></div> <div align="center"> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"> <div align="left"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080"> 1</span><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><span style="color: #000000">proc </span><span style="color: #800000"><strong>do_make</strong></span><span style="color: #000000"> {host user passwd subdir {</span><span style="color: #0000ff">to</span><span style="color: #000000"> </span><span style="color: #000000">10</span><span style="color: #000000">} } {<br /></span><span style="color: #008080"> 2</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> [catch {spawn ssh $user@$host} msg ] {<br /></span><span style="color: #008080"> 3</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        send_error </span><span style="color: #000000">"</span><span style="color: #000000">failed to spawn ssh: $msg\n</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080"> 4</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #0000ff">exit</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000"><br /></span><span style="color: #008080"> 5</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080"> 6</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    <br /></span><span style="color: #008080"> 7</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    </span><span style="color: #0000ff">set</span><span style="color: #000000"> timeout $</span><span style="color: #0000ff">to</span><span style="color: #000000"><br /></span><span style="color: #008080"> 8</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    expect_after eof { <br /></span><span style="color: #008080"> 9</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        send_error </span><span style="color: #000000">"</span><span style="color: #000000">$host ssh died unexpectedly\n</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080">10</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #0000ff">exit</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000"><br /></span><span style="color: #008080">11</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080">12</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    <br /></span><span style="color: #008080">13</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    expect {  <br /></span><span style="color: #008080">14</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #000000">"</span><span style="color: #000000">*yes/no</span><span style="color: #000000">"</span><span style="color: #000000"> { send </span><span style="color: #000000">"</span><span style="color: #000000">yes\r</span><span style="color: #000000">"</span><span style="color: #000000">; exp_continue }<br /></span><span style="color: #008080">15</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #000000">-</span><span style="color: #000000">re </span><span style="color: #000000">"</span><span style="color: #000000">(?:P|p)assword:</span><span style="color: #000000">"</span><span style="color: #000000"> { send </span><span style="color: #000000">"</span><span style="color: #000000">$passwd\r</span><span style="color: #000000">"</span><span style="color: #000000"> }  <br /></span><span style="color: #008080">16</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        timeout { do_timeout </span><span style="color: #000000">"</span><span style="color: #000000">$host ssh</span><span style="color: #000000">"</span><span style="color: #000000"> }<br /></span><span style="color: #008080">17</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }  <br /></span><span style="color: #008080">18</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />   </span><span style="color: #ff0000"> wait_cmd $spawn_id passwd</span><span style="color: #000000"><br /></span><span style="color: #008080">19</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080">20</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    send </span><span style="color: #000000">"</span><span style="color: #ff0000">cd</span><span style="color: #000000"> $subdir\r</span><span style="color: #000000">"</span><span style="color: #000000">  <br /></span><span style="color: #008080">21</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    wait_cmd $spawn_id cd<br /></span><span style="color: #008080">22</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    <br /></span><span style="color: #008080">23</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    send </span><span style="color: #000000">"</span><span style="color: #ff0000">source configure</span><span style="color: #000000">\r</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080">24</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    wait_cmd $spawn_id configure<br /></span><span style="color: #008080">25</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080">26</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    send </span><span style="color: #000000">"</span><span style="color: #ff0000">make</span><span style="color: #000000">\r</span><span style="color: #000000">"</span><span style="color: #000000">  <br /></span><span style="color: #008080">27</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    wait_cmd $spawn_id make<br /></span><span style="color: #008080">28</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080">29</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    send </span><span style="color: #000000">"</span><span style="color: #000000">exit\r</span><span style="color: #000000">"</span><span style="color: #000000">  <br /></span><span style="color: #008080">30</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    expect eof  <br /></span><span style="color: #008080">31</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />}</span></div></div></div> <div>   关于spawn和expect的解释与上节<a href="#copy_file">拯源码</a>相同Q不同的是依ơ发送命令cd、source configure、makeQ每个命令须{到命o提示W后Q调用自定义函数wait_cmdQ再发下一个,最后发送exit退出ssh、导致连接关闭,匚w到最后一行的eof。对于有的项目源码,可能没有或不用配|,那么configure文g可以不存在或内容为空Q如果不存在D报错也没关系Q不影响makeQ如果configure出错Q那么make也会出错。这里用source是ؓ了配置在当前shell中生效?br />   <br />   <strong>d@?/strong></div> <div align="center"></div> <div align="center"></div> <div align="center"> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"> <div align="left"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080"> 1</span><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><span style="color: #0000ff">set</span><span style="color: #000000"> f [open $file r]<br /></span><span style="color: #008080"> 2</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">set</span><span style="color: #000000"> curtime [clock seconds]<br /></span><span style="color: #008080"> 3</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080"> 4</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #ff0000">log_user </span><span style="color: #ff0000">0</span><span style="color: #000000"><br /></span><span style="color: #008080"> 5</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">set</span><span style="color: #000000"> s {[:blank:]}<br /></span><span style="color: #008080"> 6</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">set</span><span style="color: #000000"> pattern </span><span style="color: #000000">"</span><span style="color: #000000">^(\[^#$s]+)\[$s]+(\[^$s]+)\[$s]+(\[^$s]+)</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080"> 7</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080"> 8</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">while</span><span style="color: #000000"> { [gets $f line] !</span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000"> } {<br /></span><span style="color: #008080"> 9</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> { ![</span><span style="color: #ff0000">regexp</span><span style="color: #000000"> $pattern [</span><span style="color: #0000ff">string</span><span style="color: #000000"> trimleft $line] ? host user passwd] } {<br /></span><span style="color: #008080">10</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        continue<br /></span><span style="color: #008080">11</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080">12</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    send_user </span><span style="color: #000000">"</span><span style="color: #000000">$host $user $passwd\n</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080">13</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> { ![fork] } {<br /></span><span style="color: #008080">14</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        <br /></span><span style="color: #008080">15</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #0000ff">set</span><span style="color: #000000"> filename output</span><span style="color: #000000">/</span><span style="color: #000000">${host}_[clock format $curtime </span><span style="color: #000000">-</span><span style="color: #000000">format %y.%m.%d_%H.%M.%S].log<br /></span><span style="color: #008080">16</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        log_file </span><span style="color: #000000">-</span><span style="color: #000000">noappend </span><span style="color: #ff0000">-</span><span style="color: #ff0000">a</span><span style="color: #000000"> $filename<br /></span><span style="color: #008080">17</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080">18</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        copy_file $host $user $srcdir $dstdir $passwd </span><span style="color: #000000">30</span><span style="color: #000000"><br /></span><span style="color: #008080">19</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        do_make $host $user $passwd $subdir </span><span style="color: #000000">30</span><span style="color: #000000"><br /></span><span style="color: #008080">20</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" /><br /></span><span style="color: #008080">21</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        send_user </span><span style="color: #000000">"</span><span style="color: #000000">$host finish\n</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #008080">22</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />        </span><span style="color: #0000ff">exit</span><span style="color: #000000"><br /></span><span style="color: #008080">23</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />    }<br /></span><span style="color: #008080">24</span><span style="color: #000000"><img align="top" src="http://www.kffa.tw/images/OutliningIndicators/None.gif" alt="" />}</span></div></div></div> <div>   打开q程L配置文gQ读取每一行直到文件尾Q忽略注释行Q用正则提取IP、用户名和密码,创徏子进E,按IP和当前时间命名log文gQ由于前面调用log_user 0关闭了控制台输出Q因此ؓ了能记录输出到日志文Ӟ一定要?a选项Q,最后调用函数copy_file和do_make?br />   <br />   完整脚本下蝲Q?a href="/Files/qinqing1984/autobuild.zip">autobuild.zip</a></div><img src ="http://www.kffa.tw/qinqing1984/aggbug/214307.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.kffa.tw/qinqing1984/" target="_blank">春秋十二?/a> 2016-09-28 11:04 <a href="http://www.kffa.tw/qinqing1984/archive/2016/09/28/214307.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一U拦截Linux动态库API的方法及装置http://www.kffa.tw/qinqing1984/archive/2016/08/25/214213.html春秋十二?/dc:creator>春秋十二?/author>Thu, 25 Aug 2016 03:10:00 GMThttp://www.kffa.tw/qinqing1984/archive/2016/08/25/214213.htmlhttp://www.kffa.tw/qinqing1984/comments/214213.htmlhttp://www.kffa.tw/qinqing1984/archive/2016/08/25/214213.html#Feedback0http://www.kffa.tw/qinqing1984/comments/commentRss/214213.htmlhttp://www.kffa.tw/qinqing1984/services/trackbacks/214213.html描述

   拦截Linux动态库API的常规方法,是基于动态符号链接覆盖技术实现的Q基本步骤是
    1. 重命名要拦截的目标动态库?br />    2. 创徏新的同名动态库Q定义要拦截的同名APIQ在API内部调用原动态库对应的API。这里的同名是指与重命名前动态库前的名称相同?br />    显而易见,如果要拦截多个不同动态库中的APIQ那么必d建多个对应的同名动态库Q这样一来不仅繁琐低效,q必被优先链接到客户二q制E序中(Ҏ动态库链接原理Q对重复ABIW号的处理是选择优先链接的那个动态库Q?另外在钩子函数的实现中,若某调用链调用到了原APIQ则会引h循环而崩溃。本Ҏ通过直接修改ELF文g中的动态库API入口表项Q解决了常规Ҏ的上q问题?

特点
   1. 不依赖于动态库链接序?br />    2. 能拦截多个不同动态库中的多个API?br />    3. 支持q行时动态链接的拦截?br />    4. 钩子函数内的实现体,若调用到原APIQ则不会d@环?


实现
   拦截映射?/strong>
      Z支持特点2?Q徏立了一个拦截映表Q这个映表?U。第1UؓELF文g到它的API钩子映射表,键ؓELF文g句柄QgؓAPI钩子映射表;W?UؓAPI到它的钩子函数映表Q键为API名称Qgؓ包含最老原函数地址和最新钩子函数地址的结构体Q如下图
      当最先打开ELF文g成功Ӟ会在W?U映表中插入记录;反之当最后关闭同一ELF文gӞ׃从中U除对应的记录。当W一ơ挂钩动态库APIӞ׃在第2U映表插入记录Q反之卸钩同一APIӞ׃从中删除对应的记录?br />
   计算ELF文g的映像基地址
      计算映像基地址是ؓ了得到ELF中动态符可和重定位链接q程表的内容Q因些表的位|都是相对于基地址的偏U量Q该法在打开ELF文g时执行,如下?br />
      EXE文g为可执行文gQDYN文g为动态库。对于可执行文gQ映基地址为可执行装蝲D늚虚拟地址Q对于动态库Q可通过MAPI的地址减去它的偏移量得刎ͼMAPI的地址可通过调用libdl.so库API dlsym得到Q偏U量通过查询动态链接符可得到?br />
   打开ELF文g
      Z支持特点2x截不同动态库的多个APIQ节省每ơ挂钩API前要打开q读文g的开销Q独立提供了打开ELF文g的接口操作,程如下?br />
      若输入ELF文g名ؓI,则表C打开当前q程的可执行文gQ此时要从伪文gpȝ/proc/self/exed文g路径名,以正调用系l调用open。当同一ELF文g被多ơ打开Ӟ只须递增l构elf的引用计数?br />
   挂钩API
      当打开ELF文g后,可挂钩API了,程如下?br />
      当第一ơ挂钩时Q需要保存原函数以供后面協RQ第二次以后l箋挂钩同一APIӞ更新钩子函数Q但原函C变?nbsp;  
   
   協RAPI
      当打开ELF文g后,可協RAPI了,程如下?br />

   关闭ELF文g
      因ؓ提供了打开ELF文g的接口操作,所以得配有关闭ELF文g的接口操作。当不需要挂钩API的时候,可以关闭ELF文g了,程如下?br />


q行时动态拦截装|?/strong>
   在初始化模块中打开当前可执行文Ӟ挂钩libdl.so库的API dlopen和dlsymQ在转换模块中,按动态库句柄和API名称在拦截映表中查N子函敎ͼ若找到则q回钩子函数Q否则返回调用dlsym的结果;在销毁模块中Q卸钩dlopen和dlsym?br /> 当动态库被进E加载的时候,会调用初始化模块Q当被进E卸载或q程退出的时候,会调用销毁模块;当通过dlsym调用APIӞ则会在dlsym的钩子函C调用转换模块。通过环境变量LD_PRELOAD动态库libhookapi.so设ؓ预加载库Q这样就能拦截到所有进E对dlopen及dlsym的调用,q而拦截到已挂钩动态库API的调用?img src ="http://www.kffa.tw/qinqing1984/aggbug/214213.html" width = "1" height = "1" />

]]>一U统计云查询黑文件的Ҏ及系l?/title><link>http://www.kffa.tw/qinqing1984/archive/2016/08/25/214212.html</link><dc:creator>春秋十二?/dc:creator><author>春秋十二?/author><pubDate>Thu, 25 Aug 2016 03:10:00 GMT</pubDate><guid>http://www.kffa.tw/qinqing1984/archive/2016/08/25/214212.html</guid><wfw:comment>http://www.kffa.tw/qinqing1984/comments/214212.html</wfw:comment><comments>http://www.kffa.tw/qinqing1984/archive/2016/08/25/214212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kffa.tw/qinqing1984/comments/commentRss/214212.html</wfw:commentRss><trackback:ping>http://www.kffa.tw/qinqing1984/services/trackbacks/214212.html</trackback:ping><description><![CDATA[<strong style="font-size: 14pt;">描述</strong><br />    云查杀q_以nginx作ؓ反向代理服务器,作ؓ安全l端与云查询服务的桥梁。当安全l端需要查询黑文gӞHTTPh及其响应都会l过nginxQؓ了获取ƈl计一?4时查询的黑文g数量Q就得先截获l过nginx的HTTP响应Q再做数据分析。截获HTTP数据有多种ҎQؓ了简单高效,q里使用了挂接HTTPqo模块的方法,另外Z不媄响nginx本n的IO处理Q将HTTP响应实体发送到另一个进E即l计服务Q由l计服务来接收ƈ分析HTTP响应Q架构如下图 <div align="center"><img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/kstat_schema.png" width="599" height="289" /></div>    l计服务?个接收线E和1个存储线E构成,其中接收U程负责接收从nginxqo模块发来的HTTP响应实体Q解析它q提取黑文gMD5Q加入共享环形队列;而存储线E从׃n环Ş队列Ud黑文件MD5Q插入到临时内存映射文gQ于每天定时同步到磁盘文件?br /> <br /> <strong style="font-size: 14pt">特点</strong><br />    q种架构减少了nginx IO延迟Q保证了nginx的稳定高效运行,从而不影响用户的业务运行;本地q接为非d的,支持了统计服务的独立q行与升U?br /> <br /> <strong style="font-size: 14pt">实现</strong><br />    <strong style="font-size: 12pt">nginxqo模块</strong><br />       该流E运行在nginx工作q程?br /> <div align="center"><img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/kstat_ngxmod.png" width="279" height="802" /></div>       ׃nginx采用了异步IO机制Q因此仅当截获到HTTP响应实体也就是有数据l过Ӟ才有后面的操作;若没有数据,则什么也不用做。这里每ơ发送前先判断是否连接了l计服务Q是Z支持l计服务的独立运行与升Q换句话_不管l计服务是否q行或崩溃,都不影响nginx的运行?br /> <br /> <strong style="font-size: 12pt">l计服务</strong><br />    <strong>接收U程</strong><br />       q里的接收线E也是ȝE?br /> <div align="center"><img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/kstat_receiver.png" width="575" height="592" /></div>    <hr width="97%" />    <strong>存储U程</strong><br />       存储U程为另一个工作线E?br /> <div align="center"><img border="0" alt="" src="http://www.kffa.tw/images/cppblog_com/qinqing1984/kstat_storer.png" width="492" height="644" /></div>       同步文g定时器的旉间隔要比新徏文g定时器的短,׃定时器到期的事g处理是一U异步执行流Q所以将它们当做q行Q与“从q头移出黑文gMD5”操作d了同一水^方向?img src ="http://www.kffa.tw/qinqing1984/aggbug/214212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.kffa.tw/qinqing1984/" target="_blank">春秋十二?/a> 2016-08-25 11:10 <a href="http://www.kffa.tw/qinqing1984/archive/2016/08/25/214212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一U根据dentry获取l对路径名的实现Ҏhttp://www.kffa.tw/qinqing1984/archive/2016/08/24/214229.html春秋十二?/dc:creator>春秋十二?/author>Wed, 24 Aug 2016 11:22:00 GMThttp://www.kffa.tw/qinqing1984/archive/2016/08/24/214229.htmlhttp://www.kffa.tw/qinqing1984/comments/214229.htmlhttp://www.kffa.tw/qinqing1984/archive/2016/08/24/214229.html#Feedback0http://www.kffa.tw/qinqing1984/comments/commentRss/214229.htmlhttp://www.kffa.tw/qinqing1984/services/trackbacks/214229.html
   1. 先获取dentry所属文件系l对应的挂蝲点,基本原理是遍历文件系lvfsmount树,扑ֈ与dentry有相同超U块的vfsmountQ实现如?
 1extern spinlock_t *vfsmnt_lock;
 2
 3static struct vfsmount* next_mnt(struct vfsmount *p, struct vfsmount *root)
 4{
 5    struct list_head *next = p->mnt_mounts.next;
 6    if (next == &p->mnt_mounts) {
 7        while (1{
 8            if (p == root)
 9                return NULL;
10            next = p->mnt_child.next;
11            if (next != &p->mnt_parent->mnt_mounts)
12                break;
13            p = p->mnt_parent;
14        }

15    }

16    return list_entry(next, struct vfsmount, mnt_child);
17}

18
19static struct vfsmount* get_dentry_mnt(struct dentry *dentry)
20{
21    struct vfsmount *p, *root;
22    struct fs_struct *fs = current->fs;            
23
24    read_lock(&fs->lock);
25    root = fs->root.mnt;
26    mntget(root);
27    read_unlock(&fs->lock);
28
29    spin_lock(vfsmnt_lock);
30    for(p = root; p; p = next_mnt(p,root)){
31        if(p->mnt_sb == dentry->d_sb){
32            mntget(p);
33            break;    
34        }

35    }

36    spin_unlock(vfsmnt_lock);
37
38    mntput(root);
39    
40    return p;
41}
   next_mnt函数实现?span style="color: red;">先根遍历法,遍历以root为根的文件系l挂载点Qp为遍历过E中的当前结点,q回p的下一个挂载点Qvfsmnt_lock可通过内核函数kallsyms_on_each_symbol或kallsyms_lookup_name查找获得?br />
   2. 再调用内核函数d_pathQ接口封装如?br />
 1char* get_dentry_path(struct dentry *dentry,char *buf,int len)
 2{
 3    char *= "";    
 4    struct vfsmount *mnt = get_dentry_mnt(dentry);
 5    
 6    if(mnt){
 7        struct path ph = {.dentry = dentry, .mnt = mnt};
 8        p = d_path(&ph,buf,len);
 9        if(IS_ERR(p))
10            p = "";
11        mntput(mnt);
12    }

13    
14    return p;
15}


]]>
<var id="pl157"></var>
<cite id="pl157"><noframes id="pl157"><thead id="pl157"><strike id="pl157"><progress id="pl157"></progress></strike></thead>
<var id="pl157"><span id="pl157"></span></var>
<var id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></var>
<cite id="pl157"><video id="pl157"></video></cite><ins id="pl157"></ins>
<cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<cite id="pl157"><span id="pl157"></span></cite><var id="pl157"><video id="pl157"><thead id="pl157"></thead></video></var>
<cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<var id="pl157"><span id="pl157"><menuitem id="pl157"></menuitem></span></var><cite id="pl157"><span id="pl157"><var id="pl157"></var></span></cite>
<var id="pl157"><span id="pl157"></span></var>
<ins id="pl157"><span id="pl157"></span></ins>
<ins id="pl157"><video id="pl157"></video></ins><ins id="pl157"></ins>
<var id="pl157"></var> <cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<ins id="pl157"></ins>
<ins id="pl157"></ins>
<var id="pl157"></var>
<cite id="pl157"></cite><del id="pl157"></del>
<cite id="pl157"><video id="pl157"></video></cite>
<menuitem id="pl157"></menuitem>
<var id="pl157"></var>
<menuitem id="pl157"></menuitem>
<cite id="pl157"></cite>
<progress id="pl157"><ruby id="pl157"><th id="pl157"></th></ruby></progress><var id="pl157"></var>
<ins id="pl157"><noframes id="pl157"><var id="pl157"></var>
<ins id="pl157"><span id="pl157"></span></ins><cite id="pl157"></cite>
<cite id="pl157"><span id="pl157"></span></cite>
3׬Ǯ
<var id="pl157"></var>
<cite id="pl157"><noframes id="pl157"><thead id="pl157"><strike id="pl157"><progress id="pl157"></progress></strike></thead>
<var id="pl157"><span id="pl157"></span></var>
<var id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></var>
<cite id="pl157"><video id="pl157"></video></cite><ins id="pl157"></ins>
<cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<cite id="pl157"><span id="pl157"></span></cite><var id="pl157"><video id="pl157"><thead id="pl157"></thead></video></var>
<cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<var id="pl157"><span id="pl157"><menuitem id="pl157"></menuitem></span></var><cite id="pl157"><span id="pl157"><var id="pl157"></var></span></cite>
<var id="pl157"><span id="pl157"></span></var>
<ins id="pl157"><span id="pl157"></span></ins>
<ins id="pl157"><video id="pl157"></video></ins><ins id="pl157"></ins>
<var id="pl157"></var> <cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<ins id="pl157"></ins>
<ins id="pl157"></ins>
<var id="pl157"></var>
<cite id="pl157"></cite><del id="pl157"></del>
<cite id="pl157"><video id="pl157"></video></cite>
<menuitem id="pl157"></menuitem>
<var id="pl157"></var>
<menuitem id="pl157"></menuitem>
<cite id="pl157"></cite>
<progress id="pl157"><ruby id="pl157"><th id="pl157"></th></ruby></progress><var id="pl157"></var>
<ins id="pl157"><noframes id="pl157"><var id="pl157"></var>
<ins id="pl157"><span id="pl157"></span></ins><cite id="pl157"></cite>
<cite id="pl157"><span id="pl157"></span></cite>
<var id="pl157"></var>
<cite id="pl157"><noframes id="pl157"><thead id="pl157"><strike id="pl157"><progress id="pl157"></progress></strike></thead>
<var id="pl157"><span id="pl157"></span></var>
<var id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></var>
<cite id="pl157"><video id="pl157"></video></cite><ins id="pl157"></ins>
<cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<cite id="pl157"><span id="pl157"></span></cite><var id="pl157"><video id="pl157"><thead id="pl157"></thead></video></var>
<cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<var id="pl157"><span id="pl157"><menuitem id="pl157"></menuitem></span></var><cite id="pl157"><span id="pl157"><var id="pl157"></var></span></cite>
<var id="pl157"><span id="pl157"></span></var>
<ins id="pl157"><span id="pl157"></span></ins>
<ins id="pl157"><video id="pl157"></video></ins><ins id="pl157"></ins>
<var id="pl157"></var> <cite id="pl157"><video id="pl157"><menuitem id="pl157"></menuitem></video></cite>
<ins id="pl157"></ins>
<ins id="pl157"></ins>
<var id="pl157"></var>
<cite id="pl157"></cite><del id="pl157"></del>
<cite id="pl157"><video id="pl157"></video></cite>
<menuitem id="pl157"></menuitem>
<var id="pl157"></var>
<menuitem id="pl157"></menuitem>
<cite id="pl157"></cite>
<progress id="pl157"><ruby id="pl157"><th id="pl157"></th></ruby></progress><var id="pl157"></var>
<ins id="pl157"><noframes id="pl157"><var id="pl157"></var>
<ins id="pl157"><span id="pl157"></span></ins><cite id="pl157"></cite>
<cite id="pl157"><span id="pl157"></span></cite>