So Tired !_! 逆水行舟, 不进则退!

22May/15

Openssl移植到Android

Posted by Nick Xu

Openssl移植到Android都是使用别人提好(从Android源码)的Openssl代码,方法简单但过程不那么顺利,因为Openssl版本变动太频繁了,再加上NDK一堆BUG,极不愿意去调试原始配置,单单Openssl的模块编译前后就等了两个月直到Google推出NDK新版本R8C才编译通过。因为原生程序应用到很多Openssl签名、验证算法函数,就连Openssl的版本升级一下往往都要修改一些代码才能通过。

一、下载Openssl最新版本

可选的Openssl Android版本下载地址:

Openssl 1.0.0a:

https://github.com/guardianproject/openssl-android

Openssl 1.0.1c:

https://github.com/aluvalasuman/OpenSSL1.0.1cForAndroid

本文将要使用的Openssl版本为1.0.1c,前一1.0.0a版本未验证通过(NDKr8b),编译时会出现下文的编译错误。所以改用较新版本,目前已知1.0.1c在NDK r8b上编译会有很多问题,不是Openssl工程有兼容BUG就是NDK版本有BUG,反正不是那么容易调试通过。

二、编译过程

本文编译使用最新的NDK r8c(Ubuntu 12.04),下载Openssl android工程后解压,可以看到完整的NDK工程,简单的编译过程如下:

  1. 进入解压目录,执行:
  2. $NDK_HOME/ndk-build clean
  3. $NDK_HOME/ndk-build
  4. 编译结果在obj目录下(libcrypto-static.a和libssl-static.a或是libcrypto.so和libssl.so)
  5. 把结果拷贝出来放到自己的Android工程Helloworld对应目录下进行调用即可。

上述步骤4编译出Openssl的链接库,一般拷贝到ndk_r8c\platforms\android-10\arch-arm\usr\lib目录下(仅为示例),然后把openssl根下的include目录都拷贝出去就是编译头文件,这样就可以构建自己的helloworld工程了,在helloworld的Android.mk中增加类似如下调用:

LOCAL_LDLIBS := -L$(SYSROOT)/lib/ -llog -lcrypto -lssl

三、常见错误

以下编译错误,有的在1.0.0a版本中遇到,有的是在NDK r8b环境下遇到,此间涉及到OpenSSL版本问题、GCC版本问题、NDK版本BUG问题,等等都混到一起总结方便对应处理。

1、undefined reference to `zError'

openssl 库时错误如下:

SharedLibrary  : libssl.so
Executable     : openssl
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld: warning: libz.so, needed by ./obj/local/armeabi/libcrypto.so, not found (try using -rpath or -rpath-link)

./obj/local/armeabi/libcrypto.so: undefined reference to `zError'
./obj/local/armeabi/libcrypto.so: undefined reference to `inflateEnd'
./obj/local/armeabi/libcrypto.so: undefined reference to `deflate'
./obj/local/armeabi/libcrypto.so: undefined reference to `deflateInit_'
./obj/local/armeabi/libcrypto.so: undefined reference to `inflate'
./obj/local/armeabi/libcrypto.so: undefined reference to `deflateEnd'
./obj/local/armeabi/libcrypto.so: undefined reference to `inflateInit_'
collect2: ld returned 1 exit status

解决办法:

1、$NDK_HOME/ndk-build NDK_TOOLCHAIN_VERSION=4.4.3

$NDK_HOME/ndk-build NDK_TOOLCHAIN=arm-linux-androideabi-4.4.3

该方法参考来自:android-ndk-r8b/doc/NDK-BUILD.html 说明,ndk-build可以携带 NDK_XXX这样的参数,来指定编译环境版本信息。具体参数有哪些?目前可以通过android-ndk-r8b/build/core/init.mk里查询到一些NDK_开头的参数。

2、在openssl的jni目录下的Application.mk中增加:

APP_PLATFORM := android-8

3、在openssl根下的android-config.mk中增加:

APP_ABI := armeabi armeabi-v7a

该参考来源android-ndk-r8b/docs/APPLICATION-MK.html

2、Unknown EABI object attribute 44

SharedLibrary  : libssl.so
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: Warning: /root/android-ndk-r8b/platforms/android-8/arch-arm/usr/lib/crtend_so.o: Unknown EABI object attribute 44
Executable     : openssl
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: Warning: /root/android-ndk-r8b/platforms/android-8/arch-arm/usr/lib/crtend_android.o: Unknown EABI object attribute 44
Install        : openssl => /root/aluvalassuman/libs/armeabi/openssl
Install        : libssl.so => /root/aluvalassuman/libs/armeabi/libssl.so
Compile thumb  : ssltest <= ssltest.c
Executable     : ssltest
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: Warning: /root/android-ndk-r8b/platforms/android-8/arch-arm/usr/lib/crtend_android.o: Unknown EABI object attribute 44
Install        : ssltest => /root/aluvalassuman/libs/armeabi/ssltest

解决办法:

4.4.3似乎跟链接库的编译环境可能对不上(44冲突),网上有说改成4.6就没问题了,不会出现该提示,但是4.6支持STL有BUG啊?

crypto/Android.mk 大约535行,添加:

LOCAL_EXPORT_LDLIBS := -lz

注意有没添加以下两个静态库,大约576行,添加(暂时不用):

LOCAL_LDLIBS := -lz –ldl

3、build/gmsl/__gmsl:512: *** non-numeric second

Complile Openssl:

Error:
build/gmsl/__gmsl:512: *** non-numeric second
Changes:

I changed the file  __gmsl, the second wordlist argument(line 512),
and it's running my jni example without errors:

int_encode = $(__gmsl_tr1)$(wordlist 1, $1,$(__gmsl_input_int))

to:

int_encode = $(__gmsl_tr1)$(wordlist 1,$(words $1),$
(__gmsl_input_int))

参考资料(下述可能有地址被墙了):

http://www.uml.org.cn/mobiledev/201108101.asp

http://blog.csdn.net/someonea/article/details/6312213

http://ssuman185.blogspot.sg/p/steps-for-porting-openssl-for-android.html

http://stackoverflow.com/questions/11856688/openssl-build-issue-with-android-ndk-r8

http://stackoverflow.com/questions/11929773/compiling-the-latest-openssl-for-android

https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/b4DSxE1NAS0

10Jul/14

Smali注入之打造属于自己的安卓crack利器

Posted by Nick Xu

关于Smali注入大家应该了解过,网上有不少教程。那些注入代码看上去简单,实际用起来得花不少功夫。

普通的注入就是在软件源代码中添加几行代码,用于改变软件的功能,或查看某个寄存器在运行中具体的值。

需要注意的地方是:添加的注入代码所使用的寄存器不影响其他代码的执行。当注入代码较多时,这个要求就变得很困难了。

在这里我的解决办法是:把注入代码写进自己专属的crack.smali,然后在要注入的地方调用crack.smali里的注入方法即可,只用一行注入代码,而且不影响其他寄存器。

举个例子说明下两种方法的区别,假设原软件中有以下代码:

.method public methodName()Ljava/lang/String;
.locals 4
.prologue
const-string v0, "test1"

const-string v3, "test2"

invoke-static {v0}, Lpackage/name/ObjectName;——>methodName1(Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

invoke-static {v1}, Lpackage/name/ObjectName;——>methodName2(Ljava/lang/String;)Ljava/lang/String;

move-result-object v2

invoke-static {v3}, Lpackage/name/ObjectName;——>methodName3(Ljava/lang/String;)V

new-instance v3, Ljava/lang/StringBuilder;

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

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

move-result-object v0

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

move-result-object v0

return-object v0
.end method

假如我要查看move-result-object v1和move-result-object v2,两处中v1、v2的值该如何注入?

普通的log.d注入方法如下(可以用Logcat查看日志):

.method public methodName()Ljava/lang/String;
.locals 5
.prologue
const-string v0, "test1"

const-string v3, "test2"

invoke-static {v0}, Lpackage/name/ObjectName;——>methodName1(Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

const-string v4, "info"

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

invoke-static {v1}, Lpackage/name/ObjectName;——>methodName2(Ljava/lang/String;)Ljava/lang/String;

move-result-object v2

const-string v4, "info"

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

invoke-static {v3}, Lpackage/name/ObjectName;——>methodName3(Ljava/lang/String;)V

new-instance v3, Ljava/lang/StringBuilder;

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

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

move-result-object v0

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

move-result-object v0

return-object v0
.end method

在上面的代码中,我先是修改了开头的“.locals 5”,表示使用的寄存器为v0-v4。然后我用v4作为log.d的第一个参数,寄存器v1、v2为第二个参数。

由于原代码中,v0、v1、v2、v3从头到尾都有使用,所以注入时使用这几个寄存器会影响软件的正常执行,所以我才修改“.locals”开辟新的寄存器v4。

明显这样注入很麻烦。而且刚好v1、v2都是字符串,符合log.d的要求。如果v1、v2为整数值,注入就更加复杂了。

下面看看创建了crack.smali的注入会如何。

假设我已经有了个crack.smali,代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
.class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
.method public static log(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

把crack.smali放到反编译后的smali根目录,在源代码中注入:

.method public methodName()Ljava/lang/String;
.locals 4
.prologue
const-string v0, "test1"

const-string v3, "test2"

invoke-static {v0}, Lpackage/name/ObjectName;——>methodName1(Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

invoke-static {v1}, Lcrack;->log(Ljava/lang/String;)V

invoke-static {v1}, Lpackage/name/ObjectName;——>methodName2(Ljava/lang/String;)Ljava/lang/String;

move-result-object v2

invoke-static {v2}, Lcrack;->log(Ljava/lang/String;)V

invoke-static {v3}, Lpackage/name/ObjectName;——>methodName3(Ljava/lang/String;)V

new-instance v3, Ljava/lang/StringBuilder;

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

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

move-result-object v0

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

move-result-object v0

return-object v0
.end method

明显比前面的注入方式简单多了。crack.smali的方法可以不断丰富,需要用时信手拈来。

既然如此,就让我们打造属于自己的安卓crack利器吧!

最基本的crack.smali推荐加入log日志输出,代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
.class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
.method public static log(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

把crack.smali放进smali目录,在要查看的,保存了字符串的寄存器vx的下面,添加代码:

[Java] 纯文本查看 复制代码
1
invoke-static {vx}, Lcrack;->log(Ljava/lang/String;)V

保存并重新编译,在手机或模拟器上安装软件,连上电脑,打开cmd命令行:

<ignore_js_op>

cd到桌面,然后输入命令adb logcat>test.txt,然后在手机上运行软件,当软件执行了注入的代码(自行判断),按ctrl+c结束,然后回到桌面。

如无法识别adb命令,请先添加adb.exe所在位置的环境变量,如我安装了靠谱助手,我找到了它提供的adb.exe所在的路径,然后我照下面图设置:

<ignore_js_op>

打开test.txt,查找d/info,在找到的那一行的右边就是要查看的寄存器的值。

<ignore_js_op>

“info”是由“ const-string v0, "info" ”给出。可以自行修改。

上面的说的命令还可以添加过滤代码,有经验的人自行修改,使得test.txt的内容更简洁。

从上面test.txt的结果可以看出,如果需要注入的位置有多处,那么就很难分辨具体哪个结果对应哪个了。

解决办法是,给crack.smali的log方法加序号,并复制多份log方法,参照下面修改方式,如:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
.class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
.method public static log1(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info1"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method
.method public static log2(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info2"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

第一处注入调用log1,第二处注入调用log2,依次类推,然后根据序号对应结果。

上面说的注入,前提都是vx是String,如果vx是int型怎么办?

可以给crack.smali添加下面方法:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
.method public static I(I)V
    .locals 2
    .prologue
    const-string v0, "info_int"
    invoke-static {p0}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
    move-result-object v1
    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

上面方法调用代码为:

[Java] 纯文本查看 复制代码
1
invoke-static {vx}, Lcrack;->I(I)V

vx为要查看的寄存器。

当vx保存的是long型的话,就比较麻烦了,稍微用错就会导致程序停止运行,所以尽量避免查看long型vx。

给crack.smali添加以下代码:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
.method public static J(J)V
.locals 2
.prologue
const-string v0, "info_long"
invoke-static {p0, p1}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;
move-result-object v1
invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
return-void
.end method

上面方法调用代码为:

[Java] 纯文本查看 复制代码
1
invoke-static {vx, vx+1}, Lcrack;->J(J)V

vx为要查看的寄存器,同时确保vx+1在上面的代码中没有被使用过,且在.locals声明的可使用的寄存器范围内。

至于[C、[B、[Ljava/lang/String的查看,有机会再补上。

软件大部分时间都在跟字符串、数据打交道。很多时候就因为某个寄存器的值不知,导致软件代码很难分析下去。

因此在没有调试器的前提下,通过注入查看寄存器的值就变得非常重要了。

总是通过logcat查看寄存器值,多少有点不方便,所以下面讲下如何将字符串输出到文本。

直接用smali写有点麻烦,所以先用java写,编译后再反编译为smali,参考java代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.io.*;
import android.util.Log;
public class crack
{
/*将字符串s输出到/sdcard/debug.txt*/
public static void puts(String s)
{
  try
  {
          String path= "/sdcard/debug.txt";
           
                  FileOutputStream outStream = new FileOutputStream(path,false);
                  OutputStreamWriter writer = new OutputStreamWriter(outStream,"gb2312");
                  writer.write(s);
                  writer.flush();
                  writer.close();
                  outStream.close();
  }
                  catch (Exception e)
                  {
                          Log.e("debug", "file write error");
                  }
}
}

反编译后smali代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
.method public static puts(Ljava/lang/String;)V
    .locals 7
    .prologue
    :try_start_0
    const-string v3, "/sdcard/debug.txt"
    new-instance v2, Ljava/io/FileOutputStream;
    const/4 v5, 0x0
    invoke-direct {v2, v3, v5}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;Z)V
    .line 19
    new-instance v4, Ljava/io/OutputStreamWriter;
    const-string v5, "gb2312"
    invoke-direct {v4, v2, v5}, Ljava/io/OutputStreamWriter;-><init>(Ljava/io/OutputStream;Ljava/lang/String;)V
    .line 21
    invoke-virtual {v4, p0}, Ljava/io/OutputStreamWriter;->write(Ljava/lang/String;)V
    .line 23
    invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->flush()V
    .line 25
    invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->close()V
    .line 27
    invoke-virtual {v2}, Ljava/io/FileOutputStream;->close()V
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
    .line 37
    :cond_0
    :goto_0
    return-void
    .line 30
    :catch_0
    move-exception v0
    .line 34
    const-string v5, "debug"
    const-string v6, "file write error"
    invoke-static {v5, v6}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
    goto :goto_0
.end method

使用方法为,在要查看的寄存器vx的下方换行添加代码:

[Java] 纯文本查看 复制代码
1
invoke-static {vx}, Lcrack;->puts(Ljava/lang/String;)V

至于输出整型变量到文本,请参考之前的例子,先将整型变量转为字符串,再输出,具体代码这里略过。。。

下面介绍通过注入,改变软件获得的imei号,让软件改为读取保存在 “/sdcard/deviceid/imei.txt” 里的串号。

参考java代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.io.*;
public class crack {
        public static String getDeviceId()
        {
        String path = "/sdcard/deviceid/imei.txt";
        String str = null;
        File f = new File(path);
        if (f != null && f.exists()) 
        {
            FileInputStream fis = null;
            try {
                    fis = new FileInputStream(f);
            } catch (FileNotFoundException e1) {
            e1.printStackTrace(); 
        }
            InputStreamReader inputStreamReader = null;
            try {
                    inputStreamReader = new InputStreamReader(fis, "utf-8");
                    try {
                            BufferedReader reader = new BufferedReader(inputStreamReader);
                            StringBuffer sb = new StringBuffer("");
                            String line;
                            line = reader.readLine();
                            sb.append(line);
                            reader.close();       
                            fis.close();
                            str = sb.toString();
                    catch (IOException e) {  
                e.printStackTrace();  
            }
            } catch (UnsupportedEncodingException e) { 
                     e.printStackTrace();          
                 }  
        }
              return str;
        }
}

反编译后得到的smali代码如下:

[Java] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
.method public static getDeviceId()Ljava/lang/String;
    .locals 13
    .prologue
    const-string v8, "/sdcard/deviceid/imei.txt"
    const/4 v11, 0x0
    new-instance v2, Ljava/io/File;
    invoke-direct {v2, v8}, Ljava/io/File;-><init>(Ljava/lang/String;)V
    if-eqz v2, :cond_0
    invoke-virtual {v2}, Ljava/io/File;->exists()Z
    move-result v12
    if-eqz v12, :cond_0
    const/4 v3, 0x0
    :try_start_0
    new-instance v4, Ljava/io/FileInputStream;
    invoke-direct {v4, v2}, Ljava/io/FileInputStream;-><init>(Ljava/io/File;)V
    :try_end_0
    .catch Ljava/io/FileNotFoundException; {:try_start_0 .. :try_end_0} :catch_0
    move-object v3, v4
    :goto_0
    const/4 v5, 0x0
    :try_start_1
    new-instance v6, Ljava/io/InputStreamReader;
    const-string v12, "utf-8"
    invoke-direct {v6, v3, v12}, Ljava/io/InputStreamReader;-><init>(Ljava/io/InputStream;Ljava/lang/String;)V
    :try_end_1
    .catch Ljava/io/UnsupportedEncodingException; {:try_start_1 .. :try_end_1} :catch_3
    :try_start_2
    new-instance v9, Ljava/io/BufferedReader;
    invoke-direct {v9, v6}, Ljava/io/BufferedReader;-><init>(Ljava/io/Reader;)V
    new-instance v10, Ljava/lang/StringBuffer;
    const-string v12, ""
    invoke-direct {v10, v12}, Ljava/lang/StringBuffer;-><init>(Ljava/lang/String;)V
    invoke-virtual {v9}, Ljava/io/BufferedReader;->readLine()Ljava/lang/String;
    move-result-object v7
    invoke-virtual {v10, v7}, Ljava/lang/StringBuffer;->append(Ljava/lang/String;)Ljava/lang/StringBuffer;
    invoke-virtual {v9}, Ljava/io/BufferedReader;->close()V
    invoke-virtual {v3}, Ljava/io/FileInputStream;->close()V
    invoke-virtual {v10}, Ljava/lang/StringBuffer;->toString()Ljava/lang/String;
    :try_end_2
    .catch Ljava/io/IOException; {:try_start_2 .. :try_end_2} :catch_1
    .catch Ljava/io/UnsupportedEncodingException; {:try_start_2 .. :try_end_2} :catch_2
    move-result-object v11
    :cond_0
    :goto_1
    return-object v11
    :catch_0
    move-exception v1
    invoke-virtual {v1}, Ljava/io/FileNotFoundException;->printStackTrace()V
    goto :goto_0
    :catch_1
    move-exception v0
    :try_start_3
    invoke-virtual {v0}, Ljava/io/IOException;->printStackTrace()V
    :try_end_3
    .catch Ljava/io/UnsupportedEncodingException; {:try_start_3 .. :try_end_3} :catch_2
    goto :goto_1
    :catch_2
    move-exception v0
    move-object v5, v6
    :goto_2
    invoke-virtual {v0}, Ljava/io/UnsupportedEncodingException;->printStackTrace()V
    goto :goto_1
    :catch_3
    move-exception v0
    goto :goto_2
.end method

使用方法为:

查找

[Java] 纯文本查看 复制代码
1
Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;

在下面换行添加

[Java] 纯文本查看 复制代码
1
invoke-static {}, Lcrack;->getDeviceId()Ljava/lang/String;

 

   
site
site