Fixed server exception on older NodeJS versions, #4102
This commit is contained in:
parent
69636342fb
commit
cfd8521381
320
authenticode.js
320
authenticode.js
|
@ -404,7 +404,7 @@ function createAuthenticodeHandler(path) {
|
||||||
r.size = buf.readUInt32LE(4);
|
r.size = buf.readUInt32LE(4);
|
||||||
//console.log('readResourceData', r.offsetToData - obj.header.sections['.rsrc'].virtualAddr, r.size, r.offsetToData + r.size - obj.header.sections['.rsrc'].virtualAddr);
|
//console.log('readResourceData', r.offsetToData - obj.header.sections['.rsrc'].virtualAddr, r.size, r.offsetToData + r.size - obj.header.sections['.rsrc'].virtualAddr);
|
||||||
r.codePage = buf.readUInt32LE(8);
|
r.codePage = buf.readUInt32LE(8);
|
||||||
r.reserved = buf.readUInt32LE(12);
|
//r.reserved = buf.readUInt32LE(12);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,12 +449,16 @@ function createAuthenticodeHandler(path) {
|
||||||
if (resources.entries[i].table) { getResourceSectionSize(resources.entries[i].table, sizes); }
|
if (resources.entries[i].table) { getResourceSectionSize(resources.entries[i].table, sizes); }
|
||||||
else if (resources.entries[i].item) {
|
else if (resources.entries[i].item) {
|
||||||
sizes.items += 16;
|
sizes.items += 16;
|
||||||
|
if (resources.entries[i].item.buffer) {
|
||||||
|
sizes.data += resources.entries[i].item.buffer.length;
|
||||||
|
} else {
|
||||||
var dataSize = resources.entries[i].item.size;
|
var dataSize = resources.entries[i].item.size;
|
||||||
if ((dataSize % 8) != 0) { dataSize += (8 - (dataSize % 8)); }
|
if ((dataSize % 8) != 0) { dataSize += (8 - (dataSize % 8)); }
|
||||||
sizes.data += dataSize;
|
sizes.data += dataSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write the resource section in the buffer, this is a recursive method
|
// Write the resource section in the buffer, this is a recursive method
|
||||||
function createResourceSection(resources, buf, resPointers) {
|
function createResourceSection(resources, buf, resPointers) {
|
||||||
|
@ -508,20 +512,29 @@ function createAuthenticodeHandler(path) {
|
||||||
// This is a pointer to a data entry
|
// This is a pointer to a data entry
|
||||||
data = resPointers.items;
|
data = resPointers.items;
|
||||||
|
|
||||||
// Write the item entry
|
|
||||||
buf.writeUInt32LE(resPointers.data + obj.header.sections['.rsrc'].virtualAddr, resPointers.items); // Write the pointer relative to the virtual address
|
|
||||||
buf.writeUInt32LE(resources.entries[i].item.size, resPointers.items + 4);
|
|
||||||
buf.writeUInt32LE(resources.entries[i].item.codePage, resPointers.items + 8);
|
|
||||||
buf.writeUInt32LE(resources.entries[i].item.reserved, resPointers.items + 12);
|
|
||||||
|
|
||||||
// Write the data
|
// Write the data
|
||||||
|
var entrySize = 0;
|
||||||
|
if (resources.entries[i].item.buffer) {
|
||||||
|
// Write the data from given buffer
|
||||||
|
resources.entries[i].item.buffer.copy(buf, resPointers.data, 0, resources.entries[i].item.buffer.length);
|
||||||
|
entrySize = resources.entries[i].item.buffer.length;
|
||||||
|
} else {
|
||||||
|
// Write the data from original file
|
||||||
const actualPtr = (resources.entries[i].item.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + obj.header.sections['.rsrc'].rawAddr;
|
const actualPtr = (resources.entries[i].item.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + obj.header.sections['.rsrc'].rawAddr;
|
||||||
const tmp = readFileSlice(actualPtr, resources.entries[i].item.size);
|
const tmp = readFileSlice(actualPtr, resources.entries[i].item.size);
|
||||||
tmp.copy(buf, resPointers.data, 0, tmp.length);
|
tmp.copy(buf, resPointers.data, 0, tmp.length);
|
||||||
|
entrySize = resources.entries[i].item.size;;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the item entry
|
||||||
|
buf.writeUInt32LE(resPointers.data + obj.header.sections['.rsrc'].virtualAddr, resPointers.items); // Write the pointer relative to the virtual address
|
||||||
|
buf.writeUInt32LE(entrySize, resPointers.items + 4);
|
||||||
|
buf.writeUInt32LE(resources.entries[i].item.codePage, resPointers.items + 8);
|
||||||
|
buf.writeUInt32LE(resources.entries[i].item.reserved, resPointers.items + 12);
|
||||||
|
|
||||||
// Move items pointers forward
|
// Move items pointers forward
|
||||||
resPointers.items += 16;
|
resPointers.items += 16;
|
||||||
var dataSize = resources.entries[i].item.size;
|
var dataSize = entrySize;
|
||||||
if ((dataSize % 8) != 0) { dataSize += (8 - (dataSize % 8)); }
|
if ((dataSize % 8) != 0) { dataSize += (8 - (dataSize % 8)); }
|
||||||
resPointers.data += dataSize;
|
resPointers.data += dataSize;
|
||||||
}
|
}
|
||||||
|
@ -531,17 +544,19 @@ function createAuthenticodeHandler(path) {
|
||||||
|
|
||||||
// Convert a unicode buffer to a string
|
// Convert a unicode buffer to a string
|
||||||
function unicodeToString(buf) {
|
function unicodeToString(buf) {
|
||||||
var r = '';
|
var r = '', c;
|
||||||
for (var i = 0; i < (buf.length / 2) ; i++) { r += String.fromCharCode(buf.readUInt16LE(i * 2)); }
|
for (var i = 0; i < (buf.length / 2) ; i++) {
|
||||||
|
c = buf.readUInt16LE(i * 2);
|
||||||
|
if (c != 0) { r += String.fromCharCode(c); } else { return r; }
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim a string at teh first null character
|
// Convert a string to a unicode buffer
|
||||||
function stringUntilNull(str) {
|
// Input is a string, a buffer to write to and the offset in the buffer (0 is default).
|
||||||
if (str == null) return null;
|
function stringToUnicode(str, buf, offset) {
|
||||||
const i = str.indexOf('\0');
|
if (offset == null) { offset = 0; }
|
||||||
if (i >= 0) return str.substring(0, i);
|
for (var i = 0; i < str.length; i++) { buf.writeInt16LE(str.charCodeAt(i), offset + (i * 2)); }
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var resourceDefaultNames = {
|
var resourceDefaultNames = {
|
||||||
|
@ -612,6 +627,7 @@ function createAuthenticodeHandler(path) {
|
||||||
|
|
||||||
// Decode the version information from the resource
|
// Decode the version information from the resource
|
||||||
obj.getVersionInfo = function () {
|
obj.getVersionInfo = function () {
|
||||||
|
console.log('READ', getVersionInfoData().toString('hex'));
|
||||||
var r = {}, info = readVersionInfo(getVersionInfoData(), 0);
|
var r = {}, info = readVersionInfo(getVersionInfoData(), 0);
|
||||||
if ((info == null) || (info.stringFiles == null)) return null;
|
if ((info == null) || (info.stringFiles == null)) return null;
|
||||||
var StringFileInfo = null;
|
var StringFileInfo = null;
|
||||||
|
@ -622,6 +638,42 @@ function createAuthenticodeHandler(path) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode the version information to the resource
|
||||||
|
obj.setVersionInfo = function (versions) {
|
||||||
|
// Convert the version information into a string array
|
||||||
|
const stringArray = [];
|
||||||
|
for (var i in versions) { stringArray.push({ key: i, value: versions[i] }); }
|
||||||
|
|
||||||
|
// Get the existing version data and switch the strings to the new strings
|
||||||
|
var r = {}, info = readVersionInfo(getVersionInfoData(), 0);
|
||||||
|
if ((info == null) || (info.stringFiles == null)) return;
|
||||||
|
var StringFileInfo = null;
|
||||||
|
for (var i in info.stringFiles) { if (info.stringFiles[i].szKey == 'StringFileInfo') { StringFileInfo = info.stringFiles[i]; } }
|
||||||
|
if ((StringFileInfo == null) || (StringFileInfo.stringTable == null) || (StringFileInfo.stringTable.strings == null)) return;
|
||||||
|
StringFileInfo.stringTable.strings = stringArray;
|
||||||
|
|
||||||
|
// Re-encode the version information into a buffer
|
||||||
|
var verInfoResBufArray = [];
|
||||||
|
writeVersionInfo(verInfoResBufArray, info);
|
||||||
|
var verInfoRes = Buffer.concat(verInfoResBufArray);
|
||||||
|
|
||||||
|
// Display all buffers
|
||||||
|
//console.log('--WRITE BUF ARRAY START--');
|
||||||
|
//for (var i in verInfoResBufArray) { console.log(verInfoResBufArray[i].toString('hex')); }
|
||||||
|
//console.log('--WRITE BUF ARRAY END--');
|
||||||
|
|
||||||
|
// Set the new buffer as part of the resources
|
||||||
|
for (var i = 0; i < obj.resources.entries.length; i++) {
|
||||||
|
if (obj.resources.entries[i].name == resourceDefaultNames.versionInfo) {
|
||||||
|
const verInfo = obj.resources.entries[i].table.entries[0].table.entries[0].item;
|
||||||
|
delete verInfo.size;
|
||||||
|
delete verInfo.offsetToData;
|
||||||
|
verInfo.buffer = verInfoRes;
|
||||||
|
obj.resources.entries[i].table.entries[0].table.entries[0].item = verInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return the version info data block
|
// Return the version info data block
|
||||||
function getVersionInfoData() {
|
function getVersionInfoData() {
|
||||||
if (obj.resources == null) return null;
|
if (obj.resources == null) return null;
|
||||||
|
@ -629,26 +681,175 @@ function createAuthenticodeHandler(path) {
|
||||||
for (var i = 0; i < obj.resources.entries.length; i++) {
|
for (var i = 0; i < obj.resources.entries.length; i++) {
|
||||||
if (obj.resources.entries[i].name == resourceDefaultNames.versionInfo) {
|
if (obj.resources.entries[i].name == resourceDefaultNames.versionInfo) {
|
||||||
const verInfo = obj.resources.entries[i].table.entries[0].table.entries[0].item;
|
const verInfo = obj.resources.entries[i].table.entries[0].table.entries[0].item;
|
||||||
|
if (verInfo.buffer != null) {
|
||||||
|
return verInfo.buffer;
|
||||||
|
} else {
|
||||||
const actualPtr = (verInfo.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + ptr;
|
const actualPtr = (verInfo.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + ptr;
|
||||||
return readFileSlice(actualPtr, verInfo.size);
|
return readFileSlice(actualPtr, verInfo.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a VS_VERSIONINFO structure as a array of buffer that is ready to be placed in the resource section
|
||||||
|
// VS_VERSIONINFO structure: https://docs.microsoft.com/en-us/windows/win32/menurc/vs-versioninfo
|
||||||
|
function writeVersionInfo(bufArray, info) {
|
||||||
|
const buf = Buffer.alloc(40);
|
||||||
|
buf.writeUInt16LE(0, 4); // wType
|
||||||
|
stringToUnicode('VS_VERSION_INFO', buf, 6);
|
||||||
|
bufArray.push(buf);
|
||||||
|
|
||||||
|
var wLength = 40;
|
||||||
|
var wValueLength = 0;
|
||||||
|
if (info.fixedFileInfo != null) {
|
||||||
|
const buf2 = Buffer.alloc(52);
|
||||||
|
wLength += 52;
|
||||||
|
wValueLength += 52;
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwSignature, 0); // dwSignature
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwStrucVersion, 4); // dwStrucVersion
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileVersionMS, 8); // dwFileVersionMS
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileVersionLS, 12); // dwFileVersionLS
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwProductVersionMS, 16); // dwProductVersionMS
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwProductVersionLS, 20); // dwProductVersionLS
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileFlagsMask, 24); // dwFileFlagsMask
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileFlags, 28); // dwFileFlags
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileOS, 32); // dwFileOS
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileType, 36); // dwFileType
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileSubtype, 40); // dwFileSubtype
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileDateMS, 44); // dwFileDateMS
|
||||||
|
buf2.writeUInt32LE(info.fixedFileInfo.dwFileDateLS, 48); // dwFileDateLS
|
||||||
|
bufArray.push(buf2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.stringFiles != null) { wLength += writeStringFileInfo(bufArray, info.stringFiles); }
|
||||||
|
|
||||||
|
console.log('@@@@@@Z', wLength, Buffer.concat(bufArray).length);
|
||||||
|
|
||||||
|
buf.writeUInt16LE(Buffer.concat(bufArray).length, 0); // wLength
|
||||||
|
buf.writeUInt16LE(wValueLength, 2); // wValueLength
|
||||||
|
return wLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringfileinfo
|
||||||
|
function writeStringFileInfo(bufArray, stringFiles) {
|
||||||
|
//console.log('writeStringFileInfo', stringFiles);
|
||||||
|
var totalLen = 0;
|
||||||
|
for (var i in stringFiles) {
|
||||||
|
var l = 6 + (stringFiles[i].szKey.length * 2);
|
||||||
|
const buf2 = Buffer.alloc(padPointer(l));
|
||||||
|
buf2.writeUInt16LE(1, 4); // wType
|
||||||
|
stringToUnicode(stringFiles[i].szKey, buf2, 6);
|
||||||
|
bufArray.push(buf2);
|
||||||
|
|
||||||
|
var wLength = 0, wValueLength = 0;
|
||||||
|
|
||||||
|
if (stringFiles[i].szKey == 'StringFileInfo') { wLength += writeStringTableStruct(bufArray, stringFiles[i].stringTable); }
|
||||||
|
if (stringFiles[i].szKey == 'VarFileInfo') { wLength += writeVarFileInfoStruct(bufArray, stringFiles[i].varFileInfo); }
|
||||||
|
|
||||||
|
buf2.writeUInt16LE(l + wLength, 0); // wLength
|
||||||
|
buf2.writeUInt16LE(wValueLength, 2); // wValueLength
|
||||||
|
totalLen += buf2.length + wLength;
|
||||||
|
}
|
||||||
|
return totalLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VarFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/var-str
|
||||||
|
function writeVarFileInfoStruct(bufArray, varFileInfo) {
|
||||||
|
console.log('*************writeVarFileInfoStruct', varFileInfo);
|
||||||
|
var l = 6 + (varFileInfo.szKey.length * 2);
|
||||||
|
const buf = Buffer.alloc(padPointer(l));
|
||||||
|
buf.writeUInt16LE(0, 4); // wType
|
||||||
|
stringToUnicode(varFileInfo.szKey, buf, 6);
|
||||||
|
bufArray.push(buf);
|
||||||
|
|
||||||
|
var wLength = 0;
|
||||||
|
var wValueLength = 0;
|
||||||
|
|
||||||
|
if (varFileInfo.value) {
|
||||||
|
bufArray.push(varFileInfo.value);
|
||||||
|
wLength += varFileInfo.value.length;
|
||||||
|
}
|
||||||
|
buf.writeUInt16LE(l + wLength, 0); // wLength
|
||||||
|
buf.writeUInt16LE(wValueLength, 2); // wValueLength
|
||||||
|
|
||||||
|
//console.log('WwriteVarFileInfoStruct', buf.toString('hex'));
|
||||||
|
return buf.length + wLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringTable structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringtable
|
||||||
|
function writeStringTableStruct(bufArray, stringTable) {
|
||||||
|
//console.log('writeStringTableStruct', stringTable);
|
||||||
|
var l = 6 + (stringTable.szKey.length * 2);
|
||||||
|
const buf = Buffer.alloc(padPointer(l));
|
||||||
|
buf.writeUInt16LE(1, 4); // wType
|
||||||
|
stringToUnicode(stringTable.szKey, buf, 6);
|
||||||
|
bufArray.push(buf);
|
||||||
|
|
||||||
|
var wLength = 0;
|
||||||
|
var wValueLength = 0;
|
||||||
|
|
||||||
|
if (stringTable.strings) { wLength += writeStringStructs(bufArray, stringTable.strings); }
|
||||||
|
buf.writeUInt16LE(l + wLength, 0); // wLength
|
||||||
|
buf.writeUInt16LE(wValueLength, 2); // wValueLength
|
||||||
|
|
||||||
|
//console.log('WStringTableStruct', buf.toString('hex'));
|
||||||
|
return buf.length + wLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// String structure: https://docs.microsoft.com/en-us/windows/win32/menurc/string-str
|
||||||
|
function writeStringStructs(bufArray, stringTable) {
|
||||||
|
//console.log('writeStringStructs', stringTable);
|
||||||
|
var totalLen = 0, bufadd = 0;
|
||||||
|
for (var i in stringTable) {
|
||||||
|
//console.log('writeStringStructs', stringTable[i]);
|
||||||
|
const buf = Buffer.alloc(padPointer(6 + ((stringTable[i].key.length + 1) * 2)));
|
||||||
|
var buf2, wLength = buf.length;
|
||||||
|
var wValueLength = 0;
|
||||||
|
stringToUnicode(stringTable[i].key, buf, 6);
|
||||||
|
bufArray.push(buf);
|
||||||
|
bufadd += buf.length;
|
||||||
|
if (typeof stringTable[i].value == 'string') {
|
||||||
|
// wType (string)
|
||||||
|
buf.writeUInt16LE(1, 4);
|
||||||
|
var l = (stringTable[i].value.length + 1) * 2;
|
||||||
|
buf2 = Buffer.alloc(padPointer(l));
|
||||||
|
stringToUnicode(stringTable[i].value, buf2, 0);
|
||||||
|
bufArray.push(buf2);
|
||||||
|
bufadd += buf2.length;
|
||||||
|
wValueLength = stringTable[i].value.length + 1;
|
||||||
|
wLength += l;
|
||||||
|
}
|
||||||
|
if (typeof stringTable[i].value == 'object') {
|
||||||
|
// wType (binary)
|
||||||
|
buf.writeUInt16LE(2, 4); // TODO: PADDING
|
||||||
|
bufArray.push(stringTable[i].value);
|
||||||
|
bufadd += stringTable[i].value.length;
|
||||||
|
wValueLength = stringTable[i].value.length;
|
||||||
|
wLength += wValueLength;
|
||||||
|
}
|
||||||
|
buf.writeUInt16LE(wLength, 0); // wLength
|
||||||
|
buf.writeUInt16LE(wValueLength, 2); // wValueLength
|
||||||
|
//console.log('WStringStruct', buf.toString('hex'), buf2.toString('hex'));
|
||||||
|
totalLen += wLength;
|
||||||
|
}
|
||||||
|
//return totalLen;
|
||||||
|
return bufadd;
|
||||||
|
}
|
||||||
|
|
||||||
// VS_VERSIONINFO structure: https://docs.microsoft.com/en-us/windows/win32/menurc/vs-versioninfo
|
// VS_VERSIONINFO structure: https://docs.microsoft.com/en-us/windows/win32/menurc/vs-versioninfo
|
||||||
function readVersionInfo(buf, ptr) {
|
function readVersionInfo(buf, ptr) {
|
||||||
const r = {};
|
const r = {};
|
||||||
if (buf.length < 2) return null;
|
if (buf.length < 2) return null;
|
||||||
r.wLength = buf.readUInt16LE(ptr);
|
const wLength = buf.readUInt16LE(ptr);
|
||||||
if (buf.length < r.wLength) return null;
|
if (buf.length < wLength) return null;
|
||||||
r.wValueLength = buf.readUInt16LE(ptr + 2);
|
const wValueLength = buf.readUInt16LE(ptr + 2);
|
||||||
r.wType = buf.readUInt16LE(ptr + 4);
|
const wType = buf.readUInt16LE(ptr + 4);
|
||||||
r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 36));
|
r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 36));
|
||||||
if (r.szKey != 'VS_VERSION_INFO') return null;
|
if (r.szKey != 'VS_VERSION_INFO') return null;
|
||||||
//console.log('getVersionInfo', r.wLength, r.wValueLength, r.wType, r.szKey.toString());
|
//console.log('getVersionInfo', wLength, wValueLength, wType, r.szKey.toString());
|
||||||
if (r.wValueLength == 52) { r.fixedFileInfo = readFixedFileInfoStruct(buf, ptr + 40); }
|
if (wValueLength == 52) { r.fixedFileInfo = readFixedFileInfoStruct(buf, ptr + 40); }
|
||||||
r.stringFiles = readStringFilesStruct(buf, ptr + 40 + r.wValueLength, r.wLength - 40 - r.wValueLength);
|
r.stringFiles = readStringFilesStruct(buf, ptr + 40 + wValueLength, wLength - 40 - wValueLength);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,30 +879,43 @@ function createAuthenticodeHandler(path) {
|
||||||
var t = [], startPtr = ptr;
|
var t = [], startPtr = ptr;
|
||||||
while (ptr < (startPtr + len)) {
|
while (ptr < (startPtr + len)) {
|
||||||
const r = {};
|
const r = {};
|
||||||
r.wLength = buf.readUInt16LE(ptr);
|
const wLength = buf.readUInt16LE(ptr);
|
||||||
if (r.wLength == 0) return t;
|
if (wLength == 0) return t;
|
||||||
r.wValueLength = buf.readUInt16LE(ptr + 2);
|
const wValueLength = buf.readUInt16LE(ptr + 2);
|
||||||
r.wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
|
const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
|
||||||
r.szKey = stringUntilNull(unicodeToString(buf.slice(ptr + 6, ptr + 6 + (r.wLength - 6)))); // String value
|
r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 6 + (wLength - 6))); // String value
|
||||||
//console.log('readStringFileStruct', r.wLength, r.wValueLength, r.wType, r.szKey.toString());
|
//console.log('readStringFileStruct', wLength, wValueLength, wType, r.szKey);
|
||||||
if (r.szKey == 'StringFileInfo') { r.stringTable = readStringTableStruct(buf, ptr + 36 + r.wValueLength); }
|
if (r.szKey == 'StringFileInfo') { r.stringTable = readStringTableStruct(buf, ptr + 36); }
|
||||||
if (r.szKey == 'VarFileInfo$') { r.varFileInfo = {}; } // TODO
|
if (r.szKey == 'VarFileInfo') { r.varFileInfo = readVarFileInfoStruct(buf, ptr + 32); }
|
||||||
t.push(r);
|
t.push(r);
|
||||||
ptr += r.wLength;
|
ptr += wLength;
|
||||||
ptr = padPointer(ptr);
|
ptr = padPointer(ptr);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VarFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/var-str
|
||||||
|
function readVarFileInfoStruct(buf, ptr) {
|
||||||
|
const r = {};
|
||||||
|
const wLength = buf.readUInt16LE(ptr);
|
||||||
|
const wValueLength = buf.readUInt16LE(ptr + 2);
|
||||||
|
const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
|
||||||
|
r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + wLength)); // "VarFileInfo"
|
||||||
|
r.value = buf.slice(ptr + wLength - wValueLength, ptr + wLength)
|
||||||
|
//console.log('readVarFileInfoStruct', wLength, wValueLength, wType, r.szKey, r.value.toString('hex'));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
// StringTable structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringtable
|
// StringTable structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringtable
|
||||||
function readStringTableStruct(buf, ptr) {
|
function readStringTableStruct(buf, ptr) {
|
||||||
const r = {};
|
const r = {};
|
||||||
r.wLength = buf.readUInt16LE(ptr);
|
const wLength = buf.readUInt16LE(ptr);
|
||||||
r.wValueLength = buf.readUInt16LE(ptr + 2);
|
const wValueLength = buf.readUInt16LE(ptr + 2);
|
||||||
r.wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
|
const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
|
||||||
|
//console.log('RStringTableStruct', buf.slice(ptr, ptr + wLength).toString('hex'));
|
||||||
r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 6 + 16)); // An 8-digit hexadecimal number stored as a Unicode string.
|
r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 6 + 16)); // An 8-digit hexadecimal number stored as a Unicode string.
|
||||||
//console.log('readStringTableStruct', r.wLength, r.wValueLength, r.wType, r.szKey);
|
//console.log('readStringTableStruct', wLength, wValueLength, r.wType, r.szKey);
|
||||||
r.strings = readStringStructs(buf, ptr + 24 + r.wValueLength, r.wLength - 22);
|
r.strings = readStringStructs(buf, ptr + 24 + wValueLength, wLength - 22);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,22 +924,30 @@ function createAuthenticodeHandler(path) {
|
||||||
var t = [], startPtr = ptr;
|
var t = [], startPtr = ptr;
|
||||||
while (ptr < (startPtr + len)) {
|
while (ptr < (startPtr + len)) {
|
||||||
const r = {};
|
const r = {};
|
||||||
r.wLength = buf.readUInt16LE(ptr);
|
const wLength = buf.readUInt16LE(ptr);
|
||||||
if (r.wLength == 0) return t;
|
if (wLength == 0) return t;
|
||||||
r.wValueLength = buf.readUInt16LE(ptr + 2);
|
|
||||||
r.wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
|
//console.log('RStringStruct', buf.slice(ptr, ptr + wLength).toString('hex'));
|
||||||
r.key = unicodeToString(buf.slice(ptr + 6, ptr + (r.wLength - (r.wValueLength * 2)))); // Key
|
|
||||||
r.value = unicodeToString(buf.slice(ptr + r.wLength - (r.wValueLength * 2), ptr + r.wLength)); // Value
|
const wValueLength = buf.readUInt16LE(ptr + 2);
|
||||||
//console.log('readStringStruct', r.wLength, r.wValueLength, r.wType, r.key, r.value);
|
const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
|
||||||
|
|
||||||
|
//console.log('R', buf.slice(ptr, ptr + wLength).toString('hex'));
|
||||||
|
|
||||||
|
r.key = unicodeToString(buf.slice(ptr + 6, ptr + (wLength - (wValueLength * 2)) - 2)); // Key
|
||||||
|
if (wType == 1) { r.value = unicodeToString(buf.slice(ptr + wLength - (wValueLength * 2), ptr + wLength - 2)); } // String value
|
||||||
|
if (wType == 2) { r.value = buf.slice(ptr + wLength - (wValueLength * 2), ptr + wLength); } // Binary value
|
||||||
|
//console.log('readStringStruct', wLength, wValueLength, wType, r.key, r.value);
|
||||||
t.push(r);
|
t.push(r);
|
||||||
ptr += r.wLength;
|
ptr += wLength;
|
||||||
ptr = padPointer(ptr);
|
ptr = padPointer(ptr);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the next 4 byte aligned number
|
// Return the next 4 byte aligned number
|
||||||
function padPointer(ptr) { return ptr + (ptr % 4); }
|
function padPointer(ptr) { return ptr + (((ptr % 4) == 0) ? 0 : (4 - (ptr % 4))); }
|
||||||
|
//function padPointer(ptr) { return ptr + (ptr % 4); }
|
||||||
|
|
||||||
// Hash the file using the selected hashing system
|
// Hash the file using the selected hashing system
|
||||||
obj.getHash = function(algo) {
|
obj.getHash = function(algo) {
|
||||||
|
@ -942,6 +1164,12 @@ function createAuthenticodeHandler(path) {
|
||||||
|
|
||||||
// Save the executable
|
// Save the executable
|
||||||
obj.writeExecutable = function (args) {
|
obj.writeExecutable = function (args) {
|
||||||
|
// Get version information from the resource
|
||||||
|
var versions = obj.getVersionInfo();
|
||||||
|
//versions['FileDescription'] = 'Mesh Agent Service';
|
||||||
|
obj.setVersionInfo(versions);
|
||||||
|
//var versions2 = obj.getVersionInfo();
|
||||||
|
|
||||||
// Open the file
|
// Open the file
|
||||||
var output = fs.openSync(args.out, 'w');
|
var output = fs.openSync(args.out, 'w');
|
||||||
var tmp, written = 0;
|
var tmp, written = 0;
|
||||||
|
|
|
@ -7697,8 +7697,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||||
xargs.autocomplete = (domain.autocomplete === false)?'x':'autocomplete'; // This option allows autocomplete to be turned off on the login page.
|
xargs.autocomplete = (domain.autocomplete === false)?'x':'autocomplete'; // This option allows autocomplete to be turned off on the login page.
|
||||||
if (typeof domain.hide == 'number') { xargs.hide = domain.hide; }
|
if (typeof domain.hide == 'number') { xargs.hide = domain.hide; }
|
||||||
|
|
||||||
// To mitigate any possible BREACH attack, we generate a random length string here.
|
// To mitigate any possible BREACH attack, we generate a random 0 to 255 bytes length string here.
|
||||||
xargs.randomlength = (args.webpagelengthrandomization !== false) ? parent.crypto.randomBytes(parent.crypto.randomInt(0, 256)).toString('base64') : '';
|
xargs.randomlength = (args.webpagelengthrandomization !== false) ? parent.crypto.randomBytes(parent.crypto.randomBytes(1)[0]).toString('base64') : '';
|
||||||
|
|
||||||
return xargs;
|
return xargs;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue