This is a function I created called the
createPayloadDirectory function. This
function determines the appropriate name
for a directory where payload files will
be placed within an Android APK. It does
so by analyzing the existing directories
in the decompiled APK and creating a new
directory name based on the naming
conventions used in the APK's "smali"
directory structure.
This new directory is intended to hold the
payload-specific files before generating the
final modified APK.
ℹ️ Info
-
It takes an array of
filesas input, which represents the list of files and directories in a decompiled APK folder. -
It defines an array called
ignoreDirs, containing directory names that should be ignored during the process. These directories are typically common directories in Android apps that don't need to be considered for payload placement. -
It filters the
filesarray to get a list of directories that are not in theignoreDirslist. This filtered list is stored in thesmaliListvariable. -
It sorts the
smaliListarray in ascending order using a custom collator with numeric comparison. -
It checks if the last item in the sorted
smaliListarray is named"smali". If it is, the function sets thepayloadSmaliFoldervariable to'/smali_classes2'and returns it. -
If the last item in the
smaliListarray is not named"smali", the function extracts a number from its name using a regular expression and increments that number. It then constructs a new directory name in the format'/smali_classes' + newSmaliNumberand returns it.
🧑💻 Code
- declare the needed imports for the function.
const fs = require('fs-extra');
const apkFolder = 'path/to/decompiled/apk'- declare the
createPayloadDirectoryfunction itself.
var createPayloadDirectory = (files) => {
var ignoreDirs = ['original',
'res',
'build',
'kotlin',
'lib',
'assets',
'META-INF',
'unknown',
'smali_assets'];
var smaliList = files.filter((item) => item.isDirectory() && !(ignoreDirs.includes(item.name))).map((item) => item.name);
var collator = new Intl.Collator([], {
numeric: true
});
smaliList.sort((a, b) => collator.compare(a, b));
var lastSmali = smaliList[smaliList.length - 1];
if (lastSmali == "smali") {
payloadSmaliFolder = '/smali_classes2';
return payloadSmaliFolder;
} else {
var extractSmaliNumber = lastSmali.match(/[a-zA-Z_]+|[0-9]+/g);
var lastSmaliNumber = parseInt(extractSmaliNumber[1]);
var newSmaliNumber = lastSmaliNumber + 1;
var payloadSmaliFolder = '/smali_classes' + newSmaliNumber;
return payloadSmaliFolder;
}
};- Run the function and handle it's output like so.
var someFunction = (apkFolder) => {
// Read the Decompiled APK folder
console.log('[★] Reading the Decompiled Original Application...')
fs.readdir(apkFolder, {
withFileTypes: true
}, (error, files) => {
if (error) {
console.log('[x] Failed to Read the Decompiled Original Application!\n' + error);
return;
}
// create the smali payload directory
console.log(`[★] Creating the ${payloadSmaliFolder} Directory...`);
const payloadSmaliFolder = createPayloadDirectory(files);
const targetPayloadFolder = path.join(apkFolder, payloadSmaliFolder);
fs.mkdir(targetPayloadFolder, {
recursive: true
}, (error) => {
if (error) {
console.log(`[x] Unable to Create the ${payloadSmaliFolder} Directory!\n` + error);
return;
}
// do something with the newly created smali directory such as copy over android payload files.
});
});
}