CalebFenton / simplify

Android virtual machine and deobfuscator
Other
4.41k stars 438 forks source link

Add emulated function and enhance sdbg output #144

Closed strazzere closed 4 years ago

strazzere commented 4 years ago

While doing some reversing one of the jiagu360 protectors, I wanted to test out sdbg and simplify. One of the easiest methods was failing and it seemed simple to fix -- hopefully I did it right.

Also added the breakpoint hit notification to sdbg so it will match gdb.

strazzere commented 4 years ago

Apparently I have merge power on this repo -- though I'd prefer you reviewing and merging these yourself so ensure I didn't do something stupid...

strazzere commented 4 years ago

For what it's worth, I did skim the safe_classes.cfg and safe_methods.cfg which seemed like ideal candidates. However these classes don't seem to have been included in android-25 jar, even though I believe they should have? I also wasn't sure if that was still used, and in the end this was just easier to add. Let me know if this other way was the proper one and I can redo it.

strazzere commented 4 years ago

Added a third small fix, which will prevent a heap object which is null from getting extra calls sent to it. This is reproducable via;

.class public final LStubApp;
.super Landroid/app/Application;
.source "SourceFile"

.field private static ᵢˑ:Landroid/content/Context;

.method public static getAppContext()Landroid/content/Context;
    .registers 1

    .prologue
    .line 61
    sget-object v0, LStubApp;->ᵢˑ:Landroid/content/Context;

    return-object v0
.end method
simplify .      
[1 / 1] Processing top level class LStubApp;
(1 / 1) Executing top level method: LStubApp;->getAppContext()Landroid/content/Context;
Simplifying: LStubApp;->getAppContext()Landroid/content/Context;
Exception in thread "main" java.lang.NullPointerException
        at org.cf.smalivm.context.HeapItem.getValueType(HeapItem.java:93)
        at org.cf.simplify.strategy.ConstantPropagationStrategy.canConstantizeAddress(ConstantPropagationStrategy.java:97)
        at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
        at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250)
        at java.util.Spliterators$IntArraySpliterator.forEachRemaining(Spliterators.java:1032)
        at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566)
        at org.cf.simplify.strategy.ConstantPropagationStrategy.getValidAddresses(ConstantPropagationStrategy.java:107)
        at org.cf.simplify.strategy.ConstantPropagationStrategy.perform(ConstantPropagationStrategy.java:48)
        at org.cf.simplify.Optimizer.simplify(Optimizer.java:109)
        at org.cf.simplify.Launcher.executeMethods(Launcher.java:221)
        at org.cf.simplify.Launcher.run(Launcher.java:141)
        at org.cf.simplify.Main.main(Main.java:14)
strazzere commented 4 years ago

Fwiw, after applying these patches you can simplify the "stub" application injected by jiagu/jiagu30;

Optimizations:
        constantized ifs = 0
        constantized ops = 0
        dead assignments removed = 0
        dead ops removed = 0
        dead results removed = 0
        nops removed = 0
        peephole optmizations = 0
        unreflected fields = 0
        unreflected methods = 0
        useless gotos removed = 0
Simplification complete:
        total classes = 7
        total methods = 2
        optimized methods = 31
        failed methods = 5
        run time = 327992 ms
Total optimizations:
        constantized ifs = 2
        constantized ops = 22
        dead assignments removed = 27
        dead ops removed = 7
        dead results removed = 6
        nops removed = 2
        peephole optmizations = 3
        unreflected fields = 0
        unreflected methods = 2
        useless gotos removed = 0
Writing output to _simple.dex

With the goodness being;

.method private static ᵢˋ()Ljava/lang/String;
    .registers 4

    .prologue
    .line 26
    :try_start_0
    const-string v0, "q~tb\u007fyt>q``>QsdyfydiDxbuqt"

    invoke-static {v0}, Lcom/qihoo/util/ᵢˏ;->ᵢˋ(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v0

    invoke-static {v0}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;

    move-result-object v0

    .line 27
    const-string v1, "sebbu~dQsdyfydiDxbuqt"

    invoke-static {v1}, Lcom/qihoo/util/ᵢˏ;->ᵢˋ(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v1

    const/4 v2, 0x0

    invoke-virtual {v0, v1, v2}, Ljava/lang/Class;->getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;

    move-result-object v1

    .line 28
    const/4 v2, 0x0

    const/4 v3, 0x0

    new-array v3, v3, [Ljava/lang/Object;

    invoke-virtual {v1, v2, v3}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v1

    .line 29
    const-string v2, "wudCicdu}S\u007f~duhd"

    invoke-static {v2}, Lcom/qihoo/util/ᵢˏ;->ᵢˋ(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v2

    const/4 v3, 0x0

    invoke-virtual {v0, v2, v3}, Ljava/lang/Class;->getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;

    move-result-object v0

    .line 30
    const/4 v2, 0x0

    new-array v2, v2, [Ljava/lang/Object;

    invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Landroid/content/Context;

    .line 31
    invoke-virtual {v0}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;

    move-result-object v0

    .line 32
    const-string v1, "PACKAGENAME"

    const/4 v2, 0x0

    invoke-virtual {v0, v1, v2}, Landroid/content/pm/PackageManager;->getApplicationInfo(Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo;

    move-result-object v0

Simplified to ->

.method private static ᵢˋ()Ljava/lang/String;
    .registers 4

    .prologue
    .line 26
    .line 27
    .line 28
    :try_start_0
    invoke-static {}, Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread;

    move-result-object v1

    .line 29
    const/4 v3, 0x0

    .line 30
    invoke-virtual {v1}, Landroid/app/ActivityThread;->getSystemContext()Landroid/app/ContextImpl;

    move-result-object v0

    check-cast v0, Landroid/content/Context;

    .line 31
    invoke-virtual {v0}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;

    move-result-object v0

    .line 32
    const-string v1, "PACKAGENAME"

    const/4 v2, 0x0

    invoke-virtual {v0, v1, v2}, Landroid/content/pm/PackageManager;->getApplicationInfo(Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo;

    move-result-object v0
CalebFenton commented 4 years ago

Thanks for the PR. Including the simplified stub at the end was a nice touch.

For what it's worth, I did skim the safe_classes.cfg and safe_methods.cfg which seemed like ideal candidates. However these classes don't seem to have been included in android-25 jar, even though I believe they should have?

IIRC, I was trying to update the framework and couldn't find a bunch of classes that were in previous frameworks. I'm not sure where the classes were hiding as I checked every dex, oat, art, lib, so, etc. and resorted to digging through android source code before getting distracted and moving in to something else.

I think white listing is the most correct solution, but until I can properly dump the latest framework, this is the best solution.

strazzere commented 4 years ago

Ok, that completely makes sense. I quickly looked for it in the android-25 and then android-29 as it was on my machine, but also didn't find the class I was looking for. I'll try to loop back and see if I can find where it's hiding later and potentially get a full framework dump as a proper fix.

apkunpacker commented 4 years ago

@strazzere sir may you upload that simplified jiagu stub dex here

strazzere commented 4 years ago

Nope. But you can build a jar and run it on whatever target you want.

On Wed, Jun 10, 2020, 21:00 Apkunpacker notifications@github.com wrote:

@strazzere https://github.com/strazzere sir may you upload that simplified jiagu stub dex here

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/CalebFenton/simplify/pull/144#issuecomment-642391660, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEYIRUYLAP4Y57PYKII2UTRWBJE3ANCNFSM4NZCB23Q .

apkunpacker commented 4 years ago

I tried already sir but unable to build on windows 7 due to long name issue

strazzere commented 4 years ago

Sorry, this thread isn't for support it's a pull request. This also isn't even my repo. Nor am I looking to run tools for other people.

You'll need to figure out how to compile and run this yourself in some other environment, wait for a new release or pay someone to do it for you.