Skip to content
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
764783a
test for ability to create interface
giantpune Feb 3, 2017
d027655
test for ability to create interface
giantpune Feb 3, 2017
ed66b84
test for class.forName hookingf
giantpune Feb 3, 2017
2e05b97
method invoke test is there, but just hangs forever
giantpune Feb 3, 2017
6469481
tests for hooks around native code loading
giantpune Feb 3, 2017
7b18348
uncomment working tests
giantpune Feb 3, 2017
c6a6b01
uncomment working tests
giantpune Feb 3, 2017
c88689f
cipiher stuffs
giantpune Feb 3, 2017
4c50462
fix cipher test
giantpune Feb 3, 2017
a83b376
comments
giantpune Feb 3, 2017
9ffb23c
use semistandard spacing
giantpune Feb 6, 2017
cd656a2
remove cipher mode test becusae ole already got one of those
giantpune Feb 6, 2017
deb15ee
Merge branch 'master' of github.com:frida/frida-java into fix/add_int…
giantpune Feb 6, 2017
e86a5c2
use 'send' rether than roundabout tomfoolery to send messages back fr…
giantpune Feb 6, 2017
e0bc392
use 'make js pretty again
giantpune Feb 6, 2017
7db82d4
use 'make js pretty
giantpune Feb 6, 2017
2701722
name -> interfaceCannotBeInstantiated
giantpune Feb 6, 2017
ecdf92b
test for constructors return correct type
giantpune Feb 6, 2017
286ab15
re-re-uncomment other tests
giantpune Feb 6, 2017
27fad93
update system.load and runtime.loadlibrary tests. better syntax, nam…
giantpune Feb 6, 2017
abbb5a6
commit so i can merge upstream
giantpune Feb 7, 2017
72421c2
Merge branch 'master' of github.com:frida/frida-java into fix/add_int…
giantpune Feb 7, 2017
3d01dee
prettify
giantpune Feb 7, 2017
4440b87
prettify
giantpune Feb 7, 2017
2a86a1b
prettify
giantpune Feb 7, 2017
a56fec4
prettify
giantpune Feb 7, 2017
85feb88
prettify
giantpune Feb 7, 2017
d220742
comment out the 2 tests that completely break everything
giantpune Feb 7, 2017
e9c0342
prettify
giantpune Feb 7, 2017
595c09f
prettify
giantpune Feb 7, 2017
fd48c2e
prettify
giantpune Feb 7, 2017
c5168d7
prettify
giantpune Feb 7, 2017
72633df
prettify
giantpune Feb 7, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions test/re/frida/MethodTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertNull;
import org.junit.rules.ExpectedException;

import javax.crypto.Cipher;
import java.io.IOException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class MethodTest {
@Rule
Expand Down Expand Up @@ -56,6 +59,165 @@ public void replacementPropagatesExceptions() {
badger.die();
}

@Test
public void interfaceCannotBeInstantiated() {
loadScript("var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');" +
"try {" +
" var tm = X509TrustManager.$new();" +
" send('ok');" +
"} catch (e) {" +
" send('couldnt create trustmanager');" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just 'error' here if we're going to assert on it below.

"}");
assertEquals("ok", script.getNextMessage());
}

@Test
public void genericReturnJavaLangClass() {
loadScript("var C = Java.use('java.lang.Class');" +
"try {" +
" var method1 = C.forName.overload('java.lang.String');" +
" method1.implementation = function (s) {" +
" return method1.call(this, s);" +
" };" +
" var d = C.forName('re.frida.MethodTest');" +
" send('ok');" +
"} catch (e) {" +
" send('class.forName failed. ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

@Test
public void genericReturnBadger() {
loadScript("var C = Java.use('re.frida.Badger');" +
"try {" +
" var method1 = C.forName;" +
" method1.implementation = function () {" +
" return method1.call(this);" +
" };" +
" var d = C.forName();" +
" send('ok');" +
"} catch (e) {" +
" send('forName failed. ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

// this one still just producing
// Error: access violation accessing 0xf2b295fe
@Test
public void nativeReturnGenericVmStack() {
loadScript(
"try {" +
" var C = Java.use('dalvik.system.VMStack');" +
" var method1 = C.getStackClass2;" +
" method1.implementation = function () {" +
" return method1.call(this);" +
" };" +
" var stack = C.getStackClass2();" +
" send('ok');" +
"} catch (e) {" +
" send('nativeReturnGeneric: ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

// this one still just producing
// Error: access violation accessing 0x2133c66a
@Test
public void nativeReturnGenericBadgerWrapperAroundJavaLangClass() {
loadScript(
"try {" +
" var C = Java.use('re.frida.Badger');" +
" var method1 = C.forNameYo;" +
" method1.implementation = function () {" +
" return method1.call(this);" +
" };" +
" var test = C.forNameYo('re.frida.Badger', false, null);" +
" send('ok');" +
"} catch (e) {" +
" send('nativeReturnGeneric: ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

// this one was just hanging indefinitely during the test, but in an actual app, it was crashing
//! either one of those is bad.
//@Test
public void methodInvoke() {
loadScript("var C = Java.use('java.lang.reflect.Method');" +
"var C2 = Java.use('java.lang.Class');" +
"try {" +
// hook the original
" var method1 = C.invoke;" +
" method1.implementation = function () {" +
" return method1.apply(this, arguments);" +
" };" +

// now call it and see what happens
" var cl = C2.forName('re.frida.Badger');" +
" var method2 = cl.getMethod('returnZero', 'int');" +
" var ret = method2.invoke();" +
" send('ok');" +
"} catch (e) {" +
" send('Method.invoke: ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

@Test
public void loadWorks() {
loadScript("var C = Java.use('java.lang.System');" +
"try {" +
" var method1 = C.load;" +
" method1.implementation = function (s) {" +
" return method1.call(this, s);" +
" };" +
" C.load('/system/lib/libc.so');" +
" send('ok');" +
"} catch (e) {" +
" send('System.load: ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

@Test
public void runtimeLoadLibrary() {
loadScript("var C = Java.use('java.lang.Runtime');" +
"try {" +
" var method1 = C.loadLibrary.overload('java.lang.String');" +
" method1.implementation = function (s) {" +
" return method1.call(this, s);" +
" };" +

// now look up the function again and call it
" var now = C.loadLibrary.overload('java.lang.String');" +
" now.call(C, '/system/lib/libc.so');" +
" send('ok');" +
"} catch (e) {" +
" send('Runtime.loadLibrary: ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

//@Test
public void constructorReturnsCorrectType() {
loadScript("var C = Java.use('javax.crypto.spec.SecretKeySpec');" +
"try {" +
" var method1 = C.$init.overload('[B', 'java.lang.String');" +
" method1.implementation = function (a, b) {" +
" return method1.call(this, a, b);" +
" };" +

// now look up the function again and call it
" var testConstructor = C.$new([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'AES');" +
" send('ok');" +
"} catch (e) {" +
" send('SecretKeySpec: ' + e);" +
"}");
assertEquals("ok", script.getNextMessage());
}

@Test
public void staticFieldCanBeRead() {
loadScript("var Cipher = Java.use('javax.crypto.Cipher');" +
Expand Down Expand Up @@ -88,4 +250,16 @@ class Badger {
void die() {
throw new IllegalStateException("Already dead");
}

static Class<?> forName() {
return Badger.class;
}

public static Class<?> forNameYo(String className, boolean shouldInitialize, ClassLoader classLoader) throws ClassNotFoundException {
return java.lang.Class.forName(className, shouldInitialize, classLoader);
}

public int returnZero() {
return 0;
}
}