Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: frida/frida-java-bridge
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 889b2d0be9348cd058c147fd485d394de26622af
Choose a base ref
...
head repository: frida/frida-java-bridge
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 65abf81c5f3105ab46c1c8d7e232b05541632074
Choose a head ref

Commits on Feb 4, 2019

  1. Improve the Android 9 fix

    Apps targeting older Android versions are subject to the old behavior.
    oleavr committed Feb 4, 2019
    Copy the full SHA
    7fe0e72 View commit details
  2. 2.0.7

    oleavr committed Feb 4, 2019
    Copy the full SHA
    cc8e375 View commit details
  3. Copy the full SHA
    c2d9f1b View commit details
  4. Copy the full SHA
    304f237 View commit details
  5. 2.0.8

    oleavr committed Feb 4, 2019
    Copy the full SHA
    57facf9 View commit details

Commits on Mar 12, 2019

  1. Fix Android 9 method hooking reliability

    The new kAccPublicApi flag got confused with kAccXposedHookedMethod.
    
    Kudos to @giantpune for reporting.
    oleavr committed Mar 12, 2019
    Copy the full SHA
    ffd29ca View commit details
  2. 2.0.9

    oleavr committed Mar 12, 2019
    Copy the full SHA
    5bd1aa8 View commit details

Commits on Mar 13, 2019

  1. Fix crash when !Java.available

    oleavr committed Mar 13, 2019
    Copy the full SHA
    fe21877 View commit details
  2. 2.0.10

    oleavr committed Mar 13, 2019
    Copy the full SHA
    87d6a7e View commit details

Commits on Mar 18, 2019

  1. Fix method hooking reliability

    By deoptimizing everything when the first method is hooked.
    
    This is essential on newer versions of Android where optimizations are
    more aggressive. It is however a performance regression, but we can
    always optimize this later by hooking the optimized native code.
    
    Kudos to @giantpune for helping track this one down.
    oleavr committed Mar 18, 2019
    Copy the full SHA
    063f0ce View commit details
  2. Copy the full SHA
    f7c03b8 View commit details
  3. 2.0.11

    oleavr committed Mar 18, 2019
    Copy the full SHA
    d9224e9 View commit details

Commits on Mar 20, 2019

  1. Add Java.deoptimizeEverything()

    And revert the automatic deoptimization behavior that was recently
    introduced. For now we'll leave it up to users to enable it when needed.
    
    Also improve portability.
    oleavr committed Mar 20, 2019
    Copy the full SHA
    47a7a13 View commit details
  2. 2.0.12

    oleavr committed Mar 20, 2019
    Copy the full SHA
    6bbe8e3 View commit details

Commits on Mar 21, 2019

  1. Copy the full SHA
    cb5da52 View commit details
  2. 2.0.13

    oleavr committed Mar 21, 2019
    Copy the full SHA
    fbc2398 View commit details

Commits on May 1, 2019

  1. Rewrite Java.deoptimizeEverything() using art::Dbg

    Accomplishing this using the underlying Instrumentation API directly
    means we'd have to deal with a lot of internals to be able to do so
    safely. It also makes it tricky in case a debugger is already present.
    
    Using the higher level Dbg API sidesteps these issues, at the expense
    of being a bit more intrusive considering the listening socket being
    opened. But we can always instrument that away later.
    oleavr committed May 1, 2019
    Copy the full SHA
    afc030b View commit details
  2. 2.0.14

    oleavr committed May 1, 2019
    Copy the full SHA
    f6dc756 View commit details
  3. Bump test dependencies

    oleavr committed May 1, 2019
    Copy the full SHA
    00d222f View commit details

Commits on May 6, 2019

  1. Copy the full SHA
    04acb04 View commit details
  2. 2.0.15

    oleavr committed May 6, 2019
    Copy the full SHA
    bc65d22 View commit details
  3. 2.0.16

    oleavr committed May 6, 2019
    Copy the full SHA
    bbe78be View commit details

Commits on May 14, 2019

  1. Fix invalid instruction crash on arm64

    The logic that recompiles ExceptionClear() did not stop parsing after
    the noreturn call to __stack_chk_fail(), which typically falls through
    to the next function. That meant we recompiled a lot more code than we
    needed to. That was however the best-case scenario, because turns out
    there was another scenario where alignment padding was inserted before
    the next function, and Instruction.parse() would choke on that.
    
    The ideal solution would have been to recognize the call to
    __stack_chk_fail(), but given how complex that is, we instead look out
    for a sudden fall-through to the next function, or an unexpected zero-
    padding word.
    
    Kudos to @giantpune for helping track this one down.
    oleavr committed May 14, 2019
    Copy the full SHA
    e7d563b View commit details
  2. 2.0.17

    oleavr committed May 14, 2019
    Copy the full SHA
    09f3cfc View commit details

Commits on May 17, 2019

  1. Add workaround for ART exception delivery bug

    One particular code-path in the exception delivery logic assumes there
    is always at least one Java stack frame on the current art::Thread.
    
    Kudos to @giantpune for helping track this one down.
    oleavr committed May 17, 2019
    Copy the full SHA
    e4027e1 View commit details
  2. 2.0.18

    oleavr committed May 17, 2019
    Copy the full SHA
    071adc6 View commit details
  3. Improve the recompilation logic

    To also avoid falling into the next function on non-arm64.
    oleavr committed May 17, 2019
    Copy the full SHA
    0a1ea87 View commit details
  4. Fix ART internals parsing in JNI checked mode

    Try resolving using symbols and fall back to the vtable, like before.
    oleavr committed May 17, 2019
    Copy the full SHA
    361af39 View commit details
  5. Copy the full SHA
    2bba8fe View commit details
  6. Configure JDWP to use ADB as transport

    As not all apps are able to open a TCP listening port.
    oleavr committed May 17, 2019
    Copy the full SHA
    bf66cbc View commit details

Commits on May 18, 2019

  1. Copy the full SHA
    269b18c View commit details
  2. 2.0.19

    oleavr committed May 18, 2019
    Copy the full SHA
    8d106a9 View commit details
  3. Add proper support for JNI checked mode

    Without relying on debug symbols.
    oleavr committed May 18, 2019
    Copy the full SHA
    f112382 View commit details
  4. 2.0.20

    oleavr committed May 18, 2019
    Copy the full SHA
    c8ae2bb View commit details

Commits on May 26, 2019

  1. Add ArtStackVisitor

    Useful for stack exploration.
    
    For now we only cover the underlying C++ API partially.
    oleavr committed May 26, 2019
    Copy the full SHA
    fdbbe1e View commit details
  2. Fix intermittent crash during ART exception delivery

    Turns out ART may get the frame size of hooked methods wrong during
    exception delivery. All we need to do to correct this little mix-up
    is to ensure that ArtMethod's GetOatQuickMethodHeader() always returns
    nullptr for hooked methods.
    oleavr committed May 26, 2019
    Copy the full SHA
    e546e74 View commit details

Commits on May 27, 2019

  1. Partially stub out the ADB JDWP transport

    To ensure we always succeed in starting it. This also makes it possible
    to impersonate the debugger, which might be worth exploring as a way to
    use ART's instrumentation APIs through a stable wire protocol.
    oleavr committed May 27, 2019
    Copy the full SHA
    e88ddbb View commit details
  2. 2.0.21

    oleavr committed May 27, 2019
    Copy the full SHA
    df695b7 View commit details
  3. Port ART exception delivery fix to 32-bit targets

    Where the GetOatQuickMethodHeader() signature is slightly different, due
    to uintptr_t obviously being a different type.
    oleavr committed May 27, 2019
    Copy the full SHA
    77c2975 View commit details
  4. 2.0.22

    oleavr committed May 27, 2019
    Copy the full SHA
    cd25aba View commit details

Commits on May 28, 2019

  1. Speed up the GetOatQuickMethodHeader() hook

    Turns out this function is quite hot when running the VM in interpreter-
    only mode. E.g. it's called close to 8 million times when launching the
    Dropbox app from start to login screen.
    
    We speed things up by emitting a little bit of machine code that looks
    at the ArtMethod and avoids the context-switch into JS for methods that
    are definitely not hooked.
    oleavr committed May 28, 2019
    Copy the full SHA
    db05c57 View commit details
  2. 2.0.23

    oleavr committed May 28, 2019
    Copy the full SHA
    ab7edfa View commit details

Commits on May 30, 2019

  1. Copy the full SHA
    abe1ee2 View commit details
  2. Revive multi-instance support

    There could be more than one script using frida-java, so we cannot
    assume that:
    
    A) We know of all the hooked methods.
    B) GetOatQuickMethodHeader() hasn't already been replaced.
    
    The challenge with A) is that ArtMethod doesn't have any unused bits we
    can use to tag the patched instances.
    
    We mitigate A) by detecting the entrypoint of Frida's libffi closures,
    which is going to be the same assuming agent and gadget aren't loaded at
    the same time and both using frida-java.
    
    For now we gracefully handle B) by assuming that the first script stays
    around for as long as the other scripts depending on this. It's not ideal,
    but it will have to do for now.
    oleavr committed May 30, 2019
    Copy the full SHA
    176100f View commit details
  3. 2.0.24

    oleavr committed May 30, 2019
    Copy the full SHA
    d5ed5ac View commit details

Commits on Jun 1, 2019

  1. Copy the full SHA
    8e671ad View commit details
  2. Bump Frida SDK to 12.6.2

    oleavr committed Jun 1, 2019
    Copy the full SHA
    ff404fc View commit details
  3. Copy the full SHA
    a69c471 View commit details
  4. 2.0.25

    oleavr committed Jun 1, 2019
    Copy the full SHA
    07c26f3 View commit details

Commits on Jun 9, 2019

  1. Fix ART internals parsing for 32-bit ARM

    Code generation was using the wrong register name.
    oleavr committed Jun 9, 2019
    Copy the full SHA
    6f3fea0 View commit details
Showing with 3,300 additions and 4,413 deletions.
  1. +2 −2 README.md
  2. +16 −10 index.js
  3. +1,082 −134 lib/android.js
  4. +0 −2 lib/api.js
  5. +158 −161 lib/class-factory.js
  6. +8 −8 lib/env.js
  7. +130 −69 lib/mkdex.js
  8. +0 −2 lib/result.js
  9. +12 −10 lib/vm.js
  10. +1 −958 package-lock.json
  11. +2 −32 package.json
  12. +18 −0 test/.babelrc
  13. +1 −1 test/Makefile
  14. +0 −2 test/bundle.js
  15. +1,584 −2,991 test/package-lock.json
  16. +3 −26 test/package.json
  17. +246 −2 test/re/frida/ClassCreationTest.java
  18. +7 −0 test/re/frida/EatableWithField.java
  19. +5 −0 test/re/frida/Fruit.java
  20. +16 −0 test/re/frida/MethodTest.java
  21. +6 −0 test/re/frida/PrimitiveArray.java
  22. +3 −3 test/runner.c
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -8,13 +8,13 @@ through the global named `Java`.
### Dependencies

- Android SDK Platform-Tools >= 27.0.1
- Android NDK r15c
- Android NDK r20

With environment configured accordingly:

```sh
$ export ANDROID_SDK_ROOT=~/Library/Android/Sdk
$ export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk-r15c
$ export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk-r20
```

### Configuration
26 changes: 16 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
'use strict';

const getApi = require('./lib/api');
const {
getAndroidVersion,
withAllArtThreadsSuspended,
withRunnableArtThread,
makeArtClassVisitor,
makeArtClassLoaderVisitor
makeArtClassLoaderVisitor,
deoptimizeEverything
} = require('./lib/android');
const ClassFactory = require('./lib/class-factory');
const Env = require('./lib/env');
@@ -231,18 +230,18 @@ function Runtime () {
const loadedClassesOffset = 172;
const hashEntrySize = 8;
const ptrLoadedClassesHashtable = api.gDvm.add(loadedClassesOffset);
const hashTable = Memory.readPointer(ptrLoadedClassesHashtable);
const tableSize = Memory.readS32(hashTable);
const hashTable = ptrLoadedClassesHashtable.readPointer();
const tableSize = hashTable.readS32();
const ptrpEntries = hashTable.add(12);
const pEntries = Memory.readPointer(ptrpEntries);
const pEntries = ptrpEntries.readPointer();
const end = tableSize * hashEntrySize;

for (let offset = 0; offset < end; offset += hashEntrySize) {
const pEntryPtr = pEntries.add(offset);
const dataPtr = Memory.readPointer(pEntryPtr.add(4));
const dataPtr = pEntryPtr.add(4).readPointer();
if (!(HASH_TOMBSTONE.equals(dataPtr) || dataPtr.isNull())) {
const descriptionPtr = Memory.readPointer(dataPtr.add(24));
const description = Memory.readCString(descriptionPtr);
const descriptionPtr = dataPtr.add(24).readPointer();
const description = descriptionPtr.readCString();
callbacks.onMatch(description);
}
}
@@ -402,6 +401,13 @@ function Runtime () {
return classFactory.registerClass(spec);
};

Object.defineProperty(this, 'deoptimizeEverything', {
enumerable: true,
value: function () {
return deoptimizeEverything(vm, vm.getEnv());
}
});

Object.defineProperty(this, 'vm', {
enumerable: false,
get: function () {
@@ -426,7 +432,7 @@ function Runtime () {
const buffer = Memory.alloc(bufferSize);
const size = readlink(pathname, buffer, ptr(bufferSize)).toInt32();
if (size !== -1) {
const exe = Memory.readUtf8String(buffer, size);
const exe = buffer.readUtf8String(size);
cachedIsAppProcess = [/^\/system\/bin\/app_process/.test(exe)];
} else {
cachedIsAppProcess = [true];
Loading