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
files
as 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
files
array to get a list of directories that are not in theignoreDirs
list. This filtered list is stored in thesmaliList
variable. -
It sorts the
smaliList
array in ascending order using a custom collator with numeric comparison. -
It checks if the last item in the sorted
smaliList
array is named"smali"
. If it is, the function sets thepayloadSmaliFolder
variable to'/smali_classes2'
and returns it. -
If the last item in the
smaliList
array 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' + newSmaliNumber
and returns it.
🧑💻 Code
- declare the needed imports for the function.
const fs = require('fs-extra');
const apkFolder = 'path/to/decompiled/apk'
- declare the
createPayloadDirectory
function 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.
});
});
}