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で表示する

