1. 程式人生 > >用 C# 編寫 USB 儲存裝置使用痕跡檢測和刪除工具

用 C# 編寫 USB 儲存裝置使用痕跡檢測和刪除工具

編寫 USB 儲存裝置使用痕跡檢測和刪除工具

(C# Windows Form 程式設計練習)

[版權所有 邱秋 2014 [email protected], 轉載請註明出處]

第一節 準備知識

之前一直都是用 Visual Basic .Net 來寫 Windows Form 程式。這幾天,熟悉了一下 C# 語言的語法,想練習一下。以前使用過一些 USB 儲存裝置使用痕跡檢測和刪除工具,於是想寫了一個小工具來模擬這些功能。

USB 儲存裝置在使用後會在登錄檔留下一些記錄,一般是通過檢索相應的登錄檔鍵值來檢查使用痕跡。這些鍵值包括:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX(CurrentControSetXXX)\Enum\USB
HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX(CurrentControSetXXX)\Enum\USBSTOR
HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX(CurrentControSetXXX)\Control\DeviceClasses\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX(CurrentControSetXXX)\Control\DeviceClasses\{a5dcbf10-6530-11d2-901f-00c04fb951ed}

其中 ControlSetXXX 和 CurrentControlSetXXX 表示的是登錄檔中的類似於 ControlSet001、ControlSet002、CurrentControlSet 這樣的子鍵(CurrentControlSet 子鍵一般只有一個,特殊情況下可能有 CurrentControlSet001 等多個,同樣的 ControlSet 一般只有 ControlSet001 和 ControlSet002 這兩個,特殊情況下可能會有多個),CurrentControlSet 儲存的是系統的當前的一些配置資訊,而 ControlSet001 等則是對當前配置資訊的備份,一般登錄檔都會有兩個以上的備份,有的時候可能會有更多。在 ControlSetXXX 中的資訊和 CurrentControlSet 中的資訊一般都是一樣的,所以在檢測和刪除 USB 儲存裝置資訊時,不僅要檢測 CurrentControlSet 子鍵,也要檢測 ControlSetXXX 子鍵。

對於 Enum\USB 子鍵,其中儲存的是曾經連線到系統的 USB 裝置的一些資訊,包括 USB 滑鼠、鍵盤、光碟機、手機、行動硬碟、攝像頭、U 盤等,所以並不是所有的資訊都是 USB 儲存裝置資訊,雖然把這些資訊刪除並無大礙(因為刪除的只是這些裝置的一些連線資訊和相應的驅動資訊,並不是刪除系統的實際驅動檔案,所以系統會自動重新識別這些裝置),但為了提高識別精確性,還是增加一些判斷來得好些。

而對於 Enum\USBSTOR 子鍵來說,則相當於把 USB 儲存裝置的資訊單獨分離出來了,該子鍵下儲存的資訊都是曾經連線到計算機的 USB 儲存裝置的相關資訊。這些資訊詳細列出了該 USB 儲存裝置的型別、硬體 ID、裝置描述、友好名稱等資訊。

對於 Control\DeviceClasses 來說,該子鍵下儲存的是以 GUID 分類的裝置資訊,其中有幾個是和 USB 裝置有關的(它們在微軟的 USB 和儲存裝置輸入輸出控制標頭檔案 USBIODEF.H 和NTDDSTOR.H 中定義):

{A5DCBF10-6530-11D2-901F-00C04FB951ED} GUID_DEVINTERFACE_USB_DEVICE
{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27} GUID_DEVINTERFACE_USB_HOST_CONTROLLER
{F18A0E88-C30C-11D0-8815-00A0C906BED8} GUID_DEVINTERFACE_USB_HUB
{53F56307-B6BF-11D0-94F2-00A0C91EFB8B} GUID_DEVINTERFACE_DISK

一般檢查 {53F56307-B6BF-11D0-94F2-00A0C91EFB8B} 和 {A5DCBF10-6530-11D2-901F-00C04FB951ED} 這兩個鍵值,其他兩個由於是和 USB 控制器有關,一般可不檢查。有的資料介紹說還要檢查 MountedDevices 子鍵,但是由於該子鍵和系統的分割槽資訊有關,一般無絕對的把握,不必進行檢查和刪除,到時可能會造成不必要的麻煩。

第二節 檢測 USB 儲存裝置使用痕跡

1、開啟 Visual Studio 2010,新建一個空白方案,命名為 USBView。

2、在解決方案下新建一個型別為“Windows 窗體應用程式”的專案,命名為 USBViewer。將主窗體命名為 MainForm。並新增一些圖示和 PNG 影象資源,美化一下程式介面。

資原始檔包含了一個文字檔案,名稱為 VendorIDs.txt,儲存的是 USB 裝置廠家的 ID 號及廠家名稱值對,用於顯示在登錄檔中搜索到的 USB 裝置的廠家名稱(該檔案內容來源於微軟的 USBView 示例程式中的標頭檔案vndrlist.h,該示例程式使用 C++ 編碼,需要使用 Visual Studio 2013開啟,並要求安裝 Windows Driver Kit (WDK)8.1,下載連結地址 http://code.msdn.microsoft.com/windowshardware/USBView-sample-application-e3241039)。

在建立必要的按鈕後,開始編寫檢測程式碼。因為要讀取登錄檔,有必要使用 .Net 框架提供的 RegistryKey 類。這需要引用 Microsoft.Win32 名稱空間,登錄檔類都在該名稱空間中。

using Microsoft.Win32;

之後便是獲取我們感興趣的登錄檔的基項 HKEY_LOCAL_MACHINE,接著使用RegistryKey 類的 OpenSubKey 方法以只讀方式開啟 SYSTEM 子鍵。

RegistryKey hklm = Registry.LocalMachine;
RegistryKey systemKey = hklm.OpenSubKey("SYSTEM");

這裡順帶說一下,.Net 框架已經將登錄檔中的資料封裝成了 Registry 類(注意 Registry 類和 RegistryKey 類是不一樣的),並公佈了幾個只讀屬性,它們是:

RegistryKey 類是用於在登錄檔中檢索資料用的類。以下是本文中用到的 RegistryKey 類的幾個屬性和方法:

SubKeyCount                     // 檢索當前項的子項數目。
OpenSubKey(string)              // 以只讀方式檢索 string 標識的子項。
OpenSubKey(string, bool)        // 以 bool 指定的方式檢索 string 標識的子項,若 bool 值為 true,表示以可讀寫方式開啟,否則為只讀方式。
DeleteSubKeyTree(string)        // 遞迴刪除 string 標識的子項和任何子級子項。
GetValue(string)                // 檢索 string 標識的名稱所關聯的值,若該標識的名稱不存在,則返回 null。
GetSubKeyNames()                // 返回一個包含所有子項名稱的字串陣列。
Close()                         // 關閉該鍵,如果有更改,則將更改重新整理到磁碟上。

需要注意的是若想用可寫方式開啟某個子項進行刪除或寫入操作,一定要具有相應的許可權,否則會丟擲 SecurityException 異常。在檢測階段,由於只需要只讀許可權,可以使用方法 OpenSubKey(string)。在打開了 Local_Machine\SYSTEM 子鍵後,開始檢索該鍵下類似於 ControlSetXXX 和 CurrentControlSetXXX 的鍵。

if (!sysKey.ToUpper().StartsWith("CONTROLSET") &&
    !sysKey.ToUpper().StartsWith("CURRENTCONTROLSET"))
    continue;

找到這樣的子鍵後,就在其中檢索 Enum\USB、Enum\USBSTOR、Control\DeviceClasses 等子鍵。由於 Enum\USB 子鍵中的資訊並不都是 USB 儲存裝置的資訊,所以要加以判斷。觀察一下 Enum\USB 子鍵下的項:

除了 ROOT_HUB20 外,其他鍵值都是以 VID_ 開始,後面跟著一個 4 位的16 進位制數,這就是廠商的 ID 號,其後的 PID_XXXX 則是廠家的產品號。進一步開啟這些 VID_ 打頭的子鍵鍵值,可以看到更多的資訊:

例如 Service 表示的是該 USB 裝置是由系統服務 HidUSB 進行處理的,而系統服務 HidUSB 表示的是使用 USB 協議的人體工程學輸入裝置,只要有 USB 類的滑鼠、鍵盤、攝像頭等裝置連線到計算機,就會觸發一個特定於 HID 裝置的事件,HidUSB 服務會處理該事件,可以看到有 ClassGUID 這個鍵值,它的值 {745a17a0-74d3-11d0-b6fe-00a0c90f57da} 就是表示 Class 是 HIDClass 這樣的裝置。同樣的,對於 USB 儲存裝置,在接入時同樣會由一個服務予以處理,這個服務就是 USBSTOR 系統服務。以下列出了在 Enum\USB 下和 USB 裝置有關的服務名稱(還有其他的相關服務,這裡列出的是我的系統上有的):

Usbccgp:       USB 裝置控制器服務。
HidUsb:        USB 人體學工程輸入裝置服務。
USBSTOR:       USB 儲存裝置服務。
Usbhub:        USB 裝置介面服務。
WUDFRd:        使用者模式驅動框架反射器相關的服務,當連線只能手機等裝置時,該服務會進行處理。
VboxUsb:       安裝 Oracle 的 VM VirtualBox 虛擬機器軟體後會出現該服務,用於處理連線到虛擬機器的 USB 裝置。

在本文中,只檢測了 USBSTOR、WUDFRd、VboxUsb服務所處理的 USB 裝置。對於 Enum\USBSTOR 子鍵的鍵值,其結構和 Enum\USB 下的鍵值結構類似。在 USB、USBSTOR 的子鍵鍵值中有FriendlyName 這個鍵值,它表示的是裝置的友好名稱,可以作為 USB 的裝置名稱來顯示。

第三節 刪除 USB 儲存裝置使用痕跡

檢測到之後便是刪除這些痕跡的問題。由於登錄檔的某些鍵值許可權是 SYSTEM 賬戶的,一般的管理員賬號許可權無法刪除,如果要想通過程式碼來刪除,必須取得 SYSTEM 許可權,一個方法是將執行刪除的程式碼做成程式後安裝為系統服務(Sysinterals 的工具 PsExec 也是利用了系統服務可以使用 SYSTEM 許可權的特性,使得啟動的程序繼承了 SYSTEM 許可權),系統服務是可以運行於 SYSTEM 許可權的,這樣對登錄檔就有了完全的控制權,可自由進行刪改(但是同時一定要注意不要刪除其他的登錄檔項,以避免麻煩)。如何使用 Visual Studio 製作系統服務呢,Step by Step。

1、右鍵單擊解決方案 USBView,選擇“新增”-“新建專案”,專案型別選擇“Windows 服務”,專案名稱命名為 USBCleaner,隨後在 IDE 自動生成的程式碼中會出現以下方法:

protected override void OnStart(string[] args)
protected override void OnStop()

分別表示服務啟動和停止時的事件處理過程。在這兩個事件處理過程中寫入刪除登錄檔鍵值的程式碼,邏輯和檢測時的一樣。在刪除過程中,我添加了一個日誌功能,記錄在執行刪除過程中成功和錯誤的資訊。為了在程式執行目錄下生成日誌檔案,需要在系統服務的執行過程中得到其所在路徑,網上查閱了一些資料,有許多獲取路徑的方法,自己實際用註冊服務的方式做了一下實驗,結果如下:

Assembly.GetExecutingAssembly().Location
D:\DATA\USBViewer\bin\Release\USBCleaner.exe

this.GetType( ).Assembly.Location
D:\DATA\USBViewer\bin\Release\USBCleaner.exe

Process.GetCurrentProcess().MainModule.FileName
D:\DATA\USBViewer\bin\Release\USBCleaner.exe

System.Environment.CurrentDirectory
C:\Windows\system32

System.AppDomain.CurrentDomain.BaseDirectory
D:\DATA\USBViewer\bin\Release\

System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase
D:\DATA\USBViewer\bin\Release\

System.IO.Directory.GetCurrentDirectory()
C:\Windows\system32

最後決定用 Assembly.GetExecutingAssembly().Location 這個方法,在 Windows 7 和 Windows XP 及 Windows Server 2003 上執行都能得到正確的結果。

在所有刪除程式碼都編寫完畢後,就是給服務新增安裝程式了。雙擊開啟 USBCleaner.cs,此時會顯示設計介面,在設計介面上單擊右鍵,選擇“新增安裝程式”,會為該服務專案新增用於服務安裝時的支援,這樣就可以通過程式碼來直接安裝和解除安裝服務了。

“新增安裝程式”這一步會在專案中自動新增兩個元件,一個是服務程序安裝類元件,另外一個是服務安裝類元件:

服務程序安裝類元件具有以下的屬性:

其中的“Account”屬性即是服務所執行的許可權級別,選擇“LocalSystem”,即可以使用 SYSTEM 許可權。另外一個是服務安裝類元件,屬性如下:

其中的幾個關鍵屬性:

Description	用於該服務的簡短描述。
DisplayName	顯示在服務列表中的顯示名稱。
ServiceName	服務的名稱,系統使用該名稱唯一標識該服務,不能和已有的服務衝突。
StartType	表示服務的啟動方式,可以是自動、手動、禁用。

設定完畢後,生成 USBCleaner,得到一個 EXE 檔案:

接下來就是在專案 USBViewer 中對 USBCleaner.exe 進行安裝呼叫了。

如果是手動進行安裝,可以使用 .Net 框架提供的工具:InstallUtil.exe 程式,對於 .Net Framework 4.0 來說,它一般位於:

SystemRoot%\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe

使用 /u 或 /uninstall 來解除安裝服務,不加引數則是安裝服務。但是要在程式中自動執行安裝和解除安裝服務,就需要使用 .Net 框架提供的 TransactedInstaller 類,它提供了的作用就是InstallUtil.exe 服務安裝工具所提供的功能。

為了程式碼更好的組織,我將檢測服務執行和安裝的程式碼統一放在 USBViewer 專案的 ServiceHelper.cs 檔案中。程式碼首先新增對以下兩個名稱空間的引用:

using System.Configuration.Install;
using System.ServiceProcess;

引用 System.Configuration.Install 的目的是使用 TransactedInstaller 類,該類的作用是以事務的方式對服務進行安裝或解除安裝,要麼安裝或解除安裝成功,要麼回到安裝前的狀態。在進行操作前常規對服務進行一下檢測,看服務是否已經存在,這裡使用了 ServiceController 類對服務名進行輪詢,只要查詢到具有指定名稱的服務,就可以知道服務已經存在了。

/// 
/// 檢測服務是否安裝。
/// 
/// 要查詢的服務名。
/// 
private static bool IsWindowsServiceInstalled(string serviceName)
{
  ServiceController[] services = ServiceController.GetServices();
  foreach (ServiceController service in services)
  {
    if (service.ServiceName == serviceName)
    return true;
  }
  return false;
}

安裝服務則按以下方式呼叫 TransactedInstaller 類:

string[] cmdline = {};
TransactedInstaller transactedInstaller = new TransactedInstaller();
AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
transactedInstaller.Installers.Add(assemblyInstaller);
transactedInstaller.Install(new System.Collections.Hashtable());

注意 Install 方法需要一個 IDictionary 介面型別的變數來儲存安裝狀態,這裡使用了雜湊表。解除安裝服務和安裝服務時類似,不過是呼叫 Uninstall 方法,而且可以不用提供儲存狀態的變數。

transactedInstaller.Uninstall(null);

在安裝和解除安裝前,不要忘記對要安裝和解除安裝的服務檔案進行檢測,確保該檔案確實存在。

// 檢測相應的服務檔案是否存在。
string serviceFileName = Path.Combine(Application.StartupPath, "USBCleaner.exe");
if (File.Exists(serviceFileName) == false)
  return false;

第四節 執行測試

對專案 USBViewer 進行編譯,得到一個 EXE 檔案:

因為在刪除過程中要安裝系統服務,執行本程式,需要系統管理員許可權,這在 Windows XP 和 Windows Server 2003 等作業系統上,需要以管理員賬戶登入系統後使用。在 Windows Vista 或 Windows 7 以上的作業系統,由於 UAC (使用者賬戶控制)的問題,可能程式無法執行,畢竟Windows Vista 以上的系統對系統安全性做了進一步增加,對登錄檔等敏感資料的操作做了進一步的限制,要使得程式能夠正常執行,一個方法可以通過右鍵單擊程式,在“相容性”選項卡,選擇“以管理員身份執行本程式”。

或者在每次執行程式時,單擊右鍵選擇“以管理員身份執行”。

另外一種方法是使用 app.manifest 檔案的方式,把程式執行所需要的許可權事先宣告,這樣就可以避免 Windows UAC 的控制阻攔問題了。具體方法是:在專案 USBViewer 右鍵單擊,選擇“屬性”-“安全性”,勾選“啟用 ClickOnce 安全設定”,

這時會自動為專案新增一個 app.manifest 檔案(在專案的 Property 資料夾下),開啟該檔案,找到

將其中的 asInvoker 替換為 requireAdministrator,

儲存編譯專案。注意在儲存編譯專案前,注意要取消勾選專案安全性中的“啟用 ClickOnce 安全設定”,否則編譯會出錯(取消勾選並不會刪除已經生成的 app.manifest 檔案)。這樣程式就會自動以管理員許可權運行了。

解決了許可權的問題後,將刪除 USB 儲存裝置使用痕跡的服務程式 USBCleaner.exe 複製到 USBViewer.exe 所在資料夾下,執行 USBViewer.exe,結果如下:

執行刪除操作,可以看到系統服務列表裡出現了顯示名稱為 USB Cleaner 的服務:

檢視其屬性,確實是執行登錄檔刪除操作的服務。

點選“退出”按鈕,稍等程式對服務進行解除安裝,然後再次檢視一下系統服務列表,發現 USB Cleaner 服務被解除安裝了。檢查 USBViewer.exe 檔案所在資料夾,會發現多了兩個檔案,一個是 USBCleanerLog.txt,它是執行刪除操作的日誌檔案:

而另外一個檔案 USBCleaner.InstallLog 則是在執行安裝和解除安裝服務時產生的日誌檔案,可開啟檢視其中的內容。

第五節 小結

通過此次 C# WindowsForm程式設計練習,進一步熟練了C#的使用,對登錄檔的操作和 Windows服務的安裝及解除安裝有了進一步的瞭解,同時對相關的知識做了一番梳理,有利於自己程式設計水平的提高(本文所涉及的解決方案檔案已壓縮為 RAR格式的壓縮檔案以供下載,下載連結:http://download.csdn.net/detail/metaphysis/6864213)

相關推薦

C# 編寫 USB 儲存裝置使用痕跡檢測刪除工具

編寫 USB 儲存裝置使用痕跡檢測和刪除工具 (C# Windows Form 程式設計練習) [版權所有 邱秋 2014 [email protected], 轉載請註明出處] 第一節 準

C++如何調C#編寫的 DLL

csharp class 配置 copy pac print pre lec visual 由於C#編繹出來的DLL不是計算機所能直接識別的二進制指令碼,需要CLS進行再解釋,說到這,我想有些朋友應該知道C#項目需要引用C++編寫的DLL時,可以直接引用DLLMPORT來

C#動態調C++編寫的DLL函數

acf char cbe cfm ria als cto b2c tar 最長公共子序列Lcs---51--Nod 狂曬C++疑問,專家幫你解答,還有更美的事麽?! 再發對於EOF的理解,Windows下面ctrl+z的WM_CHAR值為26! Scratch第一課:

C++項目中采CLR的方式調C#編寫的dll

%s dll single 目錄 復制 result 報文 clas sin 1、註意事項:在編寫C#DLL類庫時,最好不要出現相同的命名空間,否則在C++中調用可能會出現編譯錯誤。2、將C#的源碼生成的“dll”文件復制到C++項目中的Debug目錄下3、將C++項目屬性

C# 編寫 NEO 智能合約

IE nbsp 如果 嘗試 咨詢 菜單 neo 開發 lin 工具 -> 擴展和更新安裝 NeoContractPlugin 插件 打開 Visual Studio 2017,打開 工具, 擴展和更新 ,在左側點擊 聯機 ,搜索 Neo,安裝 NeoContr

JavaScript學習筆記之JavaScript調C#編寫的COM組件

nts 註意 int 類名 彈出 互操作 ces sse dll 1、新建一個C#類庫項目:MyCom; 2、修改 Properties 目錄下的 AssemblyInfo.cs(程序集文件) 中的 ComVisible 屬性為 true; 3、項目->屬性-

使用libpcap庫c編寫網路嗅探器

定義:網路嗅探也叫網路偵聽,指的是使用特定的網路協議來分解捕獲到的資料包,並根據對應的網路協議識別對應資料片斷 作用:管理員可以用來監聽網路的流量情況            開發網路應用的程式設計師可以

c編寫的一些程式

**1.列印100~200 之間的素數 ** 判斷一個數是否為一個素數,我呼叫<math.h>中的sqrt(x)的寫法,正是因為一個數的因數是成對出現的,所以開方後就只需要判斷它的前一半可以減少一些迴圈次數。 #include <stdio.h> #include

樹莓派Raspberry Pi實戰之命令列下實現USB儲存裝置自動掛載

簡單介紹實現命令列下USB儲存裝置自動掛載的方法,Linux gnome/kde視窗環境下有移動儲存的管理程式,可以實現自動掛載移動儲存裝置,但是在命令列下 通常需要用mount命令手動掛載USB儲存裝置。   通過給linux下的裝置管理服務udev新增規則配置檔案,可以實現命令列下U

C++編寫thrift第一個例子

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C++編寫 動態鏈接庫dll 調dll

.net .html 新建項目 引用 quest c++ dll 遇到 eat 參考:https://jingyan.baidu.com/article/ff42efa92c49cfc19e2202fd.html 和htps://jingyan.baidu.com/a

C# 編寫 C# 編譯器,先有雞還是先有蛋?

前段時間翻譯了一篇文章 微軟是如何重寫 C# 編譯器並使它開源的,文章講了微軟用 C# 重寫 C# 編譯器的坎坷路,引發了一些童鞋的思考:用 C# 編寫 C# 編譯器(Roslyn),那麼 C# 編譯器本身是由誰來編譯的?C# 語言編寫了 C# 編譯器,而 C# 語言又是由 C# 編譯器編譯的,這不就是先

C++編寫數制轉換(鏈式表)

> 程式設計小白,多多包涵 #include<iostream> #include<stack> using namespace std; typedef struct StackNode { int data; struc

C++ STM32 程式設計 005 c++編寫STM32程式的準備

        由於我們使用的是 ARM 的工具鏈 是gcc的,所以,我們大可以用c++來編寫程式,無論是 c++99 或c++11 還是 c++14,都是可以的。另外在 HAL 庫中,幾乎每個 .h標頭檔案都有這種巨集 #ifdef __cplusplu

在樹莓派下的opencvC++)對視訊做人臉檢測人臉模糊處理

#include "opencv2/objdetect.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <iostream> #include &

linux下C編寫ftp客戶端

這是一個大作業,要求能夠模擬ftp協議,實現一個ftp客戶端,然後要求能夠實現相應的功能,主要是能夠實現ls,pwd,cwd(cd),put和get功能。然後是在被動模式下來實現這些功能。那麼首先我們需要對ftp協議有一個具體的瞭解,然後才能夠自己實現這個功能。 FTP

在Centos下c++編寫簡單程式並輸出

小白我使用的是VMware-Workstation虛擬機器建立的centos。苦於無法用來學習(裝逼),抽空學習瞭如何在linux系統下程式設計。有不對的地方歡迎各位大佬指出,謝謝。首先開啟centos

C++編寫小學生隨機十道練習題的步驟以及原始碼

程式要求: 設計一個程式,用來實現幫助小學生進行算術運算練習,它具有以下功能: (1) 提供10道加、減、乘、除四種基本算術運算的題目,每道題中的運算元是隨機產生的; (2) 加減是100以內的數;乘除為乘法表裡的;被減數大於減數;除法要求能整除;被乘數小與乘數;(若不合格

c#編寫socks代理伺服器,大白話細述協議的最重要部分。

由於我是個粗人,是個菜鳥,只會講大白話,只想知道咱老百姓想聽的內容。 不知道為什麼那些網文作者都說socks代理比http代理複雜,http代理和socks代理我都做了,明顯感覺http代理比socks代理要複雜很多,因為http代理要自己解析http協議,這是我的http

linux下C編寫的基於smtp的帶附件郵件傳送程式

         今天做了一個簡單的stmp郵件傳送的客戶端demo,可以支援帶附件傳送,希望將實現分享一下, 目前測試環境是公司的內部郵箱,  有gmail郵箱測試沒有成功, 可能gmail郵箱需要ssl加密,後續再進行完善吧, 這個demo實現的非常簡單的阻塞的傳送傳送