冥界3大法王 发表于 2020-9-6 08:38

吸星大法抽取代码+安卓编程实现解决MT管理器没有一键注入代码的缺陷

本帖最后由 冥界3大法王 于 2020-9-6 09:34 编辑

从实战的角度说吧,我们经常在破解安卓程序的时候;您是否遇到了以下困扰?

[*]当前分析的.smali文件或当前的的activity (其实白话就是类似于Windows上看到的当前窗口名) 是否被执行过?能否执行到?
[*]何时被上一级调用的,又是哪个类调来的? 类名是?
[*]函数返回值是多少?
这些问题呢,其实对于懂安卓开发的来说根本不是个事,注入代码就能解决。

以下是本人从菜鸟的角度思考问题,并实战中发现新问题的解决途径和历程:
https://static.52pojie.cn/static/image/hrline/1.gif
我们在论坛上搜索【Toast】,会找到以下几个:我们找经典的几个来说事:

https://static.52pojie.cn/static/image/hrline/2.gif
普通的在OnCreate调用的代码如下:

const-string v1 "吾爱破解论坛"
const/4 v2 1
invoke-static {v6,v1,v2} Landroid/widget/Toast;-〉makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1} Landroid/widget/Toast;-〉show()V
这是最初的那种方法,也是最常见的那种。
优点是在当前的OnCreate之下添加,都在一个文件中操作!使用场合启动acivity时添加以来装逼使用。
缺陷:要传递的Vx寄存器不确定,用时菜鸟得自己来改,你得配合前后文来搞,这样才能让其正确的调用
而且当有多个文件想加入时,下面的代码不会被重用
而且这仅仅是弹框 ,并不能输出给DDMS 日志猫使用。
学安卓初期,我错误的看上了这种;认为是不是在随便的代码里都能添加上,完全不是这么一回事啊。

https://static.52pojie.cn/static/image/hrline/3.gif
下面的这种是论坛割绳子贴里同学stars-one大神搞的代码

创建一个crack.smali代码如下:
.class public Lcrack;
.super Ljava/lang/Object;
.source "craker.java"

.method public static toast(Landroid/content/Context;)V
    .locals 2
    .prologue

      const-string v0, "by stars-one"

      const/4 v1, 0x1

      invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

      move-result-object v0

      invoke-virtual {v0}, Landroid/widget/Toast;->show()V

      return-void
.end method


在onCreate方法里调用的代码
invoke-static {p0}, Lcrack;->toast(Landroid/content/Context;)V


以上这种方法,在MT管理器中,可以在dex编辑++模式下,找到文件夹,长按
方法名:你的程序包名(即在MT管理器点apk时看到的第一行)
类名: Crack
优点:如我要调用多次呢,可以复用。

https://static.52pojie.cn/static/image/hrline/5.gif
然后我们说,这是”吐丝特“ (Toast)并不是注入的代码啊。
论坛上还有一些高级版的https://www.52pojie.cn/search.php?mod=forum&searchid=1684&orderby=lastpost&ascdesc=desc&searchsubmit=yes&kw=toast
大家可以学习或娱乐下。其实也就装装逼无大用。

https://static.52pojie.cn/static/image/hrline/line6.png
后来,我发现了更加高明的玩法:https://www.52pojie.cn/thread-743758-1-1.html

.class public Lcom/hook/testsmali/InjectLog;
.super Ljava/lang/Object;
.source "InjectLog.java"


# direct methods
.method public constructor <init>()V
    .locals 0

    .prologue
    .line 3
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static PrintFunc()V
    .locals 6

    .prologue
    .line 7
    invoke-static {}, Ljava/lang/Thread;->currentThread()Ljava/lang/Thread;

    move-result-object v0

    .line 8
    .local v0, "cur_thread":Ljava/lang/Thread;
    invoke-virtual {v0}, Ljava/lang/Thread;->getStackTrace()[Ljava/lang/StackTraceElement;

    move-result-object v1

    .line 9
    .local v1, "stack":[Ljava/lang/StackTraceElement;
    const-string v2, "InjectLog"

    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const/4 v4, 0x3

    aget-object v4, v1, v4

    invoke-virtual {v4}, Ljava/lang/StackTraceElement;->toString()Ljava/lang/String;

    move-result-object v4

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    const-string v4, "["

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    invoke-virtual {v0}, Ljava/lang/Thread;->getId()J

    move-result-wide v4

    invoke-virtual {v3, v4, v5}, Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder;

    move-result-object v3

    const-string v4, "]"

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 10
    return-void
.end method


下面是调用的代码:
invoke-static {},Lcom/hook/testsmali/InjectLog;->PrintFunc()V

https://static.52pojie.cn/static/image/hrline/line7.png
这样ddms中,我们就能看日志了


https://static.52pojie.cn/static/image/hrline/3.gif
使用过一段时间后,我发现以上的代码也有缺陷,你输出的日志中,满眼都是 InjectLog青一色啊
于是又在一个好友Smile1110大佐的指引下认识了论坛大神 连晋
我的要求是 InjectLog+序号 修改下程序源代码,结果大神就编了个Java,然后编译生成了以下apk,提取到下面的代码;这是发生在前几年的故事。
时间过的好快,时间都到哪里去了?!


.class public Lcom/hook/testsmali/InjectLog;
.super Ljava/lang/Object;
.source "InjectLog.java"


# static fields
.field public static count:Ljava/lang/Integer;


# direct methods
.method static constructor <clinit>()V
    .registers 1

    .line 6
    const/4 v0, 0x0

    invoke-static {v0}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

    move-result-object v0

    sput-object v0, Lcom/hook/testsmali/InjectLog;->count:Ljava/lang/Integer;

    return-void
.end method

.method public constructor <init>()V
    .registers 1

    .line 5
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static PrintFunc()V
    .registers 6

    .line 9
    sget-object v0, Lcom/hook/testsmali/InjectLog;->count:Ljava/lang/Integer;

    sget-object v0, Lcom/hook/testsmali/InjectLog;->count:Ljava/lang/Integer;

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I

    move-result v0

    add-int/lit8 v0, v0, 0x1

    invoke-static {v0}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

    move-result-object v0

    sput-object v0, Lcom/hook/testsmali/InjectLog;->count:Ljava/lang/Integer;

    .line 10
    invoke-static {}, Ljava/lang/Thread;->currentThread()Ljava/lang/Thread;

    move-result-object v0

    .line 11
    .local v0, "localThread":Ljava/lang/Thread;
    invoke-virtual {v0}, Ljava/lang/Thread;->getStackTrace()[Ljava/lang/StackTraceElement;

    move-result-object v1

    .line 12
    .local v1, "arrayOfStackTraceElement":[Ljava/lang/StackTraceElement;
    new-instance v2, Ljava/lang/StringBuilder;

    invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V

    const-string v3, "InjectLog"

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    sget-object v3, Lcom/hook/testsmali/InjectLog;->count:Ljava/lang/Integer;

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;

    invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v2

    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const/4 v4, 0x3

    aget-object v4, v1, v4

    invoke-virtual {v4}, Ljava/lang/StackTraceElement;->toString()Ljava/lang/String;

    move-result-object v4

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    const-string v4, "["

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    invoke-virtual {v0}, Ljava/lang/Thread;->getId()J

    move-result-wide v4

    invoke-virtual {v3, v4, v5}, Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder;

    const-string v4, "]"

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 13
    return-void
.end method

我们可以看到ddms中 按序号输出了调用信息和一定的顺序。不过两种也有不足,比如这是给LogCat看的;要么你手机连上电脑用ddms调试;要么到vmos里用开发助手的类似ddms的调试功能;或者手机在root的情况下直接使用ddms。而没有死的日志文件的输出。所以。。。

https://static.52pojie.cn/static/image/hrline/3.gif
最近在学习过程中,我发现了在安卓手机上有个叫NP管理器的,它有一个一键注入代码 并生成log 写到sdcard的功能
代码如下:
.class public Lnp/NPInjectLog;
.super Ljava/lang/Object;
.source "NPInjectLog.java"

# direct methods
.method public constructor <init>()V
    .registers 1

    .line 9
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static NPPrintFunc()V
    .registers 9

    .line 12
    invoke-static {}, Ljava/lang/Thread;->currentThread()Ljava/lang/Thread;

    move-result-object v0

    .line 13
    .local v0, "cur_thread":Ljava/lang/Thread;
    invoke-virtual {v0}, Ljava/lang/Thread;->getStackTrace()[Ljava/lang/StackTraceElement;

    move-result-object v1

    .line 14
    .local v1, "stack":[Ljava/lang/StackTraceElement;
    new-instance v2, Ljava/lang/StringBuilder;

    invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V

    const/4 v3, 0x3

    aget-object v3, v1, v3

    invoke-virtual {v3}, Ljava/lang/StackTraceElement;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    const-string v3, "["

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    invoke-virtual {v0}, Ljava/lang/Thread;->getId()J

    move-result-wide v3

    invoke-virtual {v2, v3, v4}, Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder;

    const-string v3, "]"

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v2

    .line 15
    .local v2, "log":Ljava/lang/String;
    const-string v3, "NPInjectLog"

    invoke-static {v3, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 16
    const-string v3, "true"

    .line 17
    .local v3, "isNeedWrite":Ljava/lang/String;
    const-string v4, "true"

    invoke-virtual {v3, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v4

    if-eqz v4, :cond_69

    .line 18
    const-string v4, "/storage/emulated/0/log.txt"

    .line 19
    .local v4, "logPath":Ljava/lang/String;
    new-instance v5, Ljava/text/SimpleDateFormat;

    const-string v6, "yyyy-MM-ddHH:mm:ss.SSS"

    invoke-direct {v5, v6}, Ljava/text/SimpleDateFormat;-><init>(Ljava/lang/String;)V

    .line 20
    .local v5, "aDate":Ljava/text/SimpleDateFormat;
    new-instance v6, Ljava/util/Date;

    invoke-direct {v6}, Ljava/util/Date;-><init>()V

    invoke-virtual {v5, v6}, Ljava/text/SimpleDateFormat;->format(Ljava/util/Date;)Ljava/lang/String;

    move-result-object v6

    .line 21
    .local v6, "time":Ljava/lang/String;
    new-instance v7, Ljava/lang/StringBuilder;

    invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V

    invoke-virtual {v7, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    const-string v8, "\t"

    invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    invoke-virtual {v7, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    const-string v8, "\n"

    invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v7

    invoke-static {v4, v7}, Lnp/NPInjectLog;->logOnSdcard(Ljava/lang/String;Ljava/lang/String;)V

    .line 23
    .end local v4# "logPath":Ljava/lang/String;
    .end local v5# "aDate":Ljava/text/SimpleDateFormat;
    .end local v6# "time":Ljava/lang/String;
    :cond_69
    return-void
.end method

.method private static logOnSdcard(Ljava/lang/String;Ljava/lang/String;)V
    .registers 6
    .param p0, "fileName"# Ljava/lang/String;
    .param p1, "content"# Ljava/lang/String;

    .line 32
    const/4 v0, 0x0

    .line 34
    .local v0, "writer":Ljava/io/FileWriter;
    :try_start_1
    new-instance v1, Ljava/io/File;

    invoke-direct {v1, p0}, Ljava/io/File;-><init>(Ljava/lang/String;)V

    .line 35
    .local v1, "file":Ljava/io/File;
    invoke-virtual {v1}, Ljava/io/File;->getParentFile()Ljava/io/File;

    move-result-object v2

    invoke-virtual {v2}, Ljava/io/File;->exists()Z

    move-result v2

    if-nez v2, :cond_17

    .line 36
    invoke-virtual {v1}, Ljava/io/File;->getParentFile()Ljava/io/File;

    move-result-object v2
调用的代码:
    invoke-static {}, Lnp/NPInjectLog;->NPPrintFunc()V

然后在sdcard卡上就会生成新的.log文件,里边就是这个安卓程序,前后调用的顺序;比如你故意触发一个付费请求,那。。。

https://static.52pojie.cn/static/image/hrline/2.gif
最近我就在想,为啥我不搞个程序,弥补mt管理器没有一键注入代码的烦恼呢? 那个np管理器真的好卡顿啊。

未完,待续~~





冥界3大法王 发表于 2020-9-6 12:45

417788939 发表于 2020-9-6 10:07
np管理器一键注入log好像用不了,崩溃的时候都写不出日志。

@417788939
若手机安装virtual xpoosed 就能免root环境里 在 xpoosed 插件了
有 崩溃的插件,可以直接弹报错的 类名

若想方便,就在vmos里折腾上面。。。

反正Np,真是卡顿,bug多,还闪,还有不兼容问题。

冥界3大法王 发表于 2020-9-7 08:25

417788939 发表于 2020-9-6 18:37
np我用2部手机测试,骁龙cpu855不卡,猎户座8895主要卡在启动上,经常黑屏。

功能虽多,但不怎么好使 ...

@417788939
我打入他们qq群,竟是说有卡顿和反应问题的
有个好友跟群主关系 不错,据说 就是业余玩玩 大杂烩

我是阿乐 发表于 2020-9-6 09:23

我来学习下

Whitte 发表于 2020-9-6 09:28

学习了学习了,一步步整合+演进,闲下来了,自己也试试

QingYi. 发表于 2020-9-6 09:32

还是没看懂

冥界3大法王 发表于 2020-9-6 09:36

QingYi. 发表于 2020-9-6 09:32
还是没看懂

代码是搞在程序内部的,不是用眼看的,所以没法懂。

yeahn 发表于 2020-9-6 09:48

膜拜大佬{:1_927:}

yeahn 发表于 2020-9-6 09:50

把代码写在so再调用就恶心了{:1_918:}{:1_918:}

芽衣 发表于 2020-9-6 10:07

本帖最后由 417788939 于 2020-9-6 10:09 编辑

np管理器一键注入log好像用不了,崩溃的时候都写不出日志。


{:301_999:}

yc0205 发表于 2020-9-6 12:12

学习了自己也试试

正己 发表于 2020-9-6 12:20

417788939 发表于 2020-9-6 10:07
np管理器一键注入log好像用不了,崩溃的时候都写不出日志。

八说了,我手机连np都打不开{:17_1072:}
页: [1] 2 3 4
查看完整版本: 吸星大法抽取代码+安卓编程实现解决MT管理器没有一键注入代码的缺陷