Authenticode.js fixes to header parsing.

Ylian Saint-Hilaire committed May 30, 2022 at 13:45 UTC e422f92674a23141233db6c32f172bd01dff27d2
1 file changed +32 -14
authenticode.js
+32 -14
@@ -304,11 +304,22 @@ function createAuthenticodeHandler(path) {
304 return r;
305 }
306
307 + // Trim a string at teh first null character
308 + function stringUntilNull(str) {
309 + if (str == null) return null;
310 + const i = str.indexOf('\0');
311 + if (i >= 0) return str.substring(0, i);
312 + return str;
313 + }
314 +
315 // Decode the version information from the resource
316 obj.getVersionInfo = function () {
317 var r = {}, info = readVersionInfo(getVersionInfoData(), 0);
310 - if (info == null) return null;
311 - const strings = info.stringFile.stringTable.strings;
318 + if ((info == null) || (info.stringFiles == null)) return null;
319 + var StringFileInfo = null;
320 + for (var i in info.stringFiles) { if (info.stringFiles[i].szKey == 'StringFileInfo') { StringFileInfo = info.stringFiles[i]; } }
321 + if ((StringFileInfo == null) || (StringFileInfo.stringTable == null) || (StringFileInfo.stringTable.strings == null)) return null;
322 + const strings = StringFileInfo.stringTable.strings;
323 for (var i in strings) { r[strings[i].key] = strings[i].value; }
324 return r;
325 }
@@ -339,7 +350,7 @@ function createAuthenticodeHandler(path) {
350 if (r.szKey != 'VS_VERSION_INFO') return null;
351 //console.log('getVersionInfo', r.wLength, r.wValueLength, r.wType, r.szKey.toString());
352 if (r.wValueLength == 52) { r.fixedFileInfo = readFixedFileInfoStruct(buf, ptr + 40); }
342 - r.stringFile = readStringFileStruct(buf, ptr + 40 + r.wValueLength);
353 + r.stringFiles = readStringFilesStruct(buf, ptr + 40 + r.wValueLength, r.wLength - 40 - r.wValueLength);
354 return r;
355 }
356
@@ -365,16 +376,23 @@ function createAuthenticodeHandler(path) {
376 }
377
378 // StringFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringfileinfo
368 - function readStringFileStruct(buf, ptr) {
369 - const r = {};
370 - r.wLength = buf.readUInt16LE(ptr);
371 - r.wValueLength = buf.readUInt16LE(ptr + 2);
372 - r.wType = buf.readUInt16LE(ptr + 4);
373 - r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 34));
374 - if (r.szKey != 'StringFileInfo') return null;
375 - //console.log('readStringFileStruct', r.wLength, r.wValueLength, r.wType, r.szKey.toString());
376 - r.stringTable = readStringTableStruct(buf, ptr + 36 + r.wValueLength);
377 - return r;
379 + function readStringFilesStruct(buf, ptr, len) {
380 + var t = [], startPtr = ptr;
381 + while (ptr < (startPtr + len)) {
382 + const r = {};
383 + r.wLength = buf.readUInt16LE(ptr);
384 + if (r.wLength == 0) return t;
385 + r.wValueLength = buf.readUInt16LE(ptr + 2);
386 + r.wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
387 + r.szKey = stringUntilNull(unicodeToString(buf.slice(ptr + 6, ptr + 6 + (r.wLength - 6)))); // String value
388 + //console.log('readStringFileStruct', r.wLength, r.wValueLength, r.wType, r.szKey.toString());
389 + if (r.szKey == 'StringFileInfo') { r.stringTable = readStringTableStruct(buf, ptr + 36 + r.wValueLength); }
390 + if (r.szKey == 'VarFileInfo$') { r.varFileInfo = {}; } // TODO
391 + t.push(r);
392 + ptr += r.wLength;
393 + ptr = padPointer(ptr);
394 + }
395 + return t;
396 }
397
398 // StringTable structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringtable
@@ -610,7 +628,7 @@ function start() {
628 console.log(JSON.stringify(r, null, 2));
629 } else {
630 var versionInfo = exe.getVersionInfo();
613 - if (versionInfo != null) { console.log("Version Information:"); for (var i in versionInfo) { console.log(' ' + i + ': \"' + versionInfo[i] + '\"'); } }
631 + if (versionInfo != null) { console.log("Version Information:"); for (var i in versionInfo) { if (versionInfo[i] == null) { console.log(' ' + i + ': (Empty)'); } else { console.log(' ' + i + ': \"' + versionInfo[i] + '\"'); } } }
632 console.log("Signature Information:");
633 if (exe.fileHashAlgo != null) {
634 console.log(" Hash Method:", exe.fileHashAlgo);