How to use iResEditor.js
[Table of contents]
1. Loading files
2. Writing of files
3. Details of each class
TResEditor
TPEAnalyst
First
You download iResEditor.js, and install in your environment.
Here we introduce the basic usage.
But when there is no knowledge of a certain degree of "PE format" and "each resource format", it may be difficult to use this class library.
1. Loading files
Load the executable file. Outputs the results to the browser console.
<!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{ // Reading of PE files var ResEditor = new TResEditor(filename); ResEditor.LoadFromStream(stream,true,true); // Console to output 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>
[Result]
Following figure shows the console in Chrome.
To view the console, press the F12 key in your browser.

Resources in "Edit" property can be edit.
"PEAnalyst" property contains information such as the "header information of the executable file" and "resources" and "import", "export".
2. Writing of files
Following code adds character string of "add" to all resources of "Menu,Dialog,String Table". And, output.
<!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'; // String to add try{ // Reading of PE files var ResEditor = new TResEditor(filename); ResEditor.LoadFromStream(stream,true,true); console.log(ResEditor); if(ResEditor.PEAnalyst.IsPacked){ alert('This file is compressed.'); return; } if(ResEditor.Edit.Menu.length === 0 && ResEditor.Edit.Dialog.length === 0 && ResEditor.Edit.String.length === 0){ alert('There is no editable resources in this file.'); return; } // Change the string of all of the "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++){ // Other than the separator 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'); } // Change the string of all of the "Dialog" var Dialog = ResEditor.Edit.Dialog; if(Dialog.length !==0){ var DS_SETFONT = 64; for(var i=0;i<Dialog.length;i++){ // Normal version and Extension version 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; } // Change of string of parent window DlgTemplate.title = DlgTemplate.title + addString; // If there is a font if((DlgTemplate.style & DS_SETFONT) === DS_SETFONT){ // Change font name // DlgTemplate.typeface = 'font name'; // Change font size // DlgTemplate.pointsize = 8; } // Control for(var j=0;j<DlgItemTemplate.length;j++){ // String type if(typeof DlgItemTemplate[j].title === "string"){ DlgItemTemplate[j].title = DlgItemTemplate[j].title + addString; } } } }else{ console.log('Dialog None'); } // Change the string of all of the "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++){ // Non-NULL if(StringTable[i].resObject.Value[j] !== ''){ StringTable[i].resObject.Value[j] = StringTable[i].resObject.Value[j] + addString; } } } }else{ console.log('String Table None'); } // You can save in this one method. // However, IE / Edge can not be downloaded in the security restrictions. // ResEditor.SaveToFile('test.exe'); var zip = new Zlib.Zip(); var stream = ResEditor.SaveToStream(); // Acquisition of extension var ext = ResEditor.FileName.split('.'); ext = '.' + ext[ext.length-1]; // ZIP (Uncompressed) zip.addFile(stream,{'filename': PE_ConvertArray('test' + ext), 'compressionMethod':Zlib.Zip.CompressionMethod.STORE}); var compressed = zip.compress(); // download 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. Details of each class
Core class is TPEAnalyst. TResEditor is a wrapper class of TPEAnalst.
[TResEditor]
Property | Use |
---|---|
(Edit) | Editable resources (Menu,Dialog,String Table) resNameID, resLangID can not be changed. |
FileName | Read file name. |
OS | Target OS of the executable file. (32bit or 64bit) |
PEAnalyst | TPEAnalyst |
() of Property may not exist depending on the setting.
Method | LoadFromStream(AStream, ResourceFlg [,PackedFlg]) |
---|---|
Use | Load the executable file. |
Argument | AStream : Uint8Array ResourceFlg : true Add the Edit Properties PackedFlg : true Simple Pack tool judgment (Omitted true) |
Return value | None |
Method | SaveToStream() |
---|---|
Use | Outputs the execution file at the stream with the contents of the TResEditor.Edit. |
Argument | None |
Return value | Uint8Array |
Method | SaveToFile(FileName) |
---|---|
Use | Outputs an executable file with the contents of the TResEditor.Edit. |
Argument | FileName: file name |
Return value | None |
Method | SaveImportTEXT(FileName) |
---|---|
Use | Outputs, all of the "import" information in text format. |
Argument | FileName: file name |
Return value | true : success, false : error |
Method | SaveExportCSV(FileName) |
---|---|
Use | Outputs, all of the "export" information in csv format. |
Argument | FileName: file name |
Return value | true : success, false : error |
Method | ExtractBinFile(ZipFileName) |
---|---|
Use | Outputs, all of the resources in a binary file (RAW). |
Argument | ZipFileName: ZIP file name |
Return value | true : success, false : error |
[TPEAnalyst]
Property | Use |
---|---|
Export | Export information |
IMAGE_COFF_HEADER | IMAGE_COFF_HEADER Structure |
IMAGE_DOS_HEADER | IMAGE_DOS_HEADER Structure |
IMAGE_OPTIONAL_HEADER | IMAGE_OPTIONAL_HEADER Structure |
IMAGE_SECTION_HEADER | IMAGE_SECTION_HEADER Structure |
Import | Import information |
(IsPacked) | Compression flag. (true or false) Simple Pack tool judgment (only, UPX and AsPack). This property can be used if "PackedFlg = true" in TResEditor.LoadFromStream. |
(Resource) | Resource This resource is read-only. |
Stream | TReadStream. (see, source code) Read the contents of the executable file. |
() of property may not exist.
Other
The following sample has published in the blog. (only Japanese)
Convert resource into the RC file
Convert resource into the RES file
Extract the code section
Extract the data section
Extract all section
Get the hidden code
View the resources in the ListView