天天看點

VBS建立二進制檔案的兩種方法

搞了一天,在網上看了很多,發現這種比較少有,高手都不屑來寫,是以記錄一下,給自己那些有需要的人。

主要是受到文章點選打開連結的啟發,基本屬于實踐和翻譯。

不多說,方法一,借用ADODB.Stream,具體實作如下:

'首先定義一些檔案打開和寫入方式
Const adTypeBinary = 1 '二進制
Const adTypeText = 2   '文本方式
Const adSaveCreateNotExist = 1  '建立儲存
Const adSaveCreateOverwrite = 2 '檔案本身存在,覆寫儲存

'這是一個子過程,判斷檔案是否存在,并删除
'傳入參數: File----待判定的檔案路徑
Sub DeleteIfExists(File)
    Set fso = CreateObject("Scripting.FileSystemObject") '使用OCX對象輔助
    if (fso.FileExists(File)) Then     '判斷檔案是否存在
        fso.DeleteFile File, true      '存在就删除
    End if
End Sub

'這是一個子過程,用于建立二進制木馬檔案
'傳入參數: File----存儲的二進制檔案路徑
Sub CreateExeFile(File)
    Set ados = CreateObject("ADODB.Stream") '使用OCX對象輔助
    ados.Type = adTypeText                  '使用方式必須為Text,否則無法直接寫構造的二進制資料
    ados.Open                               '打開流
    ados.WriteText ChrB(&h50) & ChrB(&h4B) & ChrB(&h05) & ChrB(&h06) '寫入二進制文本,每個位元組用ChrB(&hxx)的方式,而連接配接使用&操作符
    '此處繼續寫木馬的二進制資料,一般情況下,一行不适合寫太多,一般寫幾十個位元組。如我們寫一個空zip檔案
    For i=1 to 18
        ados.WriteText ChrB(&h0)
    Next
    ados.SaveToFile File, adSaveCreateNotExist '存檔案
    ados.Close                                 '關閉流

    '因為以ados.Type=2的時候,寫出的檔案會被在頭部多加兩個位元組。
    '而二進制的方式寫檔案,傳入參數又要為Bytes類型數組,不能為構造的二進制資料。
    ados.Open                  '打開流
    ados.Type = adTypeBinary   '設定二進制方式讀寫
    ados.LoadFromFile File     '讀取檔案
    ados.Position = 2          '設定偏移為,跳過前面多加的兩個位元組
    arrBytes = ados.Read       '變量arrBytes為讀取的傳回,為Bytes類型的數組
    ados.Position = 0          
    ados.SetEOS                '這兩步正确也必要,不過沒有懂,感覺應該是設定寫入位置為起始,同時結束讀取流
    ados.Write arrBytes        '将Bytes的數組寫入到流
    ados.SaveToFile File, adSaveCreateOverwrite '将流中資料儲存到檔案中,以覆寫方式
    ados.Close                 '關閉流
End Sub

Dim wsh
Set wsh = CreateObject("WScript.Shell") '打開一個WSH對象
TempDir = wsh.expandEnvironmentStrings("%TEMP%") '将TempDir指派為%TEMP%環境變量的展開值
FilePath = TempDir & "\Test.zip"      '設定檔案路徑為%temp%目錄下
DeleteIfExists FilePath               '如果原本存在,删除檔案
CreateExeFile FilePath                '建立檔案

'如果為exe檔案,可以進行下面的操作...
'ExeCmd = Chr(34) & FilePath & Chr(34) '在Run的參數(檔案全路徑)兩端加上引号
'wsh.Run ExeCmd                        '運作exe檔案
           

這種方法有一個弊端,會将檔案兩次寫向磁盤,第二種方法沒有這個問題,借助Scripting.FileSystemObject,同樣以記錄一個空的zip檔案為例。

strPath = "C:\Zip.zip"

Set objFso = CreateObject("Scripting.FileSystemObject") '使用FileSystemObject
'使用OpenTextFile打開檔案得到的對象,第三個參數設定為True,則建立一個新的空檔案檔案到磁盤
With objFso.OpenTextFile(strPath, 2, True)  
   '接下來循環向新檔案寫資料,使用一個方法,将十六進制字元串兩個兩個的取出,并在前面加上&h,然後轉換為十進制數字(Clng),之後直接寫入。
   For x = 1 To 44 Step 2
      .Write Chr(Clng("&h" & Mid("504B0506000000000000000000000000000000000000",x,2)))
   Next
   .Close '關閉檔案
End With  '檔案對象使用完畢
           

因為是寫小檔案,未對效率做過多驗證。這兩種方法下,大檔案測試過方法180多兆,寫了大概兩分鐘時間才寫完。方法二未做過驗證。