I am trying to hook function of android messaging application.
I run frida hook script. then I get a following error:
Error: java.lang.ClassNotFoundException: Didn't find class "i0.a.a.a.e3.z" on path: DexPathList[[/data/app/xxxxx==/base.apk]]
In Jadx-Gui, base.apk is decompiled as follows
package i0.a.a.a.e3;
/* loaded from: classes5.dex */
public final class z {
}
script is as follows
let z = Java.use("i0.a.a.a.e3.z");
How can I solve this error?
Try running your hook inside the Java.perform() method of Frida.
Java.perform(function() {
let z = Java.use("i0.a.a.a.e3.z");
z["somefunction"].implementation = function (str) {
console.log('somefunctionis called' + ', ' + 'str: ' + str);
let ret = this.somefunction(str);
console.log('somefunctionret value is ' + ret);
return ret;
};
})
It solved my problem that was similar to yours.
Related
I want to overload following method that I found by decompiling Android app with apktool:
invoke-virtual {v0, v4, v3}, Lokhttp3/aa$a;->b(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/aa$a;
Here is my Frida script:
Java.perform(function() {
var targetClass = Java.use("okhttp3.aa$a");
targetClass.b.overload("java.lang.String", "java.lang.String").implementation = function(a, b) {
console.log("str1:" + a);
console.log("str2:" + b);
return this.b(a, b);
}
});
Hook fails with:
[ERROR] Error: expected a pointer
at value (frida/runtime/core.js:170)
at At (frida/node_modules/frida-java-bridge/lib/android.js:879)
at activate (frida/node_modules/frida-java-bridge/lib/android.js:960)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/android.js:740)
at forEach (native)
at St (frida/node_modules/frida-java-bridge/lib/android.js:741)
at kt (frida/node_modules/frida-java-bridge/lib/android.js:732)
at vt (frida/node_modules/frida-java-bridge/lib/android.js:696)
at replace (frida/node_modules/frida-java-bridge/lib/android.js:1011)
at set (frida/node_modules/frida-java-bridge/lib/class-factory.js:1010)
at <anonymous> (/script2.js:3)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:16)
at _performPendingVmOps (frida/node_modules/frida-java-bridge/index.js:238)
at <anonymous> (frida/node_modules/frida-java-bridge/index.js:213)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:16)
at _performPendingVmOpsWhenReady (frida/node_modules/frida-java-bridge/index.js:232)
at perform (frida/node_modules/frida-java-bridge/index.js:192)
at <eval> (/script2.js:8)
How to correctly overload that method?
UPDATE
I figured out that error raised because I tried to load multiple scripts at once.
Is it possible?
import frida
import sys
package_name = "com.test.com"
def hook_okhttp_url():
hook_code = open('hook_okhttp_url.js').read()
return hook_code
def hook_cronet_header():
hook_code = open('hook_cronet_header.js').read()
return hook_code
def on_message(message, data):
if message['type'] == 'error':
print("[ERROR] " + message['stack'])
elif message['type'] == 'send':
print("[INFO] " + message['payload'])
else:
print(message)
device = frida.get_usb_device()
process = device.attach(package_name)
okhttp_script = process.create_script(hook_okhttp_url())
cronet_script = process.create_script(hook_cronet_header())
okhttp_script.on('message', on_message)
cronet_script.on('message', on_message)
print('[*] Running Hook Test ...')
okhttp_script.load()
cronet_script.load()
sys.stdin.read()
I figured out that error raised because I tried to load multiple scripts at once.
Is it possible?
When it comes to overloaded methods I prefer to hook and call method this way (as it makes less problems):
Java.perform(function() {
const targetClass = Java.use("okhttp3.aa$a");
const targetMethod = targetClass.b.overload("java.lang.String", "java.lang.String");
targetMethod.implementation = function(a, b) {
console.log("str1:" + a);
console.log("str2:" + b);
return targetMethod.call(this, a, b);
}
});
Ended up with concatenating all js files with my hooks into one.
I'm trying to get an argument from the command line using a Gradle task:
class myApk extends DefaultTask {
#Option(option="apkName", description="apkName for your file")
String apkName
#TaskAction
void uploadApk() {
def arg = "curl -F \"demo${apkName}.apk=" +
"#${project.projectDir}\\app\\build\\outputs\\apk\\debug\\app-debug.apk\" " +
"https://URL"
project.exec {
commandLine("cmd", "/c", arg)
}
}
}
task uploadApk(type: myApk) { }
But after typing gradle uploadApk --apkName=foo in the terminal I get this kind of exception:
Problem configuring task :app:uploadApk from command line.
> Unknown command-line option '--apkName'.
P.S. I've read this topic(How to pass arguments from command line to gradle), but it doesn't seem helpful for this problem;(
Thanks to the comment above, I used -P to work it out
I'm trying to upload a debug apk file to the server by Gradle. I'm using a special name for it, smth like "demo-testing.apk" or "demo-first.apk".
class Apk extends DefaultTask {
String apkName
#TaskAction
void uploadApk() {
exec {
commandLine(
"cmd",
"-c",
"curl -F \"demo${apkName}.apk=" +
"#${DEFAULT_BUILD_DIR_NAME}/outputs/apk/debug/app-debug.apk\" " +
"https://URL"
)
}
}
}
tasks.register("first", Apk) {
group = 'apkUploads'
description = 'Uploads first apk'
apkName = '-first'
}
But it doesn't execute(with proper URL in the command line arguments) due to this exception:
Caused by: org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method exec() for arguments [Apk$_uploadApk_closure1#58ed1
b0a] on task ':first' of type Apk.
Can someone please tell me what I'm doing wrong?
So thanks to the comment above I should have invoke project.exec instead of exec and it worked
i am using cordova-ionic framework to build app. i am new to the iOS or iPhone
in my requirement, i have to read a file in the app. i am reading file in the android app but same code showing error (code: 5).
i am following code types:
in android:
$cordovaFile.writeFile(( 'user.json', data, {'append':false} )).then(function(result) {
alert('file created.');
alert(JSON.stringify(result));
}, function(err) {
// An error occured. Show a message to the user
alert('file writed');
alert(JSON.stringify(err));
});
i can create file, writing, reading data and removing the file but in ios phone i am not able to create file using the same code.
in iPhone:
var data = {"user":{"name":"errer","email":"sdsdff#gmail.com","username":"sdfsdfsd"}};
$cordovaFile.writeFile(( 'user.json', data, {'append':false} )).then(function(result) {
// Success!
alert('file created.');
alert(JSON.stringify(result));
}, function(err) {
// An error occured. Show a message to the user
alert('file writed');
alert(JSON.stringify(err));
});
i just change my directory is cordova.file.cacheDirecotry/cordova.file.applicationDirectory
$cordovaFile.createFile(( cordova.file.cacheDirecotry+'user.json', true )).then(function(result) {
// Success!
alert('file created.');
alert(JSON.stringify(result));
}, function(err) {
// An error occured. Show a message to the user
alert('file writed');
alert(JSON.stringify(err));
});
all way getting the error like code: 12 or code: 5
please help me to solve this or give me a idea to get application file path
I have some progression.
First, I alert my cordova.file.dataDirectory or cordova.file.documentsDirectory.
They are
file:///var/mobile/...../Library/NoCloud
and
file:///var/mobile/..../Documents
Then I create a File without the prefix and succeed. Referring to this https://github.com/driftyco/ng-cordova/issues/362
and the success message shows that the native url of the file is saved in
file:///var/mobile/...../Library/files
Which is quite strange. By the way, I add the
<preference name="iosPersistentFileLocation" value="Library" />
according to https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md#ios-persistent-storage-location
All the tests are running on IOS, i haven't test for Android.
Updates
All the following code worked for me and give success response
$cordovaFile.checkFile('/test.data')
$cordovaFile.createFile('test.data',false)
$cordovaFile.checkDir('/')
Hope this can solve your problems.
/*
Here is what I am using for my Android and IOS apps
Keep attention to a couple of things:
- Android and IOS have other directorynames for files
- Android devices have different root (myFSRootDirectory1 = Samsung Tab 3, msFSRootDirectory2 = Samsung SII)
- $cordovaFile functions prefixes all pathnames with root
$cordovaFileTransfer functions needs absolute pathnames
Here I create the prefixes for File functions and FileTransfer functions for Android and IOS
*/
// The $ionicPlatform and ionic.Platorm are from Ionic framework
//
$ionicPlatform.ready(function() {
if (ionic.Platform.isAndroid()) {
// If running on Android
console.log('cordova.file.externalDataDirectory: ' + cordova.file.externalDataDirectory);
//
// I use cordova.file.externalDataDirectory because this url is for Android devices
// If you remove the app from the device these url are cleared too on the device. So keep it clean.
// Remove the root from cordova.file.externalDataDirectory
//
myFsRootDirectory1 = 'file:///storage/emulated/0/'; // path for tablet
myFsRootDirectory2 = 'file:///storage/sdcard0/'; // path for phone
fileTransferDir = cordova.file.externalDataDirectory;
if (fileTransferDir.indexOf(myFsRootDirectory1) === 0) {
fileDir = fileTransferDir.replace(myFsRootDirectory1, '');
}
if (fileTransferDir.indexOf(myFsRootDirectory2) === 0) {
fileDir = fileTransferDir.replace(myFsRootDirectory2, '');
}
console.log('Android FILETRANSFERDIR: ' + fileTransferDir);
console.log('Android FILEDIR: ' + fileDir);
}
if (ionic.Platform.isIOS()) {
// if running on IOS
console.log('cordova.file.documentsDirectory: ' + cordova.file.documentsDirectory);
// I use cordova.file.documentsDirectory because this url is for IOS (NOT backed on iCloud) devices
fileTransferDir = cordova.file.documentsDirectory;
fileDir = '';
console.log('IOS FILETRANSFERDIR: ' + fileTransferDir);
console.log('IOS FILEDIR: ' + fileDir);
}
if (ionic.Platform.isAndroid() || ionic.Platform.isIOS()) {
//
// Just functions from the list below one by one ( or chain them)
//
}
});
// Download file from 'http://www.yourdomain.com/test.jpg' to test/one/test.jpg on device Filesystem
var hostPath = 'http://www.yourdomain.com/test.jpg';
var clientPath = fileTransferDir + 'test/one/test.jpg';
var fileTransferOptions = {};
$cordovaFile.downloadFile(hostPath, clientPath, true, fileTransferOptions).then (function() {
});
// Create dir test
$cordovaFile.createDir(fileDir + 'test/').then( function(dirEntry) {
});
// Create dir aganin in dir test
$cordovaFile.createDir(fileDir + 'test/one/').then( function(dirEntry) {
});
// Create empty file test.txt in test/again/
$cordovaFile.createFile(fileDir + 'test/one/test.txt', true).then( function(fileEntry) {
});
// List of files in test/again
$cordovaFile.listDir(fileDir + 'test/one/').then( function(entries) {
console.log('list dir: ', entries);
});
// Write some text into file
$cordovaFile.writeFile(fileDir + 'test/one/test.txt', 'Some text te test filewrite', '').then( function(result) {
});
// Read text written in file
$cordovaFile.readAsText(fileDir + 'test/one/test.txt').then( function(result) {
console.log('readAsText: ', result);
});
Perhaps it's because of a typo? You have cordova.file.cacheDirecotry. Shouldn't that be : cordova.file.cacheDirectory ?
Refer to the original documentation :-
https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md#ios-file-system-layout
iOS has some directories as read-only. Try changing your path.
Let me know if it does not work for you.
I am developing a new Phonegap 3 application. I find the development process very slow. Each time I want to test a change in my app, I have to run in the console:
phonegap run android
This command takes about 30 seconds to run! Any idea on how to improve the time to test each change?
If you are developing for android using ecllipse you can use an android handset, connect it with your development machine with usb cable and install necessary drivers from here
.
Drivers are required mostly for windows in mac and linux it is usually not necessary. After set up it is just a matter of clicking run in your ide.
If you have a huge amount of files (libraries with demos, non-minified files, etc.), installing on the app can take a long long time.
I created this hook (added to before_prepare) which only copies the necessary files (specified in "requirements.json" in my project).
You need to run cd hooks/before_prepare && npm install ncp to install the dependency.
hooks/before_prepare/010copy_assets.js
#!/usr/bin/env node
console.log("=== Running copy required assets hook ===");
var fs = require('fs'),
path = require('path');
var mkdirSync = function(path) {
try {
fs.mkdirSync(path);
} catch (e) {
if (e.code != 'EEXIST') throw e;
}
}
var mkdirpSync = function(dirpath) {
var parts = dirpath.split(path.sep);
for (var i = 1; i <= parts.length; i++) {
mkdirSync(path.join.apply(null, parts.slice(0, i)));
}
}
try {
var ncp = require('ncp').ncp
var requirements = require('./../../myproject/requirements.json');
ncp.limit = 200;
ncp.stopOnErr = true;
requirements.forEach(function(requirement) {
var source = './myproject/' + requirement;
var destination = './www/' + requirement;
var folders = destination.split('/');
folders.pop();
mkdirpSync(path.normalize(folders.join('/')));
ncp(source, destination, function(err) {
if (err) {
console.log('====== Error! Did not copy asset from ' + source + ' to ' + destination + ' ======');
console.error(err);
process.exit(1001);
} else
console.log('====== Copied asset from ' + source + ' to ' + destination + ' ======');
});
});
} catch (e) {
console.error(e);
console.error(e.stack);
process.exit(1000);
}
example requirements.json
[
"js",
"css",
"img",
"index.html"
]
Note that you can move stuff directly into the build www directory (inside platforms) but they have different paths under ios and android