好友
阅读权限40
听众
最后登录1970-1-1
|
本帖最后由 冥界3大法王 于 2020-9-6 09:34 编辑
从实战的角度说吧,我们经常在破解安卓程序的时候;您是否遇到了以下困扰?
- 当前分析的.smali文件 或当前的的activity (其实白话就是类似于Windows上看到的当前窗口名) 是否被执行过? 能否执行到?
- 何时被上一级调用的,又是哪个类调来的? 类名是?
- 函数返回值是多少?
这些问题呢,其实对于懂安卓开发的来说根本不是个事,注入代码就能解决。
以下是本人从菜鸟的角度思考问题,并实战中发现新问题的解决途径和历程:
我们在论坛上搜索【Toast】,会找到以下几个:我们找经典的几个来说事:
普通的在OnCreate调用的代码如下:
[Asm] 纯文本查看 复制代码
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 日志猫使用。
学安卓初期,我错误的看上了这种;认为是不是在随便的代码里都能添加上,完全不是这么一回事啊。
下面的这种是论坛割绳子贴里同学stars-one大神搞的代码
[Asm] 纯文本查看 复制代码 .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
[Asm] 纯文本查看 复制代码
在onCreate方法里调用的代码
invoke-static {p0}, Lcrack;->toast(Landroid/content/Context;)V
以上这种方法,在MT管理器中,可以在dex编辑++模式下,找到文件夹,长按
方法名:你的程序包名(即在MT管理器点apk时看到的第一行)
类名: Crack
优点:如我要调用多次呢,可以复用。
然后我们说,这是”吐丝特“ (Toast)并不是注入的代码啊。
论坛上还有一些高级版的https://www.52pojie.cn/search.php?mod=forum&searchid=1684&orderby=lastpost&ascdesc=desc&searchsubmit=yes&kw=toast
大家可以学习或娱乐下。其实也就装装逼无大用。
后来,我发现了更加高明的玩法:https://www.52pojie.cn/thread-743758-1-1.html
[Asm] 纯文本查看 复制代码
.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
下面是调用的代码:
[Asm] 纯文本查看 复制代码 invoke-static {},Lcom/hook/testsmali/InjectLog;->PrintFunc()V
这样ddms中,我们就能看日志了
使用过一段时间后,我发现以上的代码也有缺陷,你输出的日志中,满眼都是 InjectLog青一色啊
于是又在一个好友Smile1110大佐的指引下认识了论坛大神 连晋
我的要求是 InjectLog+序号 修改下程序源代码,结果大神就编了个Java,然后编译生成了以下apk,提取到下面的代码;这是发生在前几年的故事。
时间过的好快,时间都到哪里去了?!
[Asm] 纯文本查看 复制代码
.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。而没有死的日志文件的输出。所以。。。
最近在学习过程中,我发现了在安卓手机上有个叫NP管理器的,它有一个一键注入代码 并生成log 写到sdcard的功能
代码如下:
[Asm] 纯文本查看 复制代码 .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-dd HH: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
调用的代码:
[Asm] 纯文本查看 复制代码 invoke-static {}, Lnp/NPInjectLog;->NPPrintFunc()V
然后在sdcard卡上就会生成新的 .log文件,里边就是这个安卓程序,前后调用的顺序;比如你故意触发一个付费请求,那。。。
最近我就在想,为啥我不搞个程序,弥补mt管理器没有一键注入代码的烦恼呢? 那个np管理器真的好卡顿啊。
未完,待续~~
|
免费评分
-
查看全部评分
|