Add proper report, os guessing and version ranges
This commit is contained in:
parent
e674c15ad0
commit
8ce0bc7e71
19
README.md
19
README.md
|
@ -6,20 +6,21 @@ Try to find out which Electron version is bundled inside an application.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ npm install which-electron
|
$ npm install which-electron
|
||||||
|
|
||||||
$ which-electron Google.Play.Music.Desktop.Player.OSX.zip
|
$ which-electron Google.Play.Music.Desktop.Player.OSX.zip
|
||||||
Version Constraint: <v7.0.0
|
Version Constraint (Unsupported): <v7.0.0
|
||||||
Multiple guesses from fingerprinting:
|
Fingerprint: v3.1.7-v3.1.8
|
||||||
[
|
v3.1.8 is currently not supported
|
||||||
'v3.1.10', 'v3.1.11',
|
|
||||||
'v3.1.12', 'v3.1.13',
|
|
||||||
'v3.1.5', 'v3.1.6',
|
|
||||||
'v3.1.7', 'v3.1.8',
|
|
||||||
'v3.1.9'
|
|
||||||
]
|
|
||||||
|
|
||||||
$ which-electron HashTag-win32-x64.zip
|
$ which-electron HashTag-win32-x64.zip
|
||||||
Found Version file: v7.1.10
|
Found Version file: v7.1.10
|
||||||
|
v7.1.10 is currently not supported
|
||||||
Fingerprint: v7.1.10
|
Fingerprint: v7.1.10
|
||||||
|
v7.1.10 is currently not supported
|
||||||
|
|
||||||
|
$ which-electron Appium-linux-1.21.0.AppImage
|
||||||
|
Fingerprint: v7.2.4-v7.3.3
|
||||||
|
v7.3.3 is currently not supported
|
||||||
|
|
||||||
$ which-electron Google.Play.Music.Desktop.Player.deb
|
$ which-electron Google.Play.Music.Desktop.Player.deb
|
||||||
```
|
```
|
||||||
|
|
|
@ -54,6 +54,9 @@ module.exports = {
|
||||||
if (isDirectory(e.attributes)) {
|
if (isDirectory(e.attributes)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!e.file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let ext = path.extname(e.file);
|
let ext = path.extname(e.file);
|
||||||
if (['.h', '.dll', '.bin', '.asar', '.dylib', '.so', '.exe'].indexOf(ext) !== -1) {
|
if (['.h', '.dll', '.bin', '.asar', '.dylib', '.so', '.exe'].indexOf(ext) !== -1) {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
const DB = require("electron-fingerprints");
|
const DB = require("electron-fingerprints");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const hasha = require('hasha');
|
const hasha = require("hasha");
|
||||||
const allVersions = require('./versions')['all']
|
const allVersions = require("./versions")["all"];
|
||||||
|
|
||||||
function checksumFile(algorithm, path) {
|
function checksumFile(algorithm, path) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
let fs = require('fs');
|
let fs = require("fs");
|
||||||
let crypto = require('crypto');
|
let crypto = require("crypto");
|
||||||
|
|
||||||
let hash = crypto.createHash(algorithm).setEncoding('hex');
|
let hash = crypto.createHash(algorithm).setEncoding("hex");
|
||||||
fs.createReadStream(path)
|
fs.createReadStream(path)
|
||||||
.once('error', reject)
|
.once("error", reject)
|
||||||
.pipe(hash)
|
.pipe(hash)
|
||||||
.once('finish', function () {
|
.once("finish", function() {
|
||||||
resolve(hash.read());
|
resolve(hash.read());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -37,14 +37,18 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return possibleVersions;
|
if (possibleVersions == allVersions) {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
return possibleVersions;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getHashes: function(dir) {
|
getHashes: function(dir) {
|
||||||
let list = fs.readdirSync(dir);
|
let list = fs.readdirSync(dir);
|
||||||
return list.map((f) => {
|
return list.map((f) => {
|
||||||
let fn = `${dir}/${f}`;
|
let fn = `${dir}/${f}`;
|
||||||
return hasha.fromFileSync(fn, {algorithm: 'sha1'})
|
return hasha.fromFileSync(fn, { algorithm: "sha1" });
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
66
index.js
66
index.js
|
@ -2,57 +2,81 @@ const path = require("path");
|
||||||
const osguess = require("./os");
|
const osguess = require("./os");
|
||||||
const finder = require("./finder");
|
const finder = require("./finder");
|
||||||
const zip = require("./zip");
|
const zip = require("./zip");
|
||||||
const fp = require('./fingerprint')
|
const fp = require("./fingerprint");
|
||||||
|
const cleanup = require("rimraf");
|
||||||
|
const V = require("./version");
|
||||||
|
|
||||||
// Input file comes from process.argv[2]
|
// Input file comes from process.argv[2]
|
||||||
const FILENAME = process.argv[2];
|
const FILENAME = process.argv[2];
|
||||||
|
|
||||||
console.log(FILENAME)
|
console.log(FILENAME);
|
||||||
|
|
||||||
zip.listFileContents(FILENAME, (entries)=> {
|
function logSupport(version) {
|
||||||
|
if (V.isSupported(version)) {
|
||||||
|
console.log(`${version} is currently supported`);
|
||||||
|
} else {
|
||||||
|
console.log(`${version} is currently not supported`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zip.listFileContents(FILENAME, (entries) => {
|
||||||
|
let osguess1 = osguess.guessFromFilename(FILENAME);
|
||||||
|
let osguess2 = osguess.guessFromContents(entries);
|
||||||
|
|
||||||
|
if (osguess1 !== osguess2 && osguess1!==null) {
|
||||||
|
console.log(`Unsure about operating system. Going with ${osguess2}. Other option was ${osguess1}`);
|
||||||
|
}
|
||||||
|
let arch = osguess.guessArch(FILENAME, entries);
|
||||||
let asar = finder.asar(entries);
|
let asar = finder.asar(entries);
|
||||||
let binary = finder.binary(entries);
|
let binary = finder.binary(entries);
|
||||||
let versionFiles = finder.version(entries);
|
let versionFiles = finder.version(entries);
|
||||||
let enm = finder.findElectronPackageInsideNodeModules(entries);
|
let enm = finder.findElectronPackageInsideNodeModules(entries);
|
||||||
|
|
||||||
let filesToHash = finder.fingerprintable(entries)
|
let filesToHash = finder.fingerprintable(entries);
|
||||||
|
|
||||||
zip.extractSomeFiles(FILENAME, filesToHash, (dir)=>{
|
zip.extractSomeFiles(FILENAME, filesToHash, (dir) => {
|
||||||
hashes = fp.getHashes(dir)
|
hashes = fp.getHashes(dir);
|
||||||
guesses = fp.guessFromHashes('win32', 'x64', hashes)
|
guesses = fp.guessFromHashes(osguess2, arch, hashes);
|
||||||
if (guesses.length == 1) {
|
if (guesses.length == 1) {
|
||||||
console.log("Fingerprint: " + guesses[0])
|
console.log("Fingerprint: " + guesses[0]);
|
||||||
} else {
|
logSupport(guesses[0])
|
||||||
console.log("Multiple guesses from fingerprinting:")
|
} else if (guesses.length > 1) {
|
||||||
console.log(guesses)
|
console.log("Fingerprint: " + V.asText(guesses));
|
||||||
|
logSupport(V.max(guesses))
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
cleanup.sync(dir);
|
||||||
|
});
|
||||||
|
|
||||||
// if (binary) {
|
// if (binary) {
|
||||||
// console.log(`${process.argv[2]}:${binary}`);
|
// console.log(`${process.argv[2]}:${binary}`);
|
||||||
// }
|
// }
|
||||||
if (versionFiles.length > 0) {
|
if (versionFiles.length > 0) {
|
||||||
versionFiles.map((f) => {
|
versionFiles.map((f) => {
|
||||||
zip.readFileContents(FILENAME, f, (c)=>{
|
zip.readFileContents(FILENAME, f, (c) => {
|
||||||
console.log("Found Version file: v" + c)
|
console.log("Found Version file: v" + c);
|
||||||
})
|
logSupport(`v${c}`)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (asar.length > 0) {
|
if (asar.length > 0) {
|
||||||
asar.forEach((a) => {
|
asar.forEach((a) => {
|
||||||
console.log("Version Constraint: <v7.0.0")
|
console.log("Version Constraint (Unsupported): <v7.0.0");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (enm) {
|
if (enm) {
|
||||||
enm.forEach((a) => {
|
enm.forEach((a) => {
|
||||||
zip.readFileContents(FILENAME, a, (c)=>{
|
zip.readFileContents(FILENAME, a, (c) => {
|
||||||
try {
|
try {
|
||||||
let packageData = JSON.parse(c)
|
let packageData = JSON.parse(c);
|
||||||
console.log("Found version in package.json file: " + packageData['version'])
|
console.log(
|
||||||
}catch(e){
|
"Found version in package.json file: " + packageData["version"]
|
||||||
|
);
|
||||||
|
logSupport(`v${packageData["version"]}`)
|
||||||
|
} catch (e) {
|
||||||
// TODO: Do something
|
// TODO: Do something
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
3
os.js
3
os.js
|
@ -25,6 +25,9 @@ module.exports = {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
guessArch(filename, entries) {
|
||||||
|
return 'x64';
|
||||||
|
},
|
||||||
guessFromContents(entries) {
|
guessFromContents(entries) {
|
||||||
for (i in entries) {
|
for (i in entries) {
|
||||||
let entry = entries[i]
|
let entry = entries[i]
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
"elfinfo": "*",
|
"elfinfo": "*",
|
||||||
"hasha": "^5.2.2",
|
"hasha": "^5.2.2",
|
||||||
"macho": "^1.4.0",
|
"macho": "^1.4.0",
|
||||||
"node-7z": "^3.0.0"
|
"node-7z": "^3.0.0",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"semver-sort": "^0.0.4"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"which-electron": "index.js"
|
"which-electron": "index.js"
|
||||||
|
@ -385,6 +387,48 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rimraf": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||||
|
"dependencies": {
|
||||||
|
"glob": "^7.1.3"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rimraf": "bin.js"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/semver-regex": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/semver-sort": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver-sort/-/semver-sort-0.0.4.tgz",
|
||||||
|
"integrity": "sha1-NP293GprK0FhOYw8TbpWJDv+qos=",
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^5.0.3",
|
||||||
|
"semver-regex": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/signal-exit": {
|
"node_modules/signal-exit": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||||
|
@ -698,6 +742,33 @@
|
||||||
"signal-exit": "^3.0.2"
|
"signal-exit": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rimraf": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||||
|
"requires": {
|
||||||
|
"glob": "^7.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||||
|
},
|
||||||
|
"semver-regex": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk="
|
||||||
|
},
|
||||||
|
"semver-sort": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver-sort/-/semver-sort-0.0.4.tgz",
|
||||||
|
"integrity": "sha1-NP293GprK0FhOYw8TbpWJDv+qos=",
|
||||||
|
"requires": {
|
||||||
|
"semver": "^5.0.3",
|
||||||
|
"semver-regex": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||||
|
|
|
@ -32,7 +32,9 @@
|
||||||
"elfinfo": "*",
|
"elfinfo": "*",
|
||||||
"hasha": "^5.2.2",
|
"hasha": "^5.2.2",
|
||||||
"macho": "^1.4.0",
|
"macho": "^1.4.0",
|
||||||
"node-7z": "^3.0.0"
|
"node-7z": "^3.0.0",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"semver-sort": "^0.0.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"kuta": "*"
|
"kuta": "*"
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
const semverSort = require('semver-sort');
|
||||||
|
const VERSIONS = require('./versions')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
asText: function(listOfVersions) {
|
||||||
|
sorted = semverSort.asc(listOfVersions);
|
||||||
|
return `${sorted[0]}-${sorted[sorted.length-1]}`
|
||||||
|
},
|
||||||
|
|
||||||
|
max: function(listOfVersions) {
|
||||||
|
sorted = semverSort.asc(listOfVersions);
|
||||||
|
return sorted[sorted.length-1];
|
||||||
|
},
|
||||||
|
|
||||||
|
isSupported: function(v) {
|
||||||
|
return (VERSIONS['supported'].indexOf(v) !== -1)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue