Authenticode.js can now fully decode and reencode a resource section.
Ylian Saint-Hilaire committed
Jun 9, 2022 at 11:37 UTC
d06ca601ffde4602f97147038616ed2331f01624
1 file changed
+12
-35
authenticode.js
+12
-35
@@ -627,7 +627,7 @@ function createAuthenticodeHandler(path) {
627
628
// Decode the version information from the resource
629
obj.getVersionInfo = function () {
630
- console.log('READ', getVersionInfoData().toString('hex'));
630
+ //console.log('READ', getVersionInfoData().toString('hex'));
631
var r = {}, info = readVersionInfo(getVersionInfoData(), 0);
632
if ((info == null) || (info.stringFiles == null)) return null;
633
var StringFileInfo = null;
@@ -661,6 +661,7 @@ function createAuthenticodeHandler(path) {
661
//console.log('--WRITE BUF ARRAY START--');
662
//for (var i in verInfoResBufArray) { console.log(verInfoResBufArray[i].toString('hex')); }
663
//console.log('--WRITE BUF ARRAY END--');
664
+ //console.log('OUT', Buffer.concat(verInfoResBufArray).toString('hex'));
665
666
// Set the new buffer as part of the resources
667
for (var i = 0; i < obj.resources.entries.length; i++) {
@@ -724,8 +725,6 @@ function createAuthenticodeHandler(path) {
725
726
if (info.stringFiles != null) { wLength += writeStringFileInfo(bufArray, info.stringFiles); }
727
727
- console.log('@@@@@@Z', wLength, Buffer.concat(bufArray).length);
728
-
728
buf.writeUInt16LE(Buffer.concat(bufArray).length, 0); // wLength
729
buf.writeUInt16LE(wValueLength, 2); // wValueLength
730
return wLength;
@@ -733,10 +732,10 @@ function createAuthenticodeHandler(path) {
732
733
// StringFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringfileinfo
734
function writeStringFileInfo(bufArray, stringFiles) {
736
- //console.log('writeStringFileInfo', stringFiles);
735
var totalLen = 0;
736
for (var i in stringFiles) {
737
var l = 6 + (stringFiles[i].szKey.length * 2);
738
+ if (stringFiles[i].szKey == 'VarFileInfo') { l += 4; } // TODO: This is a hack, not sure what the correct code should be
739
const buf2 = Buffer.alloc(padPointer(l));
740
buf2.writeUInt16LE(1, 4); // wType
741
stringToUnicode(stringFiles[i].szKey, buf2, 6);
@@ -756,8 +755,7 @@ function createAuthenticodeHandler(path) {
755
756
// VarFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/var-str
757
function writeVarFileInfoStruct(bufArray, varFileInfo) {
759
- console.log('*************writeVarFileInfoStruct', varFileInfo);
760
- var l = 6 + (varFileInfo.szKey.length * 2);
758
+ var l = 8 + (varFileInfo.szKey.length * 2);
759
const buf = Buffer.alloc(padPointer(l));
760
buf.writeUInt16LE(0, 4); // wType
761
stringToUnicode(varFileInfo.szKey, buf, 6);
@@ -769,11 +767,10 @@ function createAuthenticodeHandler(path) {
767
if (varFileInfo.value) {
768
bufArray.push(varFileInfo.value);
769
wLength += varFileInfo.value.length;
770
+ wValueLength += varFileInfo.value.length;
771
}
773
- buf.writeUInt16LE(l + wLength, 0); // wLength
772
+ buf.writeUInt16LE(buf.length + wLength, 0); // wLength
773
buf.writeUInt16LE(wValueLength, 2); // wValueLength
775
-
776
- //console.log('WwriteVarFileInfoStruct', buf.toString('hex'));
774
return buf.length + wLength;
775
}
776
@@ -792,8 +789,6 @@ function createAuthenticodeHandler(path) {
789
if (stringTable.strings) { wLength += writeStringStructs(bufArray, stringTable.strings); }
790
buf.writeUInt16LE(l + wLength, 0); // wLength
791
buf.writeUInt16LE(wValueLength, 2); // wValueLength
795
-
796
- //console.log('WStringTableStruct', buf.toString('hex'));
792
return buf.length + wLength;
793
}
794
@@ -1166,9 +1161,8 @@ function createAuthenticodeHandler(path) {
1161
obj.writeExecutable = function (args) {
1162
// Get version information from the resource
1163
var versions = obj.getVersionInfo();
1169
- //versions['FileDescription'] = 'Mesh Agent Service';
1164
+ versions['FileDescription'] = 'This is a test';
1165
obj.setVersionInfo(versions);
1171
- //var versions2 = obj.getVersionInfo();
1166
1167
// Open the file
1168
var output = fs.openSync(args.out, 'w');
@@ -1185,11 +1179,13 @@ function createAuthenticodeHandler(path) {
1179
var newResSize = obj.header.sections['.rsrc'].rawSize; // Testing 102400
1180
var resDeltaSize = newResSize - oldResSize;
1181
1182
+ /*
1183
console.log('fileAlign', fileAlign);
1184
console.log('resPtr', resPtr);
1185
console.log('oldResSize', oldResSize);
1186
console.log('newResSize', newResSize);
1187
console.log('resDeltaSize', resDeltaSize);
1188
+ */
1189
1190
// Change PE optional header sizeOfInitializedData standard field
1191
fullHeader.writeUInt32LE(obj.header.peStandard.sizeOfInitializedData + resDeltaSize, obj.header.peOptionalHeaderLocation + 8);
@@ -1232,13 +1228,13 @@ function createAuthenticodeHandler(path) {
1228
}
1229
1230
// Write the entire header to the destination file
1235
- console.log('Write header', fullHeader.length);
1231
+ //console.log('Write header', fullHeader.length);
1232
fs.writeSync(output, fullHeader);
1233
written += fullHeader.length;
1234
1235
// Write the entire executable until the start to the resource segment
1236
var totalWrite = resPtr;
1241
- console.log('Write until res', totalWrite);
1237
+ //console.log('Write until res', totalWrite);
1238
while ((totalWrite - written) > 0) {
1239
tmp = readFileSlice(written, Math.min(totalWrite - written, 65536));
1240
fs.writeSync(output, tmp);
@@ -1250,28 +1246,9 @@ function createAuthenticodeHandler(path) {
1246
fs.writeSync(output, rsrcSection);
1247
written += rsrcSection.length;
1248
1253
- /*
1254
- // Write the old resource segment (debug)
1255
- totalWrite = resPtr + oldResSize;
1256
- console.log('Write res', totalWrite);
1257
- while ((totalWrite - written) > 0) {
1258
- tmp = readFileSlice(written, Math.min(totalWrite - written, 65536));
1259
- fs.writeSync(output, tmp);
1260
- written += tmp.length;
1261
- }
1262
- */
1263
-
1264
- /*
1265
- // Write a dummy 102400 bytes
1266
- tmp = Buffer.alloc(resDeltaSize);
1267
- console.log('Write dummy', resDeltaSize);
1268
- fs.writeSync(output, tmp);
1269
- written += tmp.length;
1270
- */
1271
-
1249
// Write until the signature block
1250
totalWrite = obj.header.sigpos + resDeltaSize;
1274
- console.log('Write until signature', totalWrite);
1251
+ //console.log('Write until signature', totalWrite);
1252
while ((totalWrite - written) > 0) {
1253
tmp = readFileSlice(written - resDeltaSize, Math.min(totalWrite - written, 65536));
1254
fs.writeSync(output, tmp);