編輯本段SC命令功能
            SC命令是XP系統中功能強大的DOS命令,SC命令能與“服務控制器”和已安裝設備進行通訊。SC命令的功能有
            1、SC可以 檢索和設置有關服務的控制信息。可以使用 SC.exe 來測試和調試服務程序。
            2、可以設置存儲在注冊表中的服務屬性,以控制如何在啟動時啟動服務應用程序,以及如何將其作為后臺程序運行。即更改服務的啟動狀態。
            3、SC 命令還可以用來刪除系統中的無用的服務。(除非對自己電腦中的軟硬件所需的服務比較清楚,否則不建議刪除任何系統服務,尤其是基礎服務)
            4、SC命令 的參數可以配置指定的服務,檢索當前服務的狀態,也可以停止和啟動服務(功能上類似NET STOP/START命令,但SC速度更快且能停止更多的服務)。
            5、可以創建批處理文件來調用不同的 SC 命令,以自動啟動或關閉服務序列。
            SC.exe 提供的功能類似于“控制面板”中“管理工具”項中的“服務”。
          編輯本段SC命令列表及格式
            SC命令不能單獨使用,必須和其它的命令結合起來一起使用。一共有24個,如下所示
            sc boot sc config sc continue sc control sc create sc delete sc descrīption sc enumdepend
            sc failure sc getdisplayname sc getkeyname sc interrogate sc lock sc pause sc qc
            sc qdescrīption sc qfailure sc query sc queryex sc querylock sc sdset sc sdshow
            sc start sc stop
            在命令行中直接輸入SC會顯示SC命令的幫助信息,直接輸入以上24個命令除sc query 和 sc queryex之外都將顯示該SC命令的幫助信息。(輸入sc query和sc queryex會顯示當前系統中正在運行的所有服務的詳細信息,但sc queryex比sc query顯示的信息多出來兩項:PID和FLAGS)
            SC命令的格式:SC [Servername] command Servicename [Optionname= Optionvalues]
            Servername:指定服務所在的遠程服務器的名稱。名稱必須采用通用命名約定 (UNC) 格式(“\\myserver”)。要在本地運行SC.exe,請忽略此參數。
            command :即以上提到的那24個命令(SC后面的那個,如query,start,stop,create,config等)
            Servicename:服務名,也就是要配置的那個服務的名字,例如你要啟動一個服務你就輸入sc start +你要啟動的服務名。(注意這里的服務名不是服務的顯示名稱,而是服務名稱,這個服務名稱可以在系統管理工具下的服務中可以看到,例如在服務中雙擊DHCP Client可以看到其服務名稱是Dhcp,而那個DHCP Client是顯示名稱,可以用sc命令來更改一個服務的顯示名稱)
            Optionname= Optionvalues:是選項名和選項的值。
            例如你要在開機是系統自動加載themes服務,你可以使用sc config themes start= auto,后面的start就是選項,auto是選項的值。(注意=號后面有個空格,所有的使用選項的在=號后面都要加個空格再加上選項值)
          編輯本段SC命令的用法
            下面給出每個命令詳細的用法
            1、sc boot
            表明最近的啟動是否應該保存為上次已知的正確配置。
            語法
            Sc [ServerName] boot [{bad | OK}]
            參數
            ServerName:上面已經介紹,在此不在累述(下同)
            [{bad | OK}]
            指定最近的啟動是否錯誤或它是否應該保存為上次已知的正確啟動配置。
            下面的示例顯示了如何使用 sc boot 命令:
            sc boot ok
            sc boot bad
            2、sc config
            修改注冊表和“服務控制管理器”數據庫中服務項目的值。
            語法
            Sc [ServerName] config [ServiceName] [type= {own | share | kernel | filesys | rec | adapt | interacttype= {own | share}}] [start= {boot | system | auto | demand | disabled}] [error= {normal | severe | critical | ignore}] [binpath= BinaryPathName] [group= LoadOrderGroup] [tag= {yes | no}] [depend= dependencies] [obj= {AccountName | ObjectName}] [displayname= DisplayName] [password= Password]
            ServiceName
            指定要操作的服務名。(上面也已經介紹,下文不在累述)
            type= {own | share | kernel | filesys | rec | adapt | interacttype= {own | share}}
            指定服務類型。
            own
            服務以其自身的進程運行。不與其他服務共享可執行文件。這是默認值。
            share
            服務作為共享進程運行。與其他服務共享可執行文件。
            kernel
            驅動程序。
            filesys
            文件系統驅動程序。
            rec
            文件系統識別驅動程序(標識計算機上使用的文件系統)。
            adapt
            適配器驅動程序(標識鍵盤、鼠標、磁盤驅動器這樣的硬件項)。
            interact
            服務可以與桌面交互,接收用戶的輸入。交互服務必須在 LocalSystem 帳戶下運行。該類型必須與 type= own 或 type= shared(例如,type= interact type= own)結合使用。自身使用 type= interact 將會產生參數無效的錯誤。
            start= {boot | system | auto | demand | disabled}
            指定服務的啟動類型。
            boot
            由啟動加載程序加載的設備驅動程序。
            system
            在核心初始化過程中啟動的設備驅動程序。
            auto
            每次計算機重新啟動時都會自動啟動、并且即使無人登錄到計算機也能正常運行的服務。
            demand
            必須手動啟動的服務。如果沒有指定 start=,則此項即為默認值。
            disabled
            不能啟動的服務。要啟動禁用的服務,應將啟動類型更改為其他值。
            error= {normal | severe | critical | ignore}
            如果在啟動過程中,服務啟動失敗,則指定錯誤的嚴重性。
            normal
            將記錄錯誤,并且顯示消息對話框,通知用戶服務啟動失敗。啟動將繼續。這是默認設置。
            severe
            記錄錯誤(如果存在)。計算機嘗試以最新的有效配置重新啟動。這可能導致計算機能夠重新啟動,但服務卻仍然無法運行。
            critical
            記錄錯誤(如果存在)。計算機嘗試以最新的有效配置重新啟動。如果上次已知正確的配置失敗,啟動也將失敗,啟動進程將以停止錯誤而中止。
            ignore
            錯誤已記錄,啟動繼續。記錄錯誤超出在事件ri志的范圍,不再給用戶作出提示。
            binpath= BinaryPathName
            指定指向服務二進制文件的路徑。
            group= LoadOrderGroup
            指定該服務所屬組的名稱。組列表存儲在注冊表的 HKLM\System\CurrentControlSet\Control\ServiceGroupOrder 子項中。默認設置為空值。
            tag= {yes | no}
            指定是否在 CreateService 調用中獲得 TagID。標記僅用于引導啟動或系統啟動驅動程序。
            depend= dependencies
            指定必須在此項服務之前啟動的服務或組的名稱。名稱以正斜杠 (/) 分隔。
            obj= {AccountName | ObjectName}
            指定運行服務將使用的帳戶名,或指定運行驅動程序將使用的 Windows 驅動程序對象名。默認設置為 LocalSystem。
            displayname= DisplayName
            指定一個可以在用戶界面程序中用于為用戶標識服務的友好的、有意義的名稱。例如,一項服務的子項名是對用戶毫無意義的 wuauserv,而顯示的名稱是“自動更新”。
            password= Password
            指定一個密碼。如果使用了非 LocalSystem 的帳戶,則此項是必需的。
            備注
            如果參數及其值之間沒有空格,(例如,是 type= own,而不是 type=own),則操作會失敗。
            示例
            下面的示例顯示了如何使用 sc config 命令:
            sc config NewService binpath= "ntsd -d c:\windows\system32\NewServ.exe"
            3、sc continue
            為了恢復暫停的服務,要給服務發送一個 CONTINUE 控制請求。
            語法
            Sc [ServerName] continue [ServiceName]
            參數
            ServerName:略
            ServiceName:略
            備注
            使用 continue 操作來恢復暫停的服務。
            下面的示例顯示了如何使用 sc continue 命令:
            sc continue tapisrv
            4、sc control
            向服務發送 CONTROL 。
            語法
            sc [ServerName] control [ServiceName] [{paramchange | netbindadd | netbindremove | netbindenable | netbinddisable | UserDefinedControlB}]
            參數
            {paramchange | netbindadd | netbindremove | netbindenable | netbinddisable | UserDefinedControlB}
            指定要發送到服務的控制。
            5、sc create
            在注冊表和“服務控制管理器”中為服務創建子項和項目。
            語法
            Sc [ServerName] create [ServiceName] [type= {own | share | kernel | filesys | rec | adapt | interacttype= {own | share}}] [start= {boot | system | auto | demand | disabled}] [error= {normal | severe | critical | ignore}] [binpath= BinaryPathName] [group= LoadOrderGroup] [tag= {yes | no}] [depend= dependencies] [obj= {AccountName | ObjectName}] [displayname= DisplayName] [password= Password]
            參數:各個參數的作用參見sc config 命令
            下面的示例顯示了如何使用 sc create 命令:
            sc \\myserver create NewService binpath= c:\windows\system32\NewServ.exe
            sc create NewService binpath= c:\windows\system32\NewServ.exe type= share start= auto depend= "+TDI Netbios"
            6、sc delete
            從注冊表中刪除服務子項。如果服務正在運行或者另一個進程有一個該服務的打開句柄,那么此服務將標記為刪除。
            語法
            Sc [ServerName] delete [ServiceName]
            參數:略
            備注
            使用“添加或刪除程序”刪除 DHCP、DNS 或任何其他內置的操作系統服務。“添加或刪除程序”不僅會刪除該服務的注冊表子項,而且還會卸載該服務并刪除其所有的快捷方式。
            下面的示例顯示了如何使用 sc delete 命令:
            sc delete newserv
            7、sc descrīption
            設置服務的描述字符串。
            語法
            Sc [ServerName] descrīption [ServiceName] [Descrīption]
            參數:略
            描述
            為指定服務指定描述。這個描述的內容可以在控制面板-管理工具-服務里通過查看該服務的屬性看到。如果沒有指定字符串,則不會修改該服務的描述。不限制服務描述中可包含的字符數。
            示例
            下面的示例顯示了如何使用 sc descrīption 命令:
            sc descrīption newserv "Runs quality of service control."
            8、sc enumdepend
            枚舉依賴此服務的系統組件,這也可以從控制面板-管理工具-服務里通過查看該服務的屬性中的依存關系選項卡看到(“下面的系統組件依賴此服務”下面的部分)
            語法
            Sc [ServerName] enumdepend [ServiceName] [BufferSize]
            參數
            BufferSize
            以字節為單位指定枚舉緩沖區的大小。默認值為 1024 字節。
            備注
            如果緩沖區不夠大,enumdepend 操作只會部分輸出依存關系,并指定輸出所有依存關系所需的額外緩沖區大小。如果輸出被截斷,請重新運行該操作并指定更大的緩沖區大小。
            下面的示例顯示了如何使用 sc enumdepend 命令:
            sc enumdepend rpcss 5690
            sc enumdepend tapisrv
            9、sc failure
            指定服務失敗時要采取的措施。
            語法
            Sc [ServerName] failure [ServiceName] [reset= ErrorFreePeriod] [reboot= BroadcastMessage] [command= CommandLine] [actions= FailureActionsAndDelayTime]
            參數
            reset= ErrorFreePeriod
            指定沒有失敗的周期長度(單位為秒),此后失敗計數應該重置為 0。這個參數必須與 actions= 參數結合使用。
            reboot= BroadcastMessage
            指定服務失敗時要廣播的消息。
            command= CommandLine
            指定服務失敗時要運行的命令行。有關在失敗時如何運行批處理或 VBS 文件的詳細信息,請參閱“注釋”。
            actions= FailureActionsAndDelayTime
            指定失敗操作及其延遲時間(單位為毫秒),以正斜杠 (/) 隔開。以下操作均有效:run、restart 和 reboot。此參數必須與 reset= 參數結合使用。失敗后不采取任何操作時,請使用 actions= ""。
            備注
            并非所有服務都允許更改其失敗選項。其中一些作為服務集的一部分運行。
            要在失敗時運行批處理文件,請指定 cmd.exeDrive:\FileName.bat 為 command= 參數,其中 Drive:\FileName.bat 是批處理文件的完全合格的名稱。
            要在失敗時運行 VBS 文件,請指定 cscrīpt drive:\myscrīpt.vbs 為 command= 參數,其中 Drive:\myscrīpt.vbs 是腳本文件完全合格的名稱。
            可以將三種不同的操作指定為 actions= 參數,它們將會在服務的第一次、第二次、第三次失敗時使用。
            如果參數及其值之間沒有空格,(例如,是 type= own,而不是 type=own),則操作會失敗。
            下面的示例顯示了如何使用 sc failure 命令:
            sc failure msftpsvc reset= 30 actions= restart/5000
            sc failure dfs reset= 60 command= c:\windows\services\restart_dfs.exe actions= run/5000
            sc failure dfs reset= 60 actions= reboot/30000
            sc failure dfs reset= 60 reboot= "The Distributed File System service has failed.Because of this, the computer will reboot in 30 seconds." actions= reboot/30000
            sc failure myservice reset= 3600 reboot= "MyService crashed -- rebooting machine" command= "%windir%\MyServiceRecovery.exe" actions= restart/5000/run/10000/reboot/60000
            10、sc getdisplayname
            獲得與特定服務關聯的顯示名稱。
            語法
            Sc [ServerName] getdisplayname [ServiceName] [BufferSize]
            參數
            BufferSize
            指定緩沖區大小(以字節為單位)。默認值為 1024 字節。
            下面的示例顯示了如何使用 sc getdisplayname 命令:
            sc getdisplayname clipsrv
            sc getdisplayname tapisrv
            sc getdisplayname sharedaccess
            11、sc getkeyname
            使用特定服務的顯示名稱作為輸入的內容會獲得與其相關聯的項名。
            語法
            sc [ServerName] getkeyname [ServiceDisplayName] [BufferSize]
            參數
            ServiceDisplayName
            指定服務的顯示名稱。
            BufferSize
            指定緩沖區大小(以字節為單位)。默認值為 1024 字節。
            備注
            如果 ServiceDisplayName 包含空格,請使用引號將文本引起來(例如,"Service Display Name")。
            下面的示例顯示了如何使用 sc getkeyname 命令:
            sc getkeyname "remote procedure call (rpc)"
            sc getkeyname "internet connection sharing"
            sc getkeyname clipbook
            12、sc interrogate
            向服務發送一個 INTERROGATE 控制請求。
            語法
            Sc [ServerName] interrogate [ServiceName]
            參數:略
            備注
            向服務發送 INTERROGATE 會導致該服務使用“服務控制管理器”更新其狀態。
            下面的示例顯示了如何使用 sc interrogate 命令:
            sc interrogate sharedaccess
            sc interrogate rpcss
            13、sc lock
            鎖定“服務控制管理器”的數據庫。
            語法
            sc [ServerName] lock
            參數:略
            備注
            鎖定“服務控制管理器”的數據庫會阻止啟動任何服務。如果要確保服務在停止之后不會啟動,請使用這個命令。這可以使您不受干擾地進行一些操作(例如,刪除服務)。
            使用 lock 操作鎖定“服務控制管理器”的數據庫,然后通過鍵入 u 來使數據庫解鎖。也可停止鎖定數據庫的進程。
            下面的示例顯示了如何使用 sc lock 命令:
            sc lock
            14、sc pause
            向服務發送 PAUSE 控制請求。
            語法
            Sc [ServerName] pause [ServiceName]
            參數:略
            備注
            在終止服務之前使用 pause 操作來暫停它。
            并非所有服務都能夠被暫停。
            在暫停時并非所有服務都執行同樣的操作。一些服務繼續為現有客戶端服務,但拒絕接受新的客戶端。其他的會終止對現有客戶端的服務,同時也會拒絕接受新的客戶端。
            下面的示例顯示了如何使用 sc pause 命令:
            sc pause tapisrv
            15、sc qc
            查詢服務的配置信息。
            語法
            Sc [ServerName] qc [ServiceName] [BufferSize]
            參數
            BufferSize
            指定緩沖區大小(以字節為單位)。默認值為 1024 字節。
            備注
            qc 操作可以顯示有關服務的下列信息:
            SERVICE_NAME(服務的注冊表子項名稱)、TYPE、ERROR_CONTROL、BINARY_PATH_NAME、LOAD_ORDER_GROUP、TAG、DISPLAY_NAME、DEPENDENCIES 和 SERVICE_START_NAME。
            管理員可以使用 SC 來確定任一服務的二進制名稱,并查明它是否與其他服務共享一個進程,在命令行下鍵入下列命令:
            sc qc ServiceName
            SC 有助于將 Microsoft 管理控制臺 (MMC) 的服務節點中的服務與“系統監視器”中的進程進行匹配。如果二進制名稱是 Services.exe,那么服務共享“服務控制器”進程。
            Services.exe 啟動所有的服務。為節約系統資源,幾個為 Windows 開發的 Win32 服務被編寫為共享 Services.exe 進程。這些服務不作為獨立的進程列在“系統監視器”或“任務管理器”之中。Svchost.exe 也是如此,它是許多操作服務共享的服務主機進程。
            因為第三方 Win32 服務也可以配置為共享進程,所以不可能為每一個 Win32 服務創建一個進程。SC 可以用來獲得這些服務的配置信息。但是,如果一項服務不與其他服務共享其進程,那么在服務運行時,“系統監視器”中會出現其進程。
            因為 SC 與包含在 Windows 中的 Services.exe 相比,提供了有關服務的更為詳細和準確的信息,所以對于服務開發人員來說,SC 更有用處。Services.exe 可以確定服務是正在運行、已停止還是已暫停。盡管這些工具對于正在平穩運行的已調試應用程序已經足夠,但它們提供的有關正開發的服務的信息卻會使人誤解。例如,正在啟動的服務不管其實際運行與否都顯示為已啟動。
            SC 可執行對所有 Windows 服務控制應用編程接口 (API) 函數的調用。通過在命令行下指定這些函數來設置其參數。
            使用 SC,可以查詢服務狀態,檢索存儲在狀態結構字段中的值。Services.exe 不能提供服務的完整狀態,但 SC 可以顯示精確的服務狀態,以及最新的檢查點號碼和等待提示。可以將檢查點用作調試工具,原因在于它表明了在程序停止響應之前初始化進行的程度。SC 也可以用來指定遠程計算機名,以便于在遠程計算機上調用服務 API 函數或查看服務狀態結構。
            下面的示例顯示了如何使用 sc qc 命令:
            sc qc \\myserver newsrvice
            sc qc rpcss 248
            16、sc qdescrīption
            顯示服務的描述字符串。
            語法
            Sc [ServerName] qdescrīption [ServiceName] [BufferSize]
            參數
            BufferSize
            指定緩沖區大小(以字節為單位)。默認值為 1024 字節。
            下面的示例顯示了如何使用 sc qdescrīption 命令:
            sc qdescrīption rpcss
            sc qdescrīption rpcss 138
            17、sc qfailure
            顯示指定服務失敗時要執行的操作。
            語法
            Sc [ServerName] qfailure [ServiceName] [BufferSize]
            參數
            BufferSize
            指定緩沖區大小(以字節為單位)。默認值為 1024 字節。
            備注
            qfailure 操作可以顯示有關服務的下列信息:SERVICE_NAME(服務的注冊表子項名)、RESET_PERIOD、REBOOT_MESSAGE、COMMAND_LINE 和 FAILURE_ACTIONS。
            下面的示例顯示了如何使用 sc qfailure 命令:
            sc qfailure rpcss
            sc qfailure rpcss 20
            18、sc query
            獲得和顯示關于指定的服務、驅動程序、服務類型或驅動程序類型的信息。
            語法
            Sc [ServerName] query [ServiceName] [type= {driver | service | all}] [type= {own | share | interact | kernel | filesys | rec | adapt}] [state= {active | inactive | all}] [bufsize= BufferSize] [ri= ResumeIndex] [group= GroupName]
            參數
            ServiceName
            指定由 getkeyname 操作返回的服務名。此 query 參數不與其他的 query 參數結合使用(除了 ServerName)。
            type= {driver | service | all}
            指定需要枚舉的內容。默認類型為 service。
            driver
            指定僅枚舉驅動程序。
            service
            指定僅枚舉服務。
            all
            指定同時枚舉驅動程序和服務。
            type= {own | share | interact | kernel | filesys | rec | adapt}
            指定要枚舉的服務類型或驅動程序類型。
            own
            服務以其自身的進程運行。不與其他服務共享可執行文件。這是默認值。
            share
            服務作為共享進程運行。與其他服務共享可執行文件。
            interact
            服務可以與桌面交互,接收用戶的輸入。交互服務必須在 LocalSystem 帳戶下運行。
            kernel
            驅動程序。
            filesys
            文件系統驅動程序。
            state= {active | inactive | all}
            指定要枚舉的服務的已開始狀態。默認狀態是 active。
            active
            指定所有的活動服務。
            inactive
            指定所有暫停或停止的服務。
            all
            指定所有服務。
            bufsize= BufferSize
            以字節為單位指定枚舉緩沖區的大小。默認大小為 1024 字節。當從查詢返回的顯示結果超過 1024 個字節時,增加枚舉緩沖區的大小。
            ri= ResumeIndex
            指定開始或繼續枚舉的索引號。默認值為 0。 在查詢返回的信息超過默認緩沖區能夠顯示的大小時,請與 bufsize= 參數結合使用這個參數。
            group= GroupName
            指定要枚舉的服務組。默認設置為所有組。
            備注
            如果參數及其值之間沒有空格,(例如,是 type= own,而不是 type=own),則操作會失敗。
            query 操作可以顯示有關服務的下列信息:SERVICE_NAME(服務的注冊表子項名)、TYPE、STATE(以及不可用的狀態)、WIN32_EXIT_B、SERVICE_EXIT_B、CHECKPOINT 和 WAIT_HINT。
            在某些情況下,type= 參數可以使用兩次。type= 參數的第一次出現指定是否查詢服務、驅動器或所有這些項。type= 參數的第二次出現指定一個由 create 操作進一步縮小查詢范圍的類型。
            當 query 命令的顯示結果超過了枚舉緩沖區的大小時,顯示類似于以下內容的消息:
            Enum: more data, need 1822 bytes start resume at index 79
            要顯示剩余的 query 信息,請重新運行 query,將 bufsize= 設置為所需的字節數,并將 ri= 設置為指定的索引。例如,在命令行鍵入下面的指令會顯示剩余的輸出:
            sc query bufsize= 1822 ri= 79
            下面的示例顯示了如何使用 sc query 命令:
            sc query
            sc query messenger
            sc query type= driver
            sc query type= service
            sc query state= all
            sc query bufsize= 50
            sc query ri= 14
            sc query type= service type= interact
            sc query type= driver group= ndis
            19、sc queryex
            獲得和顯示關于指定的服務、驅動程序、服務類型或驅動程序類型的擴展信息。
            語法
            Sc [ServerName] queryex [type= {driver | service | all}] [type= {own | share | interact | kernel | filesys | rec | adapt}] [state= {active | inactive | all}] [bufsize= BufferSize] [ri= ResumeIndex][group= GroupName]
            參數
            ServiceName
            指定由 getkeyname 操作返回的服務名。此 queryex 參數不與 ServerName 之外的任何其他 queryex 參數結合使用。
            type= {driver | service | all}
            指定需要枚舉的內容。默認類型為 service。
            driver
            指定僅枚舉驅動程序。
            service
            指定僅枚舉服務。
            all
            指定同時枚舉驅動程序和服務。
            type= {own | share | interact | kernel | filesys | rec | adapt}
            指定要枚舉的服務類型或驅動程序類型。
            own
            服務以其自身的進程運行。不與其他服務共享可執行文件。這是默認值。
            share
            服務作為共享進程運行。與其他服務共享可執行文件。
            interact
            服務可以與桌面交互,接收用戶的輸入。交互服務必須在 LocalSystem 帳戶下運行。
            kernel
            驅動程序。
            filesys
            文件系統驅動程序。
            state= {active | inactive | all}
            指定要枚舉的服務的已開始狀態。默認狀態是 active。
            active
            指定所有的活動服務。
            inactive
            指定所有暫停或停止的服務。
            all
            指定所有服務。
            bufsize= BufferSize
            以字節為單位指定枚舉緩沖區的大小。默認大小為 1024 字節。
            ri= ResumeIndex
            指定開始或繼續枚舉的索引號。默認值為 0。
            group= GroupName
            指定要枚舉的服務組。默認設置為所有組。
            備注
            如果參數及其值之間沒有空格,(例如,是 type= own,而不是 type=own),則操作會失敗。
            queryex 操作可以顯示有關服務的下列信息:SERVICE_NAME(服務的注冊表子項名)、TYPE、STATE(以及不可用的狀態)、WIN32_EXIT_B、SERVICE_EXIT_B、CHECKPOINT、WAIT_HINT、PID 和 FLAGS。
            在某些情況下,type= 參數可以使用兩次。type= 參數的第一次出現指定是否查詢服務、驅動器或所有這些項。type= 參數的第二次出現指定一個由 create 操作進一步縮小查詢范圍的類型。
            當 queryex 命令的顯示結果超過了枚舉緩沖區的大小時,顯示類似于以下內容的消息:
            Enum: more data, need 2130 bytes start resume at index 75
            要顯示剩余的 queryex 信息,請重新運行 queryex,將 bufsize= 設置為所需的字節數,并將 ri= 設置為指定的索引。例如,在命令行鍵入下面的指令會顯示剩余的輸出:
            sc queryex bufsize= 2130 ri= 75
            下面的示例顯示了如何使用 sc queryex 命令:
            sc queryex messenger
            sc queryex group= ""
            20、sc querylock
            查詢和顯示“服務控制管理器”數據庫的鎖定信息。
            語法
            Sc [ServerName] querylock
            參數:略
            21、sc sdset
            使用“服務描述符定義語言 (SDDL)”來設置服務的安全描述符。
            語法
            Sc [ServerName] sdset ServiceName ServiceSecurityDescrīptor
            參數
            ServiceSecurityDescrīptor
            在 SDDL 中指定服務描述符。
            備注
            有關 SDDL 的詳細信息,請參閱 Microsoft 網站上的 Security Descrīptor Definition Language(安全描述符定義語言)。
            22、sc sdshow
            使用 SDDL 顯示服務的安全描述符。
            語法
            Sc [ServerName] sdshow ServiceName
            參數:略
            備注
            有關 SDDL 的詳細信息,請參閱 Microsoft 網站上的 Security Descrīptor Definition Language(安全描述符定義語言)。
            示例
            sc sdshow rpcss
            23、sc start
            啟動正在運行的服務。
            語法
            Sc [ServerName] start ServiceName [ServiceArguments]
            參數
            ServiceArguments
            指定傳遞給要啟動的服務的服務參數。
            下面的示例顯示了如何使用 sc start 命令:
            sc start tapisrv
            24、sc stop
            向服務發送 STOP 控制請求。
            語法
            Sc [ServerName] stop ServiceName
            參數:略
            備注
            并非所有服務都能夠被停止。
            下面的示例顯示了如何使用 sc stop 命令:
            sc stop tapisrv
          posted @ 2008-10-15 09:46 小馬歌 閱讀(298) | 評論 (0)編輯 收藏
           

          SC命令是XP系統中功能強大的DOS命令,SC命令能與“服務控制器”和已安裝設備進行通訊。
          安裝服務:sc create serviceName binPath= "D:\server.exe"        [注意binPath= 之后有一個空格,必須有]

          卸載服務:sc delete serviceName

          or check HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices

          以上修改要重起機器才能生效

          另:
          啟動服務:net start serviceName 或sc start serviceName
          停止服務:net stop serviceName 或sc stop serviceName

          [SC命令 的參數可以配置指定的服務,檢索當前服務的狀態,也可以停止和啟動服務(功能上類似NET STOP/START命令,但SC速度更快且能停止更多的服務)。]

          posted @ 2008-10-15 09:39 小馬歌 閱讀(650) | 評論 (0)編輯 收藏
           
             到 深圳周邊城市 坐汽車比較方便,提供個查詢地址:
          http://jt.sz.bendibao.com/keche/search.asp 
          posted @ 2008-10-13 12:14 小馬歌 閱讀(245) | 評論 (0)編輯 收藏
           
          估計是查看了qq的相關信息,自動創建的,地址:http://xiaomage234.woku.com

          這種方式蠻新奇的
          posted @ 2008-10-07 14:28 小馬歌 閱讀(106) | 評論 (0)編輯 收藏
           
          說是,小三必修課
              
              其實,是所有情場中人的扒皮戲。
              
              《畫皮》是一個驚喜,有些是無心,有些是故意。
              
              因為戲路太善良,我們總是忍不住笑場。
              
              然而,面對,那些太刻意的真情告白……我們如果不笑,難道要跟著哭嗎?
              
              這場戲,需要些時間沉淀,然后,就有人像我們回憶八十年代的港片一樣來回憶這張《畫皮》。
              
              不如把笑點抖一抖,順便幫著大家扭曲一下邏輯。
              
              這個故事告訴我們生活中的許多大道理。
              
              故事的基本結構是這樣的。
              
              
              
              陳坤和甄子丹本來是戰友,兩個人都喜歡趙薇。趙薇選擇了嫁給陳坤,甄子丹憤而遠走。
              畫皮定律一:再好的朋友,搶一個心上人,也會翻臉。無論男女。
              
              陳坤救了一個女人周迅回家。周迅其實是妖怪。
              畫皮定律二:如果一個有家的男人把一個單身女子帶回家,這絕對是場冒險,不管這個姑娘會不會畫皮。
              
              趙薇懷疑陳坤喜歡周迅,進而發覺周迅來了之后,城里開始死人。認準周迅就是妖怪,
              畫皮定律三:如果一個女人發現自己的男人外面有了女人,那么到處跟人說那個女人是狐貍精,只能顯得自己像個瘋子,太小氣。
              
              
              但是沒有人相信她。她寫信喊來了甄子丹。
              畫皮定律四:還是去找自己的舊情人,是正路!(找舊情人來干什么,看你的興趣)
              
              
              周迅想嫁給陳坤,不是做妾,而是做夫人。
              畫皮定律五:如果一個小三,喜歡上了一個有婦之夫,又不像只是玩一玩就吃掉他,而是想要個名分,會搞得三個人都很凄慘。
              
              甄子丹來了,降魔者孫麗也來了,孫麗看著甄子丹很有感覺,甄子丹對孫麗也有點感覺。
              畫皮定律六:男人終究是要變心的,不管他當初多么愛你,只不過是動手沒動手的差別,而且,總是有更年輕的姑娘出現的!!
              
              還有個蜥蜴精追隨周迅而來,蜥蜴精愛著狐貍精周迅,周迅不喜歡他。
              畫皮定律七:討厭長得不帥的男人,女人討厭“長舌頭”的男人,討厭知道自己當年底細的男人,討厭,吃的東西,跟自己口味不同的男人……之后數條,都是第一條的借口。
              
              
              甄子丹表示自己相信趙薇,趙薇說甄子丹是個好人。
              畫皮定律八:如果一個人給你發了“好人卡”,基本來說,這個人打算送死你去,吃定你一輩子了。不知道逃的,是傻瓜。
              
              
              周迅想色誘陳坤,蜥蜴精吃醋,進攻陳坤,大鬧府里。
              畫皮定律九:在兩個女人之間搖擺的男人,比較吃香。在兩個男人之間搖擺的女人,其實比較危險。女人斗心計,男人斗體力。
              
              
              蜥蜴精又進攻趙薇,關鍵時刻,陳坤選擇去保護趙薇。
              畫皮定律十:所有的男人,都會先考慮自己的老婆的,小三們的悲哀…… 其實,不是因為他更看重老婆,而是他的身份促使他必須先救自己的老婆,否則,會被人說,沒有人味。
              
              周迅終于明白,陳坤更在乎身為老婆的趙薇。
              畫皮定律十一:情人早晚會發現真相的,這個時候,怎么選擇,能比較出一個人的智商。
              
              于是周迅直接脅迫趙薇離開,逼趙薇服毒。
              畫皮定律十二:偷情的樂趣,就在于偷偷摸摸,有人爭搶的感覺比較刺激,直接逼宮……注定是悲劇
              
              …………正邪開始大決戰!!
              
              
              
              所謂,凡事,不能十三點。那就到此為止吧。
              
              愛情這種事情,都不能仔細推敲,一推敲,就千瘡百孔。
            
            
             愛情經不起推敲,幸福的是,你總是在某個時刻,還相信你會愛上,死心塌地
          posted @ 2008-10-06 14:38 小馬歌 閱讀(198) | 評論 (0)編輯 收藏
           
          鑒于rsa加密的重要性和相關源代碼的匱乏,經過整理特此貼出。需要下載bcprov-jdk14-123.jar。
            
            import javax.crypto.Cipher;
            import java.security.*;
            import java.security.spec.RSAPublicKeySpec;
            import java.security.spec.RSAPrivateKeySpec;
            import java.security.spec.InvalidKeySpecException;
            import java.security.interfaces.RSAPrivateKey;
            import java.security.interfaces.RSAPublicKey;
            import java.io.*;
            import java.math.BigInteger;
            
            /**
            * RSA 工具類。提供加密,解密,生成密鑰對等方法。
            * 需要到http://www.bouncycastle.org下載bcprov-jdk14-123.jar。
            *
            */
            public class RSAUtil {
            
            /**
            * 生成密鑰對
            * @return KeyPair
            * @throws EncryptException
            */
            public static KeyPair generateKeyPair() throws EncryptException {
            try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
            new org.bouncycastle.jce.provider.BouncyCastleProvider());
            final int KEY_SIZE = 1024;//沒什么好說的了,這個值關系到塊加密的大小,可以更改,但是不要太大,否則效率會低
            keyPairGen.initialize(KEY_SIZE, new SecureRandom());
            KeyPair keyPair = keyPairGen.genKeyPair();
            return keyPair;
            } catch (Exception e) {
            throw new EncryptException(e.getMessage());
            }
            }
            /**
            * 生成公鑰
            * @param modulus
            * @param publicExponent
            * @return RSAPublicKey
            * @throws EncryptException
            */
            public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws EncryptException {
            KeyFactory keyFac = null;
            try {
            keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            } catch (NoSuchAlgorithmException ex) {
            throw new EncryptException(ex.getMessage());
            }
            
            RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));
            try {
            return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
            } catch (InvalidKeySpecException ex) {
            throw new EncryptException(ex.getMessage());
            }
            }
            /**
            * 生成私鑰
            * @param modulus
            * @param privateExponent
            * @return RSAPrivateKey
            * @throws EncryptException
            */
            public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws EncryptException {
            KeyFactory keyFac = null;
            try {
            keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            } catch (NoSuchAlgorithmException ex) {
            throw new EncryptException(ex.getMessage());
            }
            
            RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));
            try {
            return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
            } catch (InvalidKeySpecException ex) {
            throw new EncryptException(ex.getMessage());
            }
            }
            /**
            * 加密
            * @param key 加密的密鑰
            * @param data 待加密的明文數據
            * @return 加密后的數據
            * @throws EncryptException
            */
            public static byte[] encrypt(Key key, byte[] data) throws EncryptException {
            try {
            Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, key);
            int blockSize = cipher.getBlockSize();//獲得加密塊大小,如:加密前數據為128個byte,而key_size=1024 加密塊大小為127 byte,加密后為128個byte;因此共有2個加密塊,第一個127 byte第二個為1個byte
            int outputSize = cipher.getOutputSize(data.length);//獲得加密塊加密后塊大小
            int leavedSize = data.length % blockSize;
            int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
            byte[] raw = new byte[outputSize * blocksSize];
            int i = 0;
            while (data.length - i * blockSize > 0) {
            if (data.length - i * blockSize > blockSize)
            cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
            else
            cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
            //這里面doUpdate方法不可用,查看源代碼后發現每次doUpdate后并沒有什么實際動作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的時候才將所有的byte[]進行加密,可是到了此時加密塊大小很可能已經超出了OutputSize所以只好用dofinal方法。
            
            i++;
            }
            return raw;
            } catch (Exception e) {
            throw new EncryptException(e.getMessage());
            }
            }
            /**
            * 解密
            * @param key 解密的密鑰
            * @param raw 已經加密的數據
            * @return 解密后的明文
            * @throws EncryptException
            */
            public static byte[] decrypt(Key key, byte[] raw) throws EncryptException {
            try {
            Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(cipher.DECRYPT_MODE, key);
            int blockSize = cipher.getBlockSize();
            ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
            int j = 0;
            
            while (raw.length - j * blockSize > 0) {
            bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
            j++;
            }
            return bout.toByteArray();
            } catch (Exception e) {
            throw new EncryptException(e.getMessage());
            }
            }
            /**
            *
            * @param args
            * @throws Exception
            */
            public static void main(String[] args) throws Exception {
            File file = new File("test.html");
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            byte[] tmpbuf = new byte[1024];
            int count = 0;
            while ((count = in.read(tmpbuf)) != -1) {
            bout.write(tmpbuf, 0, count);
            tmpbuf = new byte[1024];
            }
            in.close();
            byte[] orgData = bout.toByteArray();
            KeyPair keyPair = RSAUtil.generateKeyPair();
            RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
            
            byte[] pubModBytes = pubKey.getModulus().toByteArray();
            byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
            byte[] priModBytes = priKey.getModulus().toByteArray();
            byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
            RSAPublicKey recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
            RSAPrivateKey recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
            
            byte[] raw = RSAUtil.encrypt(priKey, orgData);
            file = new File("encrypt_result.dat");
            OutputStream out = new FileOutputStream(file);
            out.write(raw);
            out.close();
            byte[] data = RSAUtil.decrypt(recoveryPubKey, raw);
            file = new File("decrypt_result.html");
            out = new FileOutputStream(file);
            out.write(data);
            out.flush();
            out.close();
            }
            }
            
            加密可以用公鑰,解密用私鑰;或者加密用私鑰。通常非對稱加密是非常消耗資源的,因此可以對大數據用對稱加密如:des(具體代碼可以看我以前發的貼子),而對其對稱密鑰進行非對稱加密,這樣既保證了數據的安全,還能保證效率。
          posted @ 2008-09-19 17:15 小馬歌 閱讀(286) | 評論 (0)編輯 收藏
           
          什么是RSA
            RSA算法是第一個能同時用于加密和數字簽名的算法,也易于理解和操作。
            RSA是被研究得最廣泛的公鑰算法,從提出到現在已近二十年,經歷了各種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。RSA的安全性依賴于大數的因子分解,但并沒有從理論上證明破譯RSA的難度與大數分解難度等價。即RSA的重大缺陷是無法從理論上把握它的保密性能如何,而且密碼學界多數人士傾向于因子分解不是NPC問題。
            RSA的缺點主要有:A)產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密。B)分組長度太大,為保證安全性,n 至少也要 600 bits以上,使運算代價很高,尤其是速度較慢,較對稱密碼算法慢幾個數量級;且隨著大數分解技術的發展,這個長度還在增加,不利于數據格式的標準化。目前,SET(Secure Electronic Transaction)協議中要求CA采用2048比特長的密鑰,其他實體使用1024比特的密鑰。
            這種算法1978年就出現了,它是第一個既能用于數據加密也能用于數字簽名的算法。它易于理解和操作,也很流行。算法的名字以發明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。
            RSA算法是一種非對稱密碼算法,所謂非對稱,就是指該算法需要一對密鑰,使用其中一個加密,則需要用另一個才能解密。
            RSA的算法涉及三個參數,n、e1、e2。
            其中,n是兩個大質數p、q的積,n的二進制表示時所占用的位數,就是所謂的密鑰長度。
            e1和e2是一對相關的值,e1可以任意取,但要求e1與(p-1)*(q-1)互質;再選擇e2,要求(e2*e1)mod((p-1)*(q-1))=1。
            (n及e1),(n及e2)就是密鑰對。
            RSA加解密的算法完全相同,設A為明文,B為密文,則:A=B^e1 mod n;B=A^e2 mod n;
            e1和e2可以互換使用,即:
            A=B^e2 mod n;B=A^e1 mod n;
          一、RSA 的安全性
            RSA的安全性依賴于大數分解,但是否等同于大數分解一直未能得到理論上的證明,因為沒有證明破解 RSA就一定需要作大數分解。假設存在一種無須分解大數的算法,那它肯定可以修改成為大數分解算法。目前, RSA 的一些變種算法已被證明等價于大數分解。不管怎樣,分解n是最顯然的攻擊方法。現在,人們已能分解多個十進制位的大素數。因此,模數n 必須選大一些,因具體適用情況而定。
          二、RSA的速度
            由于進行的都是大數計算,使得RSA最快的情況也比DES慢上倍,無論是軟件還是硬件實現。速度一直是RSA的缺陷。一般來說只用于少量數據加密。
          三、RSA的選擇密文攻擊
            RSA在選擇密文攻擊面前很脆弱。一般攻擊者是將某一信息作一下偽裝( Blind),讓擁有私鑰的實體簽署。然后,經過計算就可得到它所想要的信息。實際上,攻擊利用的都是同一個弱點,即存在這樣一個事實:乘冪保留了輸入的乘法結構:
            ( XM )^d = X^d *M^d mod n
            前面已經提到,這個固有的問題來自于公鑰密碼系統的最有用的特征--每個人都能使用公鑰。但從算法上無法解決這一問題,主要措施有兩條:一條是采用好的公鑰協議,保證工作過程中實體不對其他實體任意產生的信息解密,不對自己一無所知的信息簽名;另一條是決不對陌生人送來的隨機文檔簽名,簽名時首先使用One-Way HashFunction 對文檔作HASH處理,或
          四、RSA的公共模數攻擊
            若系統中共有一個模數,只是不同的人擁有不同的e和d,系統將是危險的。最普遍的情況是同一信息用不同的公鑰加密,這些公鑰共模而且互質,那末該信息無需私鑰就可得到恢復。設P為信息明文,兩個加密密鑰為e1和e2,公共模數是n,則:
            C1 = P^e1 mod n
            C2 = P^e2 mod n
            密碼分析者知道n、e1、e2、C1和C2,就能得到P。
            因為e1和e2互質,故用Euclidean算法能找到r和s,滿足:
            r * e1 + s * e2 = 1
            假設r為負數,需再用Euclidean算法計算C1^(-1),則
            ( C1^(-1) )^(-r) * C2^s = P mod n
            另外,還有其它幾種利用公共模數攻擊的方法。總之,如果知道給定模數的一對e和d,一是有利于攻擊者分解模數,一是有利于攻擊者計算出其它成對的e’和d’,而無需分解模數。解決辦法只有一個,那就是不要共享模數n。
            RSA的小指數攻擊。 有一種提高 RSA速度的建議是使公鑰e取較小的值,這樣會使加密變得易于實現,速度有
            所提高。但這樣作是不安全的,對付辦法就是e和d都取較大的值。
            RSA算法是第一個能同時用于加密和數字簽名的算法,也易于理解和操作。RSA是被研究得最廣泛的公鑰算法,從提出到現在已近二十年,經歷了各種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。RSA的安全性依賴于大數的因子分解,但并沒有從理論上證明破譯RSA的難度與大數分解難度等價。即RSA的重大缺陷是無法從理論上把握它的保密性能如何,而且密碼學界多數人士傾向于因子分解不是NPC問題。 RSA的缺點主要有:A)產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密。B)分組長度太大,為保證安全性,n 至少也要 600 bits 以上,使運算代價很高,尤其是速度較慢,較對稱密碼算法慢幾個數量級;且隨著大數分解技術的發展,這個長度還在增加,不利于數據格式的標準化。目前,SET( Secure Electronic Transaction )協議中要求CA采用比特長的密鑰,其他實體使用比特的密鑰。
          posted @ 2008-09-19 17:15 小馬歌 閱讀(241) | 評論 (0)編輯 收藏
           

          Java 程序中也有內存漏洞?當然有。與流行的觀念相反,在 Java 編程中,內存治理仍然是需要考慮的問題。在本文中,您將了解到什么會導致內存漏洞以及何時應該關注這些漏洞。您還有機會實踐一下在您自己的項目中解決漏洞問題。
            
            Java 程序中的內存漏洞是如何顯現出來的
            大多數程序員都知道,使用像 Java 這樣的編程語言的一大好處就是,他們不必再擔心內存的分配和釋放問題。您只須創建對象,當應用程序不再需要這些對象時,Java 會通過一種稱為“垃圾收集”的機制將這些對象刪除。這種處理意味著 Java 已經解決了困擾其他編程語言的煩人問題 -- 可怕的內存漏洞。是這樣的嗎?
            
            在深入討論之前,我們先回顧一下垃圾收集的工作方式。垃圾收集器的工作是發現應用程序不再需要的對象,并在這些對象不再被訪問或引用時將它們刪除。垃圾收集器從根節點(在 Java 應用程序的整個生存周期內始終存在的那些類)開始,遍歷被引用的所有節點進行清除。在它遍歷這些節點的同時,它跟蹤哪些對象當前正被引用著。任何類只要不再被引用,它就符合垃圾收集的條件。當刪除這些對象以后,就可將它們所占用的內存資源返回給 Java 虛擬機 (JVM)。
            
            所以的確是這樣,Java 代碼不要求程序員負責內存的治理和清除,它會自動對無用的對象執行垃圾收集。但是,要緊記的一點是 僅當一個對象不再被引用時才會被統計為無用的。圖 1 說明了這個概念。
            
           

            
          圖 1. 無用但仍被引用的對象

            
            上面說明了在 Java 應用程序執行期間具有不同生存周期的兩個類。類 A 首先被實例化,并會在很長一段時間或程序的整個生存期內存在。在某個時候,類 B 被創建,類 A 添加對這個新創建的類的一個引用。現在,我們假定類 B 是某個用戶界面小部件,它由用戶顯示甚至解除。假如沒有清除類 A 對 B 的引用,則即便不再需要類 B,并且即便在執行下一個垃圾收集周期以后,類 B 仍將存在并占用內存空間。
            
            何時應該關注內存漏洞?
            假如您的程序在執行一段時間以后發出 java.lang.OutOfMemoryError 錯誤,則內存漏洞肯定是一個重大嫌疑。除了這種明顯的情況之外,何時還應該關注內存漏洞呢?持完美主義觀點的程序員肯定會回答,應該查找并糾正 所有內存漏洞。但是,在得出這個結論之前,還有幾個方面需要考慮,包括程序的生存期和漏洞的大小。
            
            完全有這樣的可能,垃圾收集器在應用程序的生存期內可能始終不會運行。不能保證 JVM 何時以及是否會調用垃圾收集器 -- 即便程序顯式地調用 System.gc() 也是如此。通常,在當前的可用內存能夠滿足程序的內存需求時,JVM 不會自動運行垃圾收集器。當可用內存不能滿足需求時,JVM 將首先嘗試通過調用垃圾收集來釋放出更多的可用內存。假如這種嘗試仍然不能釋放足夠的資源,JVM 將從操作系統獲取更多的內存,直至達到答應的最大極限。
            
            例如,考慮一個小型 Java 應用程序,它顯示一些用于修改配置的簡單用戶界面元素,并且它有一個內存漏洞。很可能到應用程序關閉時也不會調用垃圾收集器,因為 JVM 很可能有足夠的內存來創建程序所需的全部對象,而此后可用內存則所剩無幾。因此,在這種情況下,即使某些“死”對象在程序執行時占用著內存,它實際上并沒有什么用途。
            
            假如正在開發的 Java 代碼要全天 24 小時在服務器上運行,則內存漏洞在此處的影響就比在我們的配置實用程序中的影響要大得多。在要長時間運行的某些代碼中,即使最小的漏洞也會導致 JVM 耗盡全部可用內存。
            
            在相反的情況下,即便程序的生存期較短,假如存在分配大量臨時對象(或者若干吞噬大量內存的對象)的任何 Java 代碼,而且當不再需要這些對象時也沒有取消對它們的引用,則仍然可能達到內存極限。
            
            最后一種情況是內存漏洞無關緊要。我們不應該認為 Java 內存漏洞像其他語言(如 C++)中的漏洞那樣危險,在那些語言中內存將丟失,且永遠不會被返回給操作系統。在 Java 應用程序中,我們使不需要的對象依附于操作系統為 JVM 所提供的內存資源。所以從理論上講,一旦關閉 Java 應用程序及其 JVM,所分配的全部內存將被返回給操作系統。
            
            確定應用程序是否有內存漏洞
            為了查看在 Windows NT 平臺上運行的某個 Java 應用程序是否有內存漏洞,您可能試圖在應用程序運行時觀察“任務治理器”中的內存設置。但是,在觀察了運行中的幾個 Java 應用程序以后,您會發現它們比本地應用程序占用的內存要多得多。我做過的一些 Java 項目要使用 10 到 20 MB 的系統內存才能啟動。而操作系統自帶的 Windows EXPlorer 程序只需 5 MB 左右的內存。
            
            在 Java 應用程序內存使用方面應注重的另一點是,這個典型程序在 IBM JDK 1.1.8 JVM 中運行時占用的系統內存越來越多。似乎直到為它分配非常多的物理內存以后它才開始向系統返回內存。這些情況是內存漏洞的征兆嗎?
            
            要理解其中的緣由,我們必須熟悉 JVM 如何將系統內存用作它的堆。當運行 java.exe 時,您使用一定的選項來控制垃圾收集堆的起始大小和最大大小(分別用 -ms 和 -mx 表示)。Sun JDK 1.1.8 的默認起始設置為 1 MB,默認最大設置為 16 MB。IBM JDK 1.1.8 的默認最大設置為系統總物理內存大小的一半。這些內存設置對 JVM 在用盡內存時所執行的操作有直接影響。JVM 可能繼續增大堆,而不等待一個垃圾收集周期的完成。
            
            這樣,為了查找并最終消除內存漏洞,我們需要使用比任務監視實用程序更好的工具。當您試圖調試內存漏洞時,內存調試程序(請參閱參考資源)可能派得上用場。這些程序通常會顯示堆中的對象數、每個對象的實例數和這些對象所占用的內存等信息。此外,它們也可能提供有用的視圖,這些視圖可以顯示每個對象的引用和引用者,以便您跟蹤內存漏洞的來源。
            
            下面我將說明我是如何用 Sitraka Software 的 JProbedebugger 檢測和去除內存漏洞的,以使您對這些工具的部署方式以及成功去除漏洞所需的過程有所了解。
            
            內存漏洞的一個示例
            本例集中討論一個問題,我們部門當時正在開發一個商業發行版軟件,這是一個 Java JDK 1.1.8 應用程序,一個測試人員花了幾個小時研究這個程序才最終使這個問題顯現出來。這個 Java 應用程序的基本代碼和包是由幾個不同的開發小組在不同的時間開發的。我猜想,該應用程序中意外出現的內存漏洞是由那些沒有真正理解別人開發的代碼的程序員造成的。
            
            我們正在討論的 Java 代碼答應用戶為 Palm 個人數字助理創建應用程序,而不必編寫任何 Palm OS 本地代碼。通過使用圖形用戶界面,用戶可以創建窗體,向窗體中添加控件,然后連接這些控件的事件來創建 Palm 應用程序。測試人員發現,隨著不斷創建和刪除窗體和控件,這個 Java 應用程序最終會耗盡內存。開發人員沒有檢測到這個問題,因為他們的機器有更多的物理內存。
            
            為了研究這個問題,我用 JProbe 來確定什么地方出了差錯。盡管用了 JProbe 所提供的強大工具和內存快照,研究仍然是一個冗長乏味、不斷重復的過程,首先要確定出現內存漏洞的原因,然后修改代碼,最后還得檢驗結果。
            
            JProbe 提供幾個選項,用來控制調試期間實際記錄哪些信息。經過幾次試驗以后,我斷定獲取所需信息的最有效方法是,關閉性能數據收集,而將注重力集中在所捕捉的堆數據上。JProbe 提供了一個稱為 Runtime Heap Summary 的視圖,它顯示 Java 應用程序運行時所占用的堆內存量隨時間的變化。它還提供了一個工具欄按鈕,必要時可以強制 JVM 執行垃圾收集。假如您試圖弄清楚,當 Java 應用程序不再需要給定的類實例時,這個實例會不會被作為垃圾收集,這個功能將很有用。圖 2 顯示了使用中的堆存儲量隨時間的變化。
            
           

            
          圖 2. Runtime Heap Summary

            
            在 Heap Usage Chart 中,藍色部分表明已分配的堆空間大小。在啟動這個 Java 程序并達到穩定狀態以后,我強制垃圾收集器運行,在圖中的表現就是綠線(這條線表明插入了一個檢查點)左側的藍線的驟降。隨后,我添加了四個窗體,然后又將它們刪除,并再次調用了垃圾收集器。當程序返回僅有一個可視窗體的初始狀態時,檢查點之后的藍色區域高于檢查點之前的藍色區域這一情況表明可能存在內存漏洞。我通過查看 Instance Summary 證實確實有一個漏洞,因為 Instance Summary 表明 FormFrame 類(它是窗體的主用戶界面類)的計數在檢查點之后增加了 4。
            
            查找原因
            為了將測試人員報告的問題剔出,我采取的第一個步驟是找出幾個簡單的、可重復的測試案例。就本例而言,我發現只須添加一個窗體,將它刪除,然后強制執行垃圾收集,結果就會導致與被刪除窗體相關聯的許多類實例仍然處于活動狀態。這個問題在 JProbe 的 Instance Summary 視圖中很明顯,這個視圖統計每個 Java 類在堆中的實例數。
            
            為了查明使垃圾收集器無法正常完成其工作的那些引用,我使用 JProbe 的 Reference Graph(如圖 3 所示)來確定哪些類仍然引用著目前未被刪除的 FormFrame 類。在調試這個問題時該過程是最復雜的過程之一,因為我發現許多不同的對象仍然引用著這個無用的對象。用來查明究竟是哪個引用者真正造成這個問題的試錯過程相當耗時。
            
            在本例中,一個根類(左上角用紅色標明的那個類)是問題的發源地。右側用藍色突出顯示的類處在從最初的 FormFrame 類跟蹤而來的路徑上。
            


            
          圖 3. 在引

          資料引用:http://www.knowsky.com/365325.html

          posted @ 2008-09-19 17:10 小馬歌 閱讀(271) | 評論 (0)編輯 收藏
           
          動態口令,也被成為一次性口令(OTP,One-Time password)
            OTP試圖解決用戶選擇強壯密碼時的一些問題。大多數OTP基于雙要素認證原則運行。要認證一個系統,你需要擁有一個令牌卡和你的個人識別碼(PIN personal identification number)。生成和同步密碼的方法隨OTP系統的不同而不同。在一種比較流行的OTP方法中,令牌卡在一個時間間隔內(通常為 60S)生成登陸密碼。這個看上去隨機的數字串實際上與OTP服務器和令牌上運行的數學算法緊密相關。一個由令牌生成的登錄密碼可能類似這樣:4F40D974。PIN要么與算法一起使用生成登錄密碼(隨后變成OTP),要么與登陸密碼一起使用。
            使用由算法和PIN生成登錄密碼的系統防止個人反復嗅探網絡后獲得用戶的PIN。OTP用以下方法改進了密碼:
            >用戶再也不能選擇弱密碼
            >用戶只要記住PIN,而不用記住傳統的強密碼
            > 一旦密碼被使用一次,線路上嗅探到的密碼就已經失效
            當然沒有大面積的密碼系統使用OTP是有原因的,OTP也有一些缺點:
            > 用戶需要擁有令牌卡進行認證
            >OTP需要一臺額外的服務器接受來自認證服務器中繼的請求
            >使用OTP輸入一個密碼比輸入一個用戶需要記住的密碼時間花費更高
            > 在大型網絡中OTP價格不菲
            當考慮OTP總體評價時,它顯然是一種有價值的技術,只是不能到處使用。大多數的機構選擇將OTP用于他們安全策略中的關鍵系統,或用在密碼破解嘗試較多的地方。對于一個典型的機構,該地方以為著是財務和人力資源系統,也可以是撥號或虛擬專用網這樣的遠程系統。
            動態口令,又叫動態令牌、動態密碼。它的主要原理是:用戶登錄前,依據用戶私人身份信息,并引入隨機數產生隨機變化的口令,使每次登錄過程中傳送的口令信息都不同,以提高登錄過程中用戶身份認證的安全性。
            由于口令每次都變化,即使得到密碼也沒用,而且這種動態口令由專用算法生成,隨機性高,不太容易被破解。因此,動態口令極大地提高了用戶身份認證的安全性。
          posted @ 2008-09-19 17:07 小馬歌 閱讀(1228) | 評論 (0)編輯 收藏
           
          在上兩講中,筆者介紹了DirectShow的應用原理以及開發Filter之前的一些預備知識。這一講,筆者就要手把手教你如何寫自己的Filter啦。
          首先,從VC++的項目開始(請確認你已經給VC++配置好了DirectX的開發環境)。寫自己的Filter,第一步是使用VC++建立一個Filter的項目。由于DirectX SDK提供了很多Filter的例子項目(位于DXSDK\samples\Multimedia\DirectShow\ Filters目錄下),最簡單的方法就是拷貝一個,然后再在此基礎上修改。但如果你是Filter開發的初學者,筆者并不贊成這么做。
          自己新建一個Filter項目也很簡單。使用VC++的向導,建立一個空的”Win32 Dynamic-link Library”項目。注意,幾個文件是必須有的:.def文件,定義四個導出函數;定義Filter類的.cpp文件和.h文件,并在.cpp文件中定義Filter的注冊信息以及兩個Filter的注冊函數:DllRegisterServer和DllUnregisterServer。(注:Filter的注冊信息是Filter在注冊時寫到注冊表里的內容,格式可以參考SDK的示例代碼,Filter相關的GUID務必使用GuidGen.exe產生。)接下去進行項目的設置(Project->Settings…)。此時,你可以打開一個SDK的例子項目進行對比,有些宏定義完全可以照抄,最后注意將輸出文件的擴展名改為.ax。
          上一講曾經提到過,在寫Filter之前,選擇一個合適的Filter基類是至關重要的。為此,你必須對幾個Filter的基類有相當的了解。在實際應用中,Filter的基類并不總是選擇CBaseFilter的。相反,因為我們絕大部分寫的都是中間的傳輸Filter(Transform Filter),所以基類選擇CTransformFilter和CTransInPlaceFilter的居多。如果我們寫的是源Filter,我們可以選擇CSource作為基類;如果是Renderer Filter,可以選擇CBaseRenderer或CBaseVideoRenderer等。
          總之,選擇好Filter的基類是很重要的。當然,選擇Filter的基類也是很靈活的,沒有絕對的標準。能夠通過CTransformFilter實現的Filter當然也能從CBaseFilter一步一步實現。下面,筆者就從本人的實際經驗出發,對Filter基類的選擇提出幾點建議供大家參考。
          首先,你必須明確這個Filter要完成什么樣的功能,即要對Filter項目進行需求分析。請盡量保持Filter實現的功能的單一性。如果必要的話,你可以將需求分解,由兩個(或者更多的)功能單一的Filter去實現總的功能需求。
          其次,你應該明確這個Filter大致在整個Filter Graph的位置,這個Filter的輸入是什么數據,輸出是什么數據,有幾個輸入Pin、幾個輸出Pin等等。你可以畫出這個Filter的草圖。弄清這一點十分重要,這將直接決定你使用哪種“模型”的Filter。比如,如果Filter僅有一個輸入Pin和一個輸出Pin,而且一進一處的媒體類型相同,則一般采用CTransInPlaceFilter作為Filter的基類;如果媒體類型不一樣,則一般選擇CTransformFilter作為基類。
          再者,考慮一些數據傳輸、處理的特殊性要求。比如Filter的輸入和輸出的Sample并不是一一對應的,這就一般要在輸入Pin上進行數據的緩存,而在輸出Pin上使用專門的線程進行數據處理。這種情況下,Filter的基類選擇CSource為宜(雖然這個Filter并不是源Filter)。
          當Filter的基類選定了之后,Pin的基類也就相應選定了。接下去,就是Filter和Pin上的代碼實現了。有一點需要注意的是,從軟件設計的角度上來說,應該將你的邏輯類代碼同Filter的代碼分開。下面,我們一起來看一下輸入Pin的實現。你需要實現基類所有的純虛函數,比如CheckMediaType等。在CheckMediaType內,你可以對媒體類型進行檢驗,看是否是你期望的那種。因為大部分Filter采用的是推模式傳輸數據,所以在輸入Pin上一般都實現了Receive方法。有的基類里面已經實現了Receive,而在Filter類上留一個純虛函數供用戶重載進行數據處理。這種情況下一般是無需重載Receive方法的,除非基類的實現不符合你的實際要求。而如果你重載了Receive方法,一般會同時重載以下三個函數EndOfStream、BeginFlush和EndFlush。我們再來看一下輸出Pin的實現。一般情況下,你要實現基類所有的純虛函數,除了CheckMediaType進行媒體類型檢查外,一般還有DecideBufferSize以決定Sample使用內存的大小,GetMediaType提供支持的媒體類型。最后,我們看一下Filter類的實現。首先當然也要實現基類的所有純虛函數。除此之外,Filter還要實現CreateInstance以提供COM的入口,實現NonDelegatingQueryInterface以暴露支持的接口。如果我們創建了自定義的輸入、輸出Pin,一般我們還要重載GetPinCount和GetPin兩個函數。
          Filter框架的實現大致就是這樣。你或許還想知道怎樣在Filter上實現一個自定義的接口,以及怎么實現Filter的屬性頁等等。限于篇幅,筆者就不展開闡述了。其實,這些問題都能在SDK的示例項目中找到答案。其他的,關于在實際編程中應該注意的一些問題,筆者整理了一下,供大家參考。
          1.    鎖(Lock)問題
          DirectShow應用程序至少包含有兩條線程:一條主線程和一條數據傳輸線程。既然是多線程,肯定會碰到線程同步的問題。Filter有兩種鎖:Filter對象鎖和數據流鎖。Filter對象鎖用于Filter級別的如Filter狀態轉換、BeginFlush、EndFlush等;數據流鎖用于數據處理線程內,比如Receive、EndOfStream等。如果這兩種鎖沒有搞清楚,很容易產生程序的死鎖,這一點特別需要提醒。
          2.    EndOfStream問題
          當Filter接收到這個“消息”,意味著上一級Filter的數據都已經發送完畢。在這之后,如果Receive再有數據接收,也不應該去理睬它。如果Filter對輸入Pin上的數據進行了緩存,在接收到EndOfStream后應確保所有緩存的數據都已經處理過了才能返回。
          3.    Media Seeking問題
          一般情況下,你只需要在Filter的輸出Pin上實現NonDelegatingQueryInterface方法,當用戶申請得到IID_ImediaPosition接口或IID_IMediaSeeking接口時將請求往上一級Filter的輸出Pin上傳遞。當Filter Graph進行Mediaseeking的時候,一般會調用Filter上的BeginFlush、EndFlush和NewSegment。如果你的Filter對數據進行了緩存,你就要重載它們,并做出相應的處理。如果你的Filter負責給發送出去的Sample打時間戳,那么,在Mediaseeking之后應該重新從零開始打起。
          4.    關于使用專門的線程
          如果你使用了專門的線程進行數據的處理和發送,你需要特別小心,不要讓線程進行死循環,并且要讓線程處理函數能夠去時時檢查線程命令。應該確保在Filter結束工作的時候,線程也能正常地結束。有時候,你把GraphEdit程序關掉,但GraphEdit進程仍在內存中,往往就是因為數據線程沒有安全關閉這個原因。
          5.    如何從媒體類型中獲取信息
          比如,你想在輸入Pin連接的媒體類型中,獲取視頻圖像的寬、高等信息,你應該在輸入Pin的CompleteConnect方法中實現,而不要在SetMediaType中。
          posted @ 2008-09-19 15:07 小馬歌 閱讀(530) | 評論 (0)編輯 收藏
          僅列出標題
          共95頁: First 上一頁 79 80 81 82 83 84 85 86 87 下一頁 Last 
           
          主站蜘蛛池模板: 新安县| 桃园县| 仙桃市| 邯郸县| 白城市| 墨脱县| 绥芬河市| 龙海市| 广西| 沂水县| 永胜县| 略阳县| 隆尧县| 宁晋县| 东城区| 玉门市| 房山区| 沾益县| 房产| 花莲县| 天祝| 彩票| 沅江市| 云安县| 通化市| 杭州市| 托克逊县| 府谷县| 平阳县| 平塘县| 呼伦贝尔市| 汝南县| 西城区| 古田县| 南宁市| 油尖旺区| 商城县| 青河县| 沧州市| 阿拉善盟| 胶州市|