mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-01-13 16:03:20 -05:00
authenticode.js new computes the new checksum on sign/unsign.
This commit is contained in:
parent
86429258dd
commit
f5f4305841
105
authenticode.js
105
authenticode.js
@ -244,9 +244,6 @@ function createAuthenticodeHandler(path) {
|
|||||||
obj.header.siglen = obj.header.dataDirectories.certificateTable.size
|
obj.header.siglen = obj.header.dataDirectories.certificateTable.size
|
||||||
obj.header.signed = ((obj.header.sigpos != 0) && (obj.header.siglen != 0));
|
obj.header.signed = ((obj.header.sigpos != 0) && (obj.header.siglen != 0));
|
||||||
|
|
||||||
// Compute the checkSum value for this file
|
|
||||||
obj.header.peWindows.checkSumActual = getChecksum(readFileSlice(0, obj.filesize));
|
|
||||||
|
|
||||||
// The section headers are located after the optional PE header
|
// The section headers are located after the optional PE header
|
||||||
obj.header.SectionHeadersPtr = obj.header.peOptionalHeaderLocation + obj.header.coff.sizeOfOptionalHeader;
|
obj.header.SectionHeadersPtr = obj.header.peOptionalHeaderLocation + obj.header.coff.sizeOfOptionalHeader;
|
||||||
|
|
||||||
@ -272,6 +269,9 @@ function createAuthenticodeHandler(path) {
|
|||||||
obj.header.sections[sectionName] = section;
|
obj.header.sections[sectionName] = section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the checkSum value for this file
|
||||||
|
obj.header.peWindows.checkSumActual = runChecksum();
|
||||||
|
|
||||||
// If there is a .rsrc section, read the resource information and locations
|
// If there is a .rsrc section, read the resource information and locations
|
||||||
if (obj.header.sections['.rsrc'] != null) {
|
if (obj.header.sections['.rsrc'] != null) {
|
||||||
obj.resources = readResourceTable(obj.header.sections['.rsrc'].rawAddr, 0); // Read all resources recursively
|
obj.resources = readResourceTable(obj.header.sections['.rsrc'].rawAddr, 0); // Read all resources recursively
|
||||||
@ -742,18 +742,85 @@ function createAuthenticodeHandler(path) {
|
|||||||
while (ptr < end) { const buf = readFileSlice(ptr, Math.min(65536, end - ptr)); hash.update(buf); ptr += buf.length; }
|
while (ptr < end) { const buf = readFileSlice(ptr, Math.min(65536, end - ptr)); hash.update(buf); ptr += buf.length; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the PE checksum of an entire file
|
// Checksum the file loading 64k chunks
|
||||||
function getChecksum(data) {
|
function runChecksum() {
|
||||||
var checksum = 0, top = Math.pow(2, 32);
|
var ptr = 0, c = createChecksum();
|
||||||
|
while (ptr < obj.filesize) { const buf = readFileSlice(ptr, Math.min(65536, obj.filesize - ptr)); c.update(buf); ptr += buf.length; }
|
||||||
|
return c.digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checksum the open file loading 64k chunks
|
||||||
|
function runChecksumOnFile(fd, filesize) {
|
||||||
|
var ptr = 0, c = createChecksum(), buf = Buffer.alloc(65536);
|
||||||
|
while (ptr < filesize) { var len = fs.readSync(fd, buf, 0, Math.min(65536, filesize - ptr), ptr); c.update(buf, len); ptr += len; }
|
||||||
|
return c.digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Steaming checksum methods
|
||||||
|
// TODO: Works only with files padded to 4 byte.
|
||||||
|
function createChecksum() {
|
||||||
|
const obj = { checksum: 0, length: 0 };
|
||||||
|
obj.update = function (data, len) {
|
||||||
|
if (!len) { len = data.length; }
|
||||||
|
for (var i = 0; i < (len / 4) ; i++) {
|
||||||
|
if (((obj.length / 4) + i) == 54) continue; // Skip PE checksum location
|
||||||
|
const dword = data.readUInt32LE(i * 4);
|
||||||
|
var checksumlo = (obj.checksum > 4294967296) ? (obj.checksum - 4294967296) : obj.checksum;
|
||||||
|
var checksumhi = (obj.checksum > 4294967296) ? 1 : 0;
|
||||||
|
obj.checksum = checksumlo + dword + checksumhi;
|
||||||
|
if (obj.checksum > 4294967296) {
|
||||||
|
checksumlo = (obj.checksum > 4294967296) ? (obj.checksum - 4294967296) : obj.checksum;
|
||||||
|
checksumhi = (obj.checksum > 4294967296) ? 1 : 0;
|
||||||
|
obj.checksum = checksumlo + checksumhi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj.length += len;
|
||||||
|
}
|
||||||
|
obj.digest = function () {
|
||||||
|
obj.checksum = (obj.checksum & 0xffff) + (obj.checksum >>> 16);
|
||||||
|
obj.checksum = (obj.checksum) + (obj.checksum >>> 16);
|
||||||
|
obj.checksum = obj.checksum & 0xffff;
|
||||||
|
obj.checksum += obj.length;
|
||||||
|
return obj.checksum;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple checksum method that works on a complete file at once
|
||||||
|
// TODO: Works only with files padded to 4 byte.
|
||||||
|
function updateChecksum(data) {
|
||||||
|
var checksum = 0;
|
||||||
for (var i = 0; i < (data.length / 4) ; i++) {
|
for (var i = 0; i < (data.length / 4) ; i++) {
|
||||||
if (i == 54) continue; // Skip PE checksum location
|
if (i == 54) continue; // Skip PE checksum location
|
||||||
var dword = data.readUInt32LE(i * 4);
|
var dword = data.readUInt32LE(i * 4);
|
||||||
var checksumlo = (checksum > top) ? (checksum - top) : checksum;
|
var checksumlo = (checksum > 4294967296) ? (checksum - 4294967296) : checksum;
|
||||||
var checksumhi = (checksum > top) ? 1 : 0;
|
var checksumhi = (checksum > 4294967296) ? 1 : 0;
|
||||||
checksum = checksumlo + dword + checksumhi;
|
checksum = checksumlo + dword + checksumhi;
|
||||||
if (checksum > top) {
|
if (checksum > 4294967296) {
|
||||||
checksumlo = (checksum > top) ? (checksum - top) : checksum;
|
checksumlo = (checksum > 4294967296) ? (checksum - 4294967296) : checksum;
|
||||||
checksumhi = (checksum > top) ? 1 : 0;
|
checksumhi = (checksum > 4294967296) ? 1 : 0;
|
||||||
|
checksum = checksumlo + checksumhi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checksum = (checksum & 0xffff) + (checksum >>> 16);
|
||||||
|
checksum = (checksum) + (checksum >>> 16);
|
||||||
|
checksum = checksum & 0xffff;
|
||||||
|
checksum += data.length;
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the PE checksum of an entire file
|
||||||
|
function getChecksum(data) {
|
||||||
|
var checksum = 0;
|
||||||
|
for (var i = 0; i < (data.length / 4) ; i++) {
|
||||||
|
if (i == 54) continue; // Skip PE checksum location
|
||||||
|
var dword = data.readUInt32LE(i * 4);
|
||||||
|
var checksumlo = (checksum > 4294967296) ? (checksum - 4294967296) : checksum;
|
||||||
|
var checksumhi = (checksum > 4294967296) ? 1 : 0;
|
||||||
|
checksum = checksumlo + dword + checksumhi;
|
||||||
|
if (checksum > 4294967296) {
|
||||||
|
checksumlo = (checksum > 4294967296) ? (checksum - 4294967296) : checksum;
|
||||||
|
checksumhi = (checksum > 4294967296) ? 1 : 0;
|
||||||
checksum = checksumlo + checksumhi;
|
checksum = checksumlo + checksumhi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,7 +883,7 @@ function createAuthenticodeHandler(path) {
|
|||||||
|
|
||||||
// Open the output file
|
// Open the output file
|
||||||
var output = null;
|
var output = null;
|
||||||
try { output = fs.openSync(args.out, 'w'); } catch (ex) { }
|
try { output = fs.openSync(args.out, 'w+'); } catch (ex) { }
|
||||||
if (output == null) return false;
|
if (output == null) return false;
|
||||||
var tmp, written = 0;
|
var tmp, written = 0;
|
||||||
var executableSize = obj.header.sigpos ? obj.header.sigpos : this.filesize;
|
var executableSize = obj.header.sigpos ? obj.header.sigpos : this.filesize;
|
||||||
@ -853,6 +920,12 @@ function createAuthenticodeHandler(path) {
|
|||||||
fs.writeSync(output, win);
|
fs.writeSync(output, win);
|
||||||
fs.writeSync(output, p7signature);
|
fs.writeSync(output, p7signature);
|
||||||
if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); }
|
if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); }
|
||||||
|
written += p7signature.length + padding + 8;
|
||||||
|
|
||||||
|
// Compute the checksum and write it in the PE header at position (54 * 4)
|
||||||
|
var tmp = Buffer.alloc(4);
|
||||||
|
tmp.writeUInt32LE(runChecksumOnFile(output, written));
|
||||||
|
fs.writeSync(output, tmp, 0, 4, 54 * 4);
|
||||||
|
|
||||||
// Close the file
|
// Close the file
|
||||||
fs.closeSync(output);
|
fs.closeSync(output);
|
||||||
@ -862,7 +935,7 @@ function createAuthenticodeHandler(path) {
|
|||||||
// Save an executable without the signature
|
// Save an executable without the signature
|
||||||
obj.unsign = function (args) {
|
obj.unsign = function (args) {
|
||||||
// Open the file
|
// Open the file
|
||||||
var output = fs.openSync(args.out, 'w');
|
var output = fs.openSync(args.out, 'w+');
|
||||||
var written = 0, totalWrite = obj.header.sigpos;
|
var written = 0, totalWrite = obj.header.sigpos;
|
||||||
|
|
||||||
// Compute pre-header length and copy that to the new file
|
// Compute pre-header length and copy that to the new file
|
||||||
@ -881,6 +954,12 @@ function createAuthenticodeHandler(path) {
|
|||||||
fs.writeSync(output, tmp);
|
fs.writeSync(output, tmp);
|
||||||
written += tmp.length;
|
written += tmp.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the checksum and write it in the PE header at position (54 * 4)
|
||||||
|
var tmp = Buffer.alloc(4);
|
||||||
|
tmp.writeUInt32LE(runChecksumOnFile(output, written));
|
||||||
|
fs.writeSync(output, tmp, 0, 4, 54 * 4);
|
||||||
|
|
||||||
fs.closeSync(output);
|
fs.closeSync(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user