From 8ce0bc7e71c578029d51a3c6e2fac25cedd0996c Mon Sep 17 00:00:00 2001 From: Nemo <me@captnemo.in> Date: Fri, 16 Jul 2021 20:40:30 +0530 Subject: [PATCH] Add proper report, os guessing and version ranges --- README.md | 19 ++++++++++--------- finder.js | 3 +++ fingerprint.js | 26 ++++++++++++++++---------- index.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- os.js | 3 +++ package-lock.json | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 +++- version.js | 18 ++++++++++++++++++ 8 files changed, 169 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 9e0d151..7c3038f 100644 --- a/README.md +++ a/README.md @@ -6,20 +6,21 @@ ```shell $ npm install which-electron + $ which-electron Google.Play.Music.Desktop.Player.OSX.zip -Version Constraint: <v7.0.0 -Multiple guesses from fingerprinting: -[ - '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' -] +Version Constraint (Unsupported): <v7.0.0 +Fingerprint: v3.1.7-v3.1.8 +v3.1.8 is currently not supported $ which-electron HashTag-win32-x64.zip Found Version file: v7.1.10 +v7.1.10 is currently not supported 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 ``` diff --git a/finder.js b/finder.js index b522c42..ff3d552 100644 --- a/finder.js +++ a/finder.js @@ -54,6 +54,9 @@ if (isDirectory(e.attributes)) { return false; } + if (!e.file) { + return false; + } let ext = path.extname(e.file); if (['.h', '.dll', '.bin', '.asar', '.dylib', '.so', '.exe'].indexOf(ext) !== -1) { return true diff --git a/fingerprint.js b/fingerprint.js index 918190c..8433570 100644 --- a/fingerprint.js +++ a/fingerprint.js @@ -1,18 +1,18 @@ const DB = require("electron-fingerprints"); const fs = require("fs"); -const hasha = require('hasha'); -const allVersions = require('./versions')['all'] +const hasha = require("hasha"); +const allVersions = require("./versions")["all"]; function checksumFile(algorithm, path) { - return new Promise(function (resolve, reject) { - let fs = require('fs'); - let crypto = require('crypto'); + return new Promise(function(resolve, reject) { + let fs = require("fs"); + let crypto = require("crypto"); - let hash = crypto.createHash(algorithm).setEncoding('hex'); + let hash = crypto.createHash(algorithm).setEncoding("hex"); fs.createReadStream(path) - .once('error', reject) + .once("error", reject) .pipe(hash) - .once('finish', function () { + .once("finish", function() { resolve(hash.read()); }); }); @@ -37,14 +37,18 @@ } } - return possibleVersions; + if (possibleVersions == allVersions) { + return []; + } else { + return possibleVersions; + } }, getHashes: function(dir) { let list = fs.readdirSync(dir); return list.map((f) => { let fn = `${dir}/${f}`; - return hasha.fromFileSync(fn, {algorithm: 'sha1'}) - }) + return hasha.fromFileSync(fn, { algorithm: "sha1" }); + }); }, }; diff --git a/index.js b/index.js index 58e9df6..7c4c5cc 100644 --- a/index.js +++ a/index.js @@ -1,58 +1,82 @@ const path = require("path"); const osguess = require("./os"); const finder = require("./finder"); 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] 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 binary = finder.binary(entries); let versionFiles = finder.version(entries); let enm = finder.findElectronPackageInsideNodeModules(entries); - let filesToHash = finder.fingerprintable(entries) + let filesToHash = finder.fingerprintable(entries); - zip.extractSomeFiles(FILENAME, filesToHash, (dir)=>{ - hashes = fp.getHashes(dir) - guesses = fp.guessFromHashes('win32', 'x64', hashes) + zip.extractSomeFiles(FILENAME, filesToHash, (dir) => { + hashes = fp.getHashes(dir); + guesses = fp.guessFromHashes(osguess2, arch, hashes); if (guesses.length == 1) { - console.log("Fingerprint: " + guesses[0]) - } else { - console.log("Multiple guesses from fingerprinting:") - console.log(guesses) + console.log("Fingerprint: " + guesses[0]); + logSupport(guesses[0]) + } else if (guesses.length > 1) { + console.log("Fingerprint: " + V.asText(guesses)); + logSupport(V.max(guesses)) } - }) + + cleanup.sync(dir); + }); // if (binary) { // console.log(`${process.argv[2]}:${binary}`); // } if (versionFiles.length > 0) { versionFiles.map((f) => { - zip.readFileContents(FILENAME, f, (c)=>{ - console.log("Found Version file: v" + c) - }) + zip.readFileContents(FILENAME, f, (c) => { + console.log("Found Version file: v" + c); + logSupport(`v${c}`) + }); }); } if (asar.length > 0) { asar.forEach((a) => { - console.log("Version Constraint: <v7.0.0") + console.log("Version Constraint (Unsupported): <v7.0.0"); }); } if (enm) { enm.forEach((a) => { - zip.readFileContents(FILENAME, a, (c)=>{ + zip.readFileContents(FILENAME, a, (c) => { try { - let packageData = JSON.parse(c) - console.log("Found version in package.json file: " + packageData['version']) - }catch(e){ + let packageData = JSON.parse(c); + console.log( + "Found version in package.json file: " + packageData["version"] + ); + logSupport(`v${packageData["version"]}`) + } catch (e) { // TODO: Do something } - }) + }); }); } }); diff --git a/os.js b/os.js index 14cd737..ffb97de 100644 --- a/os.js +++ a/os.js @@ -25,6 +25,9 @@ } return null; }, + guessArch(filename, entries) { + return 'x64'; + }, guessFromContents(entries) { for (i in entries) { let entry = entries[i] diff --git a/package-lock.json b/package-lock.json index 4955f3f..568578c 100644 --- a/package-lock.json +++ a/package-lock.json @@ -13,7 +13,9 @@ "elfinfo": "*", "hasha": "^5.2.2", "macho": "^1.4.0", - "node-7z": "^3.0.0" + "node-7z": "^3.0.0", + "rimraf": "^3.0.2", + "semver-sort": "^0.0.4" }, "bin": { "which-electron": "index.js" @@ -385,6 +387,48 @@ "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": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -696,6 +740,33 @@ "requires": { "onetime": "^2.0.0", "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": { diff --git a/package.json b/package.json index 3c185b1..326af3c 100644 --- a/package.json +++ a/package.json @@ -32,7 +32,9 @@ "elfinfo": "*", "hasha": "^5.2.2", "macho": "^1.4.0", - "node-7z": "^3.0.0" + "node-7z": "^3.0.0", + "rimraf": "^3.0.2", + "semver-sort": "^0.0.4" }, "devDependencies": { "kuta": "*" diff --git a/version.js b/version.js new file mode 100644 index 0000000..2a92d4e 100644 --- /dev/null +++ a/version.js @@ -1,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) + } +} -- rgit 0.1.5