OpenMiInk/patches/apk_unpack+1.2.1.patch
Hellings b8c8ff98e2 Hi
2026-10-16 09:05:56 -04:00

274 lines
8.4 KiB
Diff

diff --git a/node_modules/apk_unpack/apk_unpack.js b/node_modules/apk_unpack/apk_unpack.js
index e05cc3f..8cb2ed4 100644
--- a/node_modules/apk_unpack/apk_unpack.js
+++ b/node_modules/apk_unpack/apk_unpack.js
@@ -1,132 +1,83 @@
-// APK Asset unpack - uses apktool.
-// helper for cli.js
-var fs = require('fs'),
- lineReader = require('line-reader'),
- java = require('java'),
- path = require('path'),
- _last = { dir:'' },
- cwd = process.cwd(),
- _config = {
- apk : '',
- java : true,
- dir : ''
- };
-
-// capture console out
-/*var access = fs.createWriteStream(cwd + path.sep + 'apk_unpack.log');
-process.stdout.write = process.stderr.write = access.write.bind(access);*/
-
-// add classes for JADX and apktool
-java.classpath.pushDir(__dirname+path.sep+'java/jadx/');
-java.classpath.pushDir(__dirname+path.sep+'java/');
-java.options.push('-Xrs'); // reduce signal os signals
-//
-
-var classes = {
- ApkDecoder : java.import('brut.androlib.ApkDecoder'),
- libResources : java.import('brut.androlib.res.AndrolibResources'),
- ExtFile : java.import('brut.directory.ExtFile'),
- File : java.import('java.io.File'),
- //jadx
- _jadx : java.import('jadx.api.JadxDecompiler'),
- _jadx_args : java.import('jadx.cli.JadxCLIArgs'),
- _javalog : java.import('java.util.logging.LogManager'),
- _jadx_javaclass : java.import('jadx.api.JavaClass'),
- _jadx_classnode : java.import('jadx.core.dex.nodes.ClassNode'),
+const fs = require('fs');
+const path = require('path');
+const { execSync } = require('child_process');
+const yauzl = require('yauzl');
+const cheerio = require('cheerio');
+
+const cwd = process.cwd();
+const _config = {
+ apk: '',
+ dir: ''
};
+const _last = { dir: '' };
+
+
+const APKTOOL_JAR = path.join(__dirname, 'java', 'apktool_2.4.1.jar');
+const JADX_CLI_JAR = path.join(__dirname, 'java', 'jadx', 'jadx-cli.jar');
-var init = function(config) {
+var init = function (config) {
for (var i in config) {
_config[i] = config[i];
}
- // prepare apk and outputdir location
- var _apk = _config.apk, _outd = _config.dir;
- if (_config.apk.charAt(0)!=path.sep && _config.apk.charAt(0)!='~') {
- _config.full_apk = path.join(cwd,_config.apk);
+ if (_config.apk.charAt(0) !== path.sep && _config.apk.charAt(0) !== '~') {
+ _config.full_apk = path.join(cwd, _config.apk);
}
- if (_config.dir.charAt(_config.dir.length-1)!=path.sep) {
- // if outputdir doesn't end in / or path separator, add it.
- _config.full_dir = _config.dir+''+path.sep;
+ if (_config.dir.charAt(_config.dir.length - 1) !== path.sep) {
+ _config.full_dir = _config.dir + '' + path.sep;
}
- // turn standard java logger off
- classes._javalog.getLogManagerSync().resetSync();
};
-var extractAPK = function(cb) {
+var extractAPK = function (cb) {
if (fileExists(_config.apk)) {
_last.dir = _config.full_dir;
- var decoder = new classes.ApkDecoder();
- var _apkfile = new classes.File(_config.full_apk);
- decoder.setForceDeleteSync(true);
- decoder.setDecodeResourcesSync(java.newShort(256)); // exclude resources
- decoder.setOutDirSync(new classes.File(_config.full_dir));
- decoder.setApkFileSync(_apkfile);
- decoder.decodeSync();
- // try to decrypt manifest
- // get Resources Table
- var _res = decoder.getResTableSync();
- var _ext = new classes.ExtFile(_apkfile);
- var _lib = new classes.libResources();
- _lib.decodeManifest(_res, _ext, new classes.File(_config.full_dir), function() {
+
+
+
+
+ try {
+ const cmd = `java -jar "${APKTOOL_JAR}" d -f -o "${_config.full_dir}" "${_config.full_apk}"`;
+ execSync(cmd, { stdio: 'inherit' });
cb(true);
- });
+ } catch (err) {
+ console.error('Apktool extraction failed:', err);
+ cb(false);
+ }
} else {
cb(false);
}
};
-var decompile = function(onReady) {
- // extract classes.dex into output
- extract_dex(function() {
- // decrypt dex into src, using jadx
- var _dir = new classes.File(_last.dir + 'src' + path.sep);
- var _dex = new classes.File(_last.dir + 'classes.dex');
- var _dexs = java.newInstanceSync("java.util.ArrayList");
- _dexs.addSync(_dex);
- var _args = new classes._jadx_args();
- _args.setOutputDir(_dir);
- var jadx = new classes._jadx(_args);
- jadx.setOutputDir(_dir);
- //get sources manually, to avoid threads
- /*jadx.loadFiles(_dexs, function() {
- console.log('requesting classes:');
- var _j_classes = jadx.getClassesSync();
- console.log('got classes:',_j_classes);
- for (var _o in _j_classes) {
- //var _cl_node = new classes._jadx_classnode();
- var cls = new classes._jadx_javaclass(_j_classes[_o], jadx);
- console.log(cls);
- //.decompile(function(){
- // console.log('decompiling class:'+_o);
- //});
- }
- });*/
- /**/
- jadx.loadFiles(_dexs, function() {
- jadx.save(function() {
- onReady();
- });
- });/**/
+var decompile = function (onReady) {
+ extract_dex(function () {
+ var srcDir = path.join(_last.dir, 'src');
+ var dexFile = path.join(_last.dir, 'classes.dex');
+
+
+
+ try {
+ const cmd = `java -jar "${JADX_CLI_JAR}" -d "${srcDir}" "${dexFile}"`;
+ execSync(cmd, { stdio: 'inherit' });
+ onReady();
+ } catch (err) {
+ console.error('JADX decompilation failed:', err);
+ onReady();
+ }
});
};
-var extract_dex = function(onReady) {
- // extract classes.dex from apk into outputdir.
- var yauzl = require('yauzl');
- yauzl.open(_config.apk, { lazyEntries: false }, function(err,zipfile) {
+var extract_dex = function (onReady) {
+ yauzl.open(_config.apk, { lazyEntries: false }, function (err, zipfile) {
if (err) throw err;
- // zipfile.readEntry();
- zipfile.on('entry', function(entry) {
+ zipfile.on('entry', function (entry) {
if (!/\/$/.test(entry.fileName)) {
- // file
- zipfile.openReadStream(entry, function(err2, readStream) {
- //if (err2) throw err2;
- if (entry.fileName=='classes.dex') {
- readStream.pipe(fs.createWriteStream(_last.dir + entry.fileName));
+ zipfile.openReadStream(entry, function (err2, readStream) {
+ if (entry.fileName === 'classes.dex') {
+ const writeStream = fs.createWriteStream(path.join(_last.dir, entry.fileName));
+ readStream.pipe(writeStream);
zipfile.close();
- setTimeout(function(){
- onReady();
- }, 350); // delay for zip to release lock on dex
+ writeStream.on('finish', function () {
+ setTimeout(onReady, 350);
+ });
}
});
}
@@ -134,51 +85,42 @@ var extract_dex = function(onReady) {
});
};
-var info = function(callback) {
- // to be called after 'extractAPK', gets info about APK from decoded AndroidManifest.xml
- var cheerio = require('cheerio');
- var reply = {};
- var _manifest = _last.dir + 'AndroidManifest.xml';
+var info = function (callback) {
+ var _manifest = path.join(_last.dir, 'AndroidManifest.xml');
if (fileExists(_manifest)) {
- fs.readFile(_manifest, function(err,_data) {
- if (err) callback(true,{});
- var $ = cheerio.load(_data, { xmlMode:true });
- reply['package'] = $('manifest[package]').attr('package');
- reply['versionCode'] = $('manifest').attr('android\:versionCode');
- reply['versionName'] = $('manifest').attr('android\:versionName');
- reply['appName'] = $('manifest application').attr('android\:label');
- reply['_dir'] = _last.dir;
+ fs.readFile(_manifest, function (err, _data) {
+ if (err) return callback(true, {});
+ var $ = cheerio.load(_data, { xmlMode: true });
+ var reply = {
+ 'package': $('manifest[package]').attr('package'),
+ 'versionCode': $('manifest').attr('android:versionCode'),
+ 'versionName': $('manifest').attr('android:versionName'),
+ 'appName': $('manifest application').attr('android:label'),
+ '_dir': _last.dir
+ };
callback(false, reply);
});
} else {
console.log('apk_unpack -> run \'extract\' method before \'info\'.');
- callback(true, {})
+ callback(true, {});
+ }
+};
+
+var fileExists = function (filePath) {
+ try {
+ return fs.statSync(filePath).isFile();
+ } catch (err) {
+ return false;
}
};
-var fileExists = function(filePath)
-{
- try
- {
- return fs.statSync(filePath).isFile();
- }
- catch (err)
- {
- return false;
- }
-}
-
-var dirExists = function(filePath)
-{
- try
- {
- return fs.statSync(filePath).isDirectory();
- }
- catch (err)
- {
- return false;
- }
-}
+var dirExists = function (filePath) {
+ try {
+ return fs.statSync(filePath).isDirectory();
+ } catch (err) {
+ return false;
+ }
+};
exports.init = init;
exports.extract = extractAPK;