iResEditor.jsの使い方
[目次]
1. ファイルの読み込み
2. ファイルの書き込み
3. 各クラスの詳細
TResEditor
TPEAnalyst
はじめに
iResEditor.jsは ダウンロード してあなたの環境に設置して下さい。
ここでは基本的な使い方をご紹介しますが、ある程度の「PEフォーマット」「各リソースフォーマット」の知識がないと、このクラスライブラリを扱うのは難しいかも知れません。
1. ファイルの読み込み
実行ファイルを読み込んで結果をブラウザのコンソールに出力します。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="zip.min.js"></script> <script src="iResEditor.js"></script> <script> function onDragOver(event){ event.preventDefault(); } function onDrop(event){ onAddFile(event); event.preventDefault(); } function onAddFile(event) { var files; var reader = new FileReader(); var filename; if(event.target.files){ files = event.target.files; }else{ files = event.dataTransfer.files; } reader.onload = function (event) { var stream = new Uint8Array(reader.result); try{ // PEファイルの読み込み var ResEditor = new TResEditor(filename); ResEditor.LoadFromStream(stream,true,true); // コンソールに出力 console.log(ResEditor); }catch(e){ alert('Error : ' + e); } }; if (files[0]){ filename = files[0].name; reader.readAsArrayBuffer(files[0]); document.getElementById("inputfile").value = ''; } } </script> </head> <body ondrop="onDrop(event);" ondragover="onDragOver(event);"> <div style="height:500px;width:500px;"> <input type="file" id="inputfile" onchange="onAddFile(event);" > </div> </body> </html>
[結果]
次の図はChromeでのコンソールです。
※コンソールを表示するにはブラウザでF12キーを押します。

Editプロパティにあるリソースは編集可能です。
PEAnalystプロパティは実行ファイルのヘッダ情報とリソース、インポート、エキスポート情報などが格納されます。
2. ファイルの書き込み
次のコードは「Menu,Dialog,String Table」の全てのリソースに「add」の文字列を追加します。編集が完了したらファイルを出力します。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="zip.min.js"></script> <script src="iResEditor.js"></script> <script> function onDragOver(event){ event.preventDefault(); } function onDrop(event){ onAddFile(event); event.preventDefault(); } function onAddFile(event) { var files; var reader = new FileReader(); var filename; if(event.target.files){ files = event.target.files; }else{ files = event.dataTransfer.files; } reader.onload = function (event) { var stream = new Uint8Array(reader.result); var addString = ' add'; // 追加する文字列 try{ // PEファイルの読み込み var ResEditor = new TResEditor(filename); ResEditor.LoadFromStream(stream,true,true); console.log(ResEditor); if(ResEditor.PEAnalyst.IsPacked){ alert('このファイルは圧縮されています。'); return; } if(ResEditor.Edit.Menu.length === 0 && ResEditor.Edit.Dialog.length === 0 && ResEditor.Edit.String.length === 0){ alert('このファイルには編集可能なリソースはありません。'); return; } // 全ての「Menu」の文字列を変更する var Menu = ResEditor.Edit.Menu; if(Menu.length !==0){ for(var i=0;i<Menu.length;i++){ for(var j=0;j<Menu[i].resObject.Items.length;j++){ // セパレータ以外 if(Menu[i].resObject.Items[j].menuText !== '-'){ Menu[i].resObject.Items[j].menuText = Menu[i].resObject.Items[j].menuText + addString; } } } }else{ console.log('Menu None'); } // 全ての「Dialog」の文字列を変更する var Dialog = ResEditor.Edit.Dialog; if(Dialog.length !==0){ var DS_SETFONT = 64; for(var i=0;i<Dialog.length;i++){ // 通常版と拡張版 var DlgTemplate,DlgItemTemplate; if(Dialog[i].resObject.DlgTemplate){ DlgTemplate = Dialog[i].resObject.DlgTemplate; DlgItemTemplate = Dialog[i].resObject.DlgItemTemplate; }else{ DlgTemplate = Dialog[i].resObject.DlgTemplateEx; DlgItemTemplate = Dialog[i].resObject.DlgItemTemplateEx; } // 親ウインドウの文字列の変更 DlgTemplate.title = DlgTemplate.title + addString; // フォントがある場合 if((DlgTemplate.style & DS_SETFONT) === DS_SETFONT){ // フォント名の変更 // DlgTemplate.typeface = 'font name'; // フォントサイズの変更 // DlgTemplate.pointsize = 8; } // コントロール for(var j=0;j<DlgItemTemplate.length;j++){ // 文字列型 if(typeof DlgItemTemplate[j].title === "string"){ DlgItemTemplate[j].title = DlgItemTemplate[j].title + addString; } } } }else{ console.log('Dialog None'); } // 全ての「String Table」の文字列を変更する var StringTable = ResEditor.Edit.String; if(StringTable.length !==0){ for(var i=0;i<StringTable.length;i++){ for(var j=0;j<StringTable[i].resObject.ID.length;j++){ // NULL以外 if(StringTable[i].resObject.Value[j] !== ''){ StringTable[i].resObject.Value[j] = StringTable[i].resObject.Value[j] + addString; } } } }else{ console.log('String Table None'); } // この1つのメソッドでも保存できます。 // ただし、IE/Edgeではセキュリティ制限でダウンロードできません。 // ResEditor.SaveToFile('test.exe'); var zip = new Zlib.Zip(); var stream = ResEditor.SaveToStream(); // 拡張子の取得 var ext = ResEditor.FileName.split('.'); ext = '.' + ext[ext.length-1]; // ZIP(無圧縮) zip.addFile(stream,{'filename': PE_ConvertArray('test' + ext), 'compressionMethod':Zlib.Zip.CompressionMethod.STORE}); var compressed = zip.compress(); // ダウンロード var F = new TFileStream(); F.WriteStream(compressed); F.SaveToFile('test.zip'); }catch(e){ alert('Error : ' + e); } }; if (files[0]){ filename = files[0].name; reader.readAsArrayBuffer(files[0]); document.getElementById("inputfile").value = ''; } } </script> </head> <body ondrop="onDrop(event);" ondragover="onDragOver(event);"> <div style="height:500px;width:500px;"> <input type="file" id="inputfile" onchange="onAddFile(event);" > </div> </body> </html>
3. 各クラスの詳細
コアクラスはTPEAnalystです。TResEditorはTPEAnalstのラッパークラスです。
[TResEditor]
プロパティ | 用途 |
---|---|
(Edit) | 編集可能なリソース(Menu,Dialog,String Table) ※resNameID,resLangIDは変更不可。 |
FileName | 読み込んだファイル名。 |
OS | 実行ファイルの対象OS。(32bit or 64bit) |
PEAnalyst | TPEAnalyst |
※()のプロパティは設定により存在しない場合があります。
メソッド | LoadFromStream(AStream, ResourceFlg [,PackedFlg]) |
---|---|
用途 | 実行ファイルを読み込みます。 |
引数 | AStream : Uint8Array ResourceFlg : true Editプロパティを追加する PackedFlg : true 実行ファイルの圧縮判定をする(省略はtrue) |
戻り値 | なし |
メソッド | SaveToStream() |
---|---|
用途 | TResEditor.Editの内容で実行ファイルをストリームで出力します。 |
引数 | なし |
戻り値 | Uint8Array |
メソッド | SaveToFile(FileName) |
---|---|
用途 | TResEditor.Editの内容で実行ファイルを出力します。 |
引数 | FileName: ファイル名 |
戻り値 | なし |
メソッド | SaveImportTEXT(FileName) |
---|---|
用途 | 全てのインポート情報をテキスト形式で出力する。 |
引数 | FileName: ファイル名 |
戻り値 | true : 成功 false : 失敗 |
メソッド | SaveExportCSV(FileName) |
---|---|
用途 | 全てのエキスポート情報をCSV形式で出力する。 |
引数 | FileName: ファイル名 |
戻り値 | true : 成功 false : 失敗 |
メソッド | ExtractBinFile(ZipFileName) |
---|---|
用途 | 全てのリソースをバイナリファイル(RAW)で出力する。 |
引数 | ZipFileName: ZIPファイル名 |
戻り値 | true : 成功 false : 失敗 |
[TPEAnalyst]
プロパティ | 用途 |
---|---|
Export | エキスポート情報 |
IMAGE_COFF_HEADER | IMAGE_COFF_HEADER構造体 |
IMAGE_DOS_HEADER | IMAGE_DOS_HEADER構造体 |
IMAGE_OPTIONAL_HEADER | IMAGE_OPTIONAL_HEADER構造体 |
IMAGE_SECTION_HEADER | IMAGE_SECTION_HEADER構造体 |
Import | インポート情報 |
(IsPacked) | 実行ファイルが圧縮されているかのフラグ(true or false) ※簡易判定なのでUPXとAsPackにしか対応していません。 ※TResEditor.LoadFromStreamでPackedFlgをtrueにした場合にこのプロパティが使用できます。 |
(Resource) | リソース ※このリソースは読み込み専用です。 |
Stream | TReadStream。実行ファイルの内容を読み取ります。 |
※()のプロパティは存在しない場合があります。
その他
次のサンプルはブログで公開しています。
リソースをRCファイルへ変換する
リソースをRESファイルへ変換する
コードセクションを抽出する
データセクションを抽出する
全てのセクションを抽出する
隠しコードを取得する
リソースをTreeViewで表示する