搞了一天,在网上看了很多,发现这种比较少有,高手都不屑来写,所以记录一下,给自己那些有需要的人。
主要是受到文章点击打开链接的启发,基本属于实践和翻译。
不多说,方法一,借用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多兆,写了大概两分钟时间才写完。方法二未做过验证。