VBScriptを暗号化（難読化）する方法で気付いた注意点

# 今回の方法
[Encode and Decode a VB script](https://gallery.technet.microsoft.com/Encode-and-Decode-a-VB-a480d74c#content)
[正常なファイルがウイルスとして検知された場合（誤認）の対処方法](https://service.mcafee.com/webcenter/portal/cp/home/articleview;jsessionid=Led49Z5DjGIsO8p5bTBRWZJTKEfPcvPSijoExSBs4qoP1GuZsSQg!-1600135695!-1155889578?locale=ja-JP&articleId=TS101715&_afrLoop=376254528563124#!%40%40%3F_afrLoop%3D376254528563124%26articleId%3DTS101715%26centerWidth%3D100%2525%26leftWidth%3D0%2525%26locale%3Dja-JP%26rightWidth%3D0%2525%26showFooter%3Dfalse%26showHeader%3Dfalse%26_adf.ctrl-state%3D148rvmx0wa_4)
MACAFEEでは標準だとVBEになると隔離されてしまう。
また、Script Encoderはエンコードしたものをデコードはできない。基本はもとに戻せないのでバックアップすること。
また、この記事でいうエンコードとは暗号化の意味である。しかし、これは2009年までで、2020年には難読化と訳すべきと思われる。


## 役立たないVBA版
### VBSをVBEに変換する
ドラッグアンドドロップではないのでファイル名は指定である。
Microsoft Scripting Runtimeを参照設定すること。
C:\hoge\test.vbsからC:\hoge\test.vbeを作成します。

```vb:VbEncode
Sub VBSEncode()
Dim oEncoder As New Scripting.Encoder, oFilesToEncode, sfile As String, sDest
Dim sFileOut, oFile As file, oEncFile, oFSO As New Scripting.FileSystemObject, i
Dim oStream, sSourceFile

Const sPath = "C:\hoge"
'Set oEncoder = CreateObject("Scripting.Encoder")
'   Set oFSO = CreateObject("Scripting.FileSystemObject")
   sfile = sPath & "\test.vbs"
    Set oFile = oFSO.GetFile(sfile)
     Set oStream = oFile.OpenAsTextStream(1)
    sSourceFile = oStream.ReadAll
    oStream.Close
    sDest = oEncoder.EncodeScriptFile(".vbs", sSourceFile, 0, "")
    sFileOut = Left(sfile, Len(sfile) - 3) & "vbe"
    Set oEncFile = oFSO.CreateTextFile(sFileOut)
    oEncFile.Write sDest
    oEncFile.Close
End Sub
```
# このスクリプトの注意点？
マカフィーに食われてしまうのもそうだが、もっとも重要な点はVBSがANSIテキスト形式であること。が挙げられる。ユニコード形式とかだとうまくいかないときがある。これどこにも書いていないので間違いなのかもしれないが。

# 歴史
[WindowsでWSHスクリプトコードを暗号化する ＠IT クラウド Windows Server Insider Tech Tips](http://www.atmarkit.co.jp/ait/articles/0406/26/news016.html)
は2004年の記事であるが。Windows Script Encoder（日本語版）はもうダウンロードできない。
しかしながら
[VBScriptの暗号化](http://sammaya.jugem.jp/?eid=13)
では

>以前は Windows Script Encoder というツールがマイクロソフトから提供されていたが、現在はWindow OSに標準で暗号化機能が用意されている。scrrun.dllのEncoderオブジェクトを利用してVBScriptを暗号化するスクリプトを作成できる。

とのことである。実際上記のVBAはその機能を利用しているのである。

※20190224補足
[VBSをVBEに変換し暗号化する方法](https://qiita.com/Koki-Nakamura/items/550d80e655c7431d46be)
こちらはVBSでドラッグアンドドロップしてVBEに変換する。
この時コードをFilesystemobjectで書いているのを見ても、やはりS-Jisのようだ。

#### 参考リンク
[Encode a Script encode.vbs gallery.technet.microsoft.com](https://gallery.technet.microsoft.com/scriptcenter/16439c02-3296-4ec8-9134-6eb6fb599880 )
[スクリプト エンコーダの概要](https://docs.microsoft.com/ja-jp/previous-versions/windows/scripting/cc392170(v%3dmsdn.10))
[スクリプト エンコーダの構文](https://docs.microsoft.com/ja-jp/previous-versions/windows/scripting/cc392172%28v%3dmsdn.10%29)
[スクリプト エンコードのサンプル](https://docs.microsoft.com/ja-jp/previous-versions/windows/scripting/cc392168(v=msdn.10))
[OpenAsTextStream メソッド](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/openastextstream-method)


##### スクリプト エンコードのサンプルの補足

```html
<HTML>
<HEAD>
<TITLE>Script Encoder Sample Page</TITLE>
<SCRIPT LANGUAGE="JScript">
<!--//
//Copyright® 1998 Microsoft Corporation. All Rights Reserved.
//**Start Encode**
function verifyCorrectBrowser(){
  if(navigator.appName == "Microsoft Internet Explorer")
    if (navigator.appVersion.indexOf ("5.") >= 0)
      return(true);
    else
      return(false);
}
function getAppropriatePage(){
  var str1 = "Had this been an actual Web site, a page compatible with ";
  var str2 = "browsers other than ";
  var str3 = "Microsoft Internet Explorer 5.0 ";
  var str4 = "would have been loaded.";
  if (verifyCorrectBrowser())
    document.write(str1 + str3 + str4);
  else
    document.write(str1 + str2 + str3 + str4);
}
//-->
</SCRIPT>
</HEAD>
<BODY onload="getAppropriatePage()">
</BODY>
</HTML>
```

これはメモ帳を開き、まず拡張子をHTML、ANSI形式で保存する。
上記のHTMLをコピペして保存。
Microsoft Internet Explorerまたはedgeで開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/7c04304b-5335-1edc-943e-427c1583b843.png)
インストールされていれば、Explorerのホームタブの開くで切り替えることができる。

設定にもよるが、IEの場合、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/24ee6de2-f806-7798-ad47-4cddc7c52051.png)
という警告が出る。コードを確認してから許可すること。


##### スクリプトをエンコードする（発掘）
>Encode a Script
Uses the VBScript Encoder object to encode one or more VBScript scripts. Just drag and drop files to encode onto Encoder.vbs, and encoded copies (with a .vbe extension) will be c
>Submitted By: Shawn Stugart
Uses the VBScript Encoder object to encode one or more VBScript scripts. Just drag and drop files to encode onto Encoder.vbs, and encoded copies (with a .vbe extension) will be created in the same directory.

>VBScriptエンコーダオブジェクトを使用して、1つ以上のVBScriptスクリプトをエンコードします。ファイルをドラッグアンドドロップしてEncoder.vbsにエンコードするだけで、エンコードされたコピー（拡張子は.vbe）はcになります。
評価（4）
提出者： Shawn Stugart
VBScriptエンコーダオブジェクトを使用して、1つ以上のVBScriptスクリプトをエンコードします。ファイルをドラッグアンドドロップしてEncoder.vbsにエンコードするだけで、エンコードされたコピー（.vbe拡張子付き）が同じディレクトリに作成されます。

```vb
Option Explicit
Const ForReading = 1
Const TristateFalse = 0
dim oEncoder, oFilesToEncode, file, sDest
dim sFileOut, oFile, oEncFile, oFSO, i
dim oStream, sSourceFile

set oFilesToEncode = WScript.Arguments
set oEncoder = CreateObject("Scripting.Encoder")
For i = 0 to oFilesToEncode.Count - 1
    set oFSO = CreateObject("Scripting.FileSystemObject")
    file = oFilesToEncode(i)
    set oFile = oFSO.GetFile(file)
    Set oStream = oFile.OpenAsTextStream(ForReading, TristateFalse)
    sSourceFile=oStream.ReadAll 
    oStream.Close 
    sDest = oEncoder.EncodeScriptFile(".vbs",sSourceFile,0,"") 
    sFileOut = Left(file, Len(file) - 3) & "vbe" 
    Set oEncFile = oFSO.CreateTextFile(sFileOut) 
    oEncFile.Write sDest 
    oEncFile.Close 
Next 
```

復元するに当たり、わかりやすいように定数を加えたが、原文のスクリプトは`Set oStream = oFile.OpenAsTextStream(1)`となっている。つまりASCIIであることがわかる。

### Decodeと文字コード
[VBScript の難読化と解除](https://qiita.com/yoshi389111/items/7e4cfcf95ad986c56dcf)
日本語が入れば不可能だったDecodeに成功していた。
https://gallery.technet.microsoft.com/Encode-and-Decode-a-VB-a480d74c
元になっているコードのサイトは現存しない。
ただ、このデコードでもやはり、ANSIなのは確認できる。

#### メモ帳(NOTEPAD.exe)の文字コード
[メモ帳の既定の文字コードが［UTF-8］に（ショートカットキーも追加）- hamachan.info](https://hamachan.info/win10-win-memoutf/)
2020年のWindows10 Version 1903以降のメモ帳はUTF-8がデフォルトになっている。
このままVBSを作成するとエラーになるため、保存するときにANSIに変更する必要がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/5d73ebf6-54cf-7c77-01d0-5561df99e848.png)



##### 変更履歴
vbnetではコードが装飾されないのでVBに変更
また参考リンクの増加、記述を若干みなおし。
htmlのサンプルの作成方法を補足。(2022/07/15)
公式がコードサンプルを削除したので発掘。(2022/07/15)
メモ帳の文字コードのデフォルトの変更を注意喚起(2022/07/15)