Fixed authenticode PS checksum calculation.
Ylian Saint-Hilaire committed
Jun 8, 2022 at 14:52 UTC
85fc1a4d4ccc68522355f483d58103b37ebc899b
2 files changed
+15
-38
authenticode.js
+13
-36
@@ -744,26 +744,26 @@ function createAuthenticodeHandler(path) {
744
745
// Checksum the file loading 64k chunks
746
function runChecksum() {
747
- var ptr = 0, c = createChecksum();
747
+ var ptr = 0, c = createChecksum(((obj.header.peOptionalHeaderLocation + 64) / 4));
748
while (ptr < obj.filesize) { const buf = readFileSlice(ptr, Math.min(65536, obj.filesize - ptr)); c.update(buf); ptr += buf.length; }
749
return c.digest();
750
}
751
752
// Checksum the open file loading 64k chunks
753
- function runChecksumOnFile(fd, filesize) {
754
- var ptr = 0, c = createChecksum(), buf = Buffer.alloc(65536);
753
+ function runChecksumOnFile(fd, filesize, checksumLocation) {
754
+ var ptr = 0, c = createChecksum(checksumLocation), buf = Buffer.alloc(65536);
755
while (ptr < filesize) { var len = fs.readSync(fd, buf, 0, Math.min(65536, filesize - ptr), ptr); c.update(buf, len); ptr += len; }
756
return c.digest();
757
}
758
759
// Steaming checksum methods
760
// TODO: Works only with files padded to 4 byte.
761
- function createChecksum() {
761
+ function createChecksum(checksumLocation) {
762
const obj = { checksum: 0, length: 0 };
763
obj.update = function (data, len) {
764
if (!len) { len = data.length; }
765
for (var i = 0; i < (len / 4) ; i++) {
766
- if (((obj.length / 4) + i) == 54) continue; // Skip PE checksum location
766
+ if (((obj.length / 4) + i) == checksumLocation) continue; // Skip PE checksum location
767
const dword = data.readUInt32LE(i * 4);
768
var checksumlo = (obj.checksum > 4294967296) ? (obj.checksum - 4294967296) : obj.checksum;
769
var checksumhi = (obj.checksum > 4294967296) ? 1 : 0;
@@ -786,34 +786,11 @@ function createAuthenticodeHandler(path) {
786
return obj;
787
}
788
789
- // Simple checksum method that works on a complete file at once
790
- // TODO: Works only with files padded to 4 byte.
791
- function updateChecksum(data) {
792
- var checksum = 0;
793
- for (var i = 0; i < (data.length / 4) ; i++) {
794
- if (i == 54) continue; // Skip PE checksum location
795
- var dword = data.readUInt32LE(i * 4);
796
- var checksumlo = (checksum > 4294967296) ? (checksum - 4294967296) : checksum;
797
- var checksumhi = (checksum > 4294967296) ? 1 : 0;
798
- checksum = checksumlo + dword + checksumhi;
799
- if (checksum > 4294967296) {
800
- checksumlo = (checksum > 4294967296) ? (checksum - 4294967296) : checksum;
801
- checksumhi = (checksum > 4294967296) ? 1 : 0;
802
- checksum = checksumlo + checksumhi;
803
- }
804
- }
805
- checksum = (checksum & 0xffff) + (checksum >>> 16);
806
- checksum = (checksum) + (checksum >>> 16);
807
- checksum = checksum & 0xffff;
808
- checksum += data.length;
809
- return checksum;
810
- }
811
-
789
// Compute the PE checksum of an entire file
813
- function getChecksum(data) {
790
+ function getChecksum(data, checksumLocation) {
791
var checksum = 0;
792
for (var i = 0; i < (data.length / 4) ; i++) {
816
- if (i == 54) continue; // Skip PE checksum location
793
+ if (i == (checksumLocation / 4)) continue; // Skip PE checksum location
794
var dword = data.readUInt32LE(i * 4);
795
var checksumlo = (checksum > 4294967296) ? (checksum - 4294967296) : checksum;
796
var checksumhi = (checksum > 4294967296) ? 1 : 0;
@@ -920,12 +897,12 @@ function createAuthenticodeHandler(path) {
897
fs.writeSync(output, win);
898
fs.writeSync(output, p7signature);
899
if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); }
923
- written += p7signature.length + padding + 8;
900
+ written += (p7signature.length + padding + 8);
901
925
- // Compute the checksum and write it in the PE header at position (54 * 4)
902
+ // Compute the checksum and write it in the PE header checksum location
903
var tmp = Buffer.alloc(4);
927
- tmp.writeUInt32LE(runChecksumOnFile(output, written));
928
- fs.writeSync(output, tmp, 0, 4, 54 * 4);
904
+ tmp.writeUInt32LE(runChecksumOnFile(output, written, ((obj.header.peOptionalHeaderLocation + 64) / 4)));
905
+ fs.writeSync(output, tmp, 0, 4, obj.header.peOptionalHeaderLocation + 64);
906
907
// Close the file
908
fs.closeSync(output);
@@ -955,10 +932,10 @@ function createAuthenticodeHandler(path) {
932
written += tmp.length;
933
}
934
958
- // Compute the checksum and write it in the PE header at position (54 * 4)
935
+ // Compute the checksum and write it in the PE checksum header at position
936
var tmp = Buffer.alloc(4);
937
tmp.writeUInt32LE(runChecksumOnFile(output, written));
961
- fs.writeSync(output, tmp, 0, 4, 54 * 4);
938
+ fs.writeSync(output, tmp, 0, 4, obj.header.peOptionalHeaderLocation + 64);
939
940
fs.closeSync(output);
941
}
public/translate.bat
+2
-2
@@ -1,7 +1,7 @@
1
@ECHO OFF
2
CD ..\translate
3
%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js minifyall
4
-REM %LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js translateall
5
-REM %LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js extractall
4
+%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js translateall
5
+%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js extractall
6
DEL ..\emails\translations\*-min_*
7
Pause
\ No newline at end of file