Last active
November 30, 2020 20:06
-
-
Save liath/c148ce9f72a64457150e16f2a880e7c4 to your computer and use it in GitHub Desktop.
Revisions
-
liath revised this gist
Dec 1, 2020 . 1 changed file with 6 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -19,8 +19,8 @@ const header = { for (let i = 0; i < header.sections; i += 1) { const offset = at + 0x18 + header.sizeOfOptionalHeader + (i * 0x28); const vaddr = file.readUInt32LE(offset + 0xc); const addr = file.readUInt32LE(offset + 0x14); const name = file.toString('utf-8', offset, offset + 8).split('\0').shift(); if (name === '.rsrc') { @@ -94,13 +94,14 @@ if (readUTF16String(at + 0x6) !== 'VS_VERSION_INFO') { } const parseStringFileInfo = (offset) => { const entrySize = file.readUInt16LE(offset + 0x2); const name = readUTF16String(offset + 0x6); const valueOffset = dwordAlign(offset + 0x6 + utf16len(name), at); return { totalSize: file.readUInt16LE(offset), name, value: entrySize ? readUTF16String(valueOffset) : null, }; }; -
liath created this gist
Nov 26, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,131 @@ const fs = require('fs'); const file = fs.readFileSync(process.argv[2]); let at = file.readUInt32LE(0x3c); if (file.slice(at, at + 0x4).toString('utf-8') !== 'PE\x00\x00') { // bail if not PE header console.error('Did not see PE magic constant'); process.exit(1); } const header = { sections: file.readUInt16LE(at + 0x6), sizeOfOptionalHeader: file.readUInt16LE(at + 0x14), resourcesVAddr: 0, resources: 0, }; // console.log({header}); for (let i = 0; i < header.sections; i += 1) { const offset = at + 0x18 + header.sizeOfOptionalHeader + (i * 0x28); const vaddr = file.readUint32LE(offset + 0xc); const addr = file.readUint32LE(offset + 0x14); const name = file.toString('utf-8', offset, offset + 8).split('\0').shift(); if (name === '.rsrc') { header.resourcesVAddr = vaddr; header.resources = addr; break; } } if (!header.resources) { console.error('Did not find resource table offset'); process.exit(1); } const parseResources = (offset) => { const namedEntriesCount = file.readUInt16LE(offset + 0xc); const idEntriesCount = file.readUInt16LE(offset + 0xe); const entries = []; for (let i = 0; i < namedEntriesCount + idEntriesCount; i += 1) { const cur = offset + 0x10 + (i * 0x8); const id = file.readUInt32LE(cur); const data = file.readUInt32LE(cur + 0x4); // true if high bit is set const isDir = !!(data >>> 31); // clear high bit const target = data & 0x7fffffff; entries.push({ id, isDir, target, }); } return entries; }; const versionDataEntry = { offset: parseResources( parseResources( parseResources(header.resources) .find((x) => x.id === 16 && x.isDir).target + header.resources, ) .find((x) => x.isDir).target + header.resources, ) .find((x) => !x.isDir).target + header.resources, }; versionDataEntry.rvaTarget = file.readUInt32LE(versionDataEntry.offset); versionDataEntry.sizeTarget = file.readUInt32LE(versionDataEntry.offset + 0x4); // set position to start of version data adjusted for virtual address at = versionDataEntry.rvaTarget - header.resourcesVAddr + header.resources; const readUTF16String = (offset) => { let count = 0; let i = 0; while (count < 2) { count += file[offset + i] === 0 ? 1 : -1; i += 1; } return file.toString('utf-16le', offset, offset + i - 1); }; const dwordAlign = (offset, base) => ((offset + base + 3) & 0xfffffffc) - (base & 0xfffffffc); const utf16len = (x) => 2 * (x.length + 1); if (readUTF16String(at + 0x6) !== 'VS_VERSION_INFO') { console.error('Failed to find version struct'); process.exit(1); } const parseStringFileInfo = (offset) => { const entrySize = file.readUint16LE(offset + 0x2); const name = readUTF16String(offset + 0x6); return { totalSize: file.readUint16LE(offset), name, value: entrySize ? readUTF16String(offset + 0x6 + utf16len(name)) : null, }; }; let curStringFileInfo = dwordAlign(0x5a + at, at); while (curStringFileInfo < at + versionDataEntry.sizeTarget) { const stringFileInfo = parseStringFileInfo(curStringFileInfo); if (stringFileInfo.name === 'StringFileInfo') { let curStringTable = dwordAlign(curStringFileInfo + 0x6 + utf16len(stringFileInfo.name), at); while (curStringTable < curStringFileInfo + stringFileInfo.totalSize) { const stringTableInfo = parseStringFileInfo(curStringTable); let curStringTableEntry = dwordAlign(curStringTable + 0x6 + utf16len(stringTableInfo.name), at); while (curStringTableEntry < curStringTable + stringTableInfo.totalSize) { const stringEntryInfo = parseStringFileInfo(curStringTableEntry); console.log(`${stringEntryInfo.name}: ${stringEntryInfo.value}`); curStringTableEntry = dwordAlign(curStringTableEntry + stringEntryInfo.totalSize, at); } curStringTable = dwordAlign(curStringTable + stringTableInfo.totalSize, at); } } curStringFileInfo = dwordAlign(curStringFileInfo + stringFileInfo.totalSize, at); }