当前位置:首页 > 从零开始 > 正文

re从零开始的反编译教程

2023-02-16 21:35:32  来源:网络   热度:

写在开头,引用很喜欢的一句话: 要么学!要么不学!学和不学之间没有中间值 不学就放弃,学就要去认真的学! --致选择

为了回溯编译过程(或对程序进行逆向工程),我们使用各种工具来撤销汇编和编译过程,这些工具就叫反汇编器和反编译器。反汇编器撤销汇编过程,因此我们可以得到汇编语言形式的输出结果。反编译器则以汇编语言甚至是机器语言为输入,其输出结果为高级语言。

数组的表示方式是:在基本类型前加上前中括号“[”,例如int数组和float数组分别表示为:[I、[F;对象的表示则以L作为开头,格式是 LpackageName/objectName;

(注意必须有个分号跟在最后),例如String对象在smali中为: Ljava/lang/String; ,其中 java/lang 对应 java.lang 包,String就是定义在该包中的一个对象。或许有人问,既然类是用 LpackageName/objectName; 来表示,那类里面的内部类又如何在smali中引用呢?

答案是:在 LpackageName/objectName/subObjectName 的 subObjectName 前加 $ 符号。

方法的定义一般为: Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type

注意参数与参数之间没有任何分隔符,同样举几个例子就容易明白

无序列表的使用,在符号-后加空格使用。如下:

解决:点击进去jd-gui,删除试一试。再不行换最新版本

解析结束后进行编译报错

解决方法:

Failed parse during installPackageLI: Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompress

解决方法:

降低gradle里版本,若出现

signatures do not match the previously installed version; ,

使用adb install命令在手机上安装app时,遇到这个报错。原因是新装的app和手机上现有的旧版app冲突了。

解决方法:删除手机上原来的app,再重新安装即可。

可是转念一想如果反编译的apk都是Version 30 R+以上,难道我解压后挨个改一遍gradle?太彻淡了,一定有解决方法,所以有了下面探究出现这个问题的解决方法:既然报错是资源文件高版本不支持,而且没有4位对齐,那么不编译资源文件就好了

APK签名工具之jarsigner和apksigner:

利用apktool反编译apk,并且重新签名打包:

验证apktool能否使用

apktool -r d apk名字.apk,不反编译资源文件,为什么这么做,先挖个坑

错误提示没有4位对齐和不支持30版本以上的资源文件。所有尝试不编译资源文件

解决4位对齐的方法:

查看当前目录,生成了新文件:abc.keystor

使用JarSigner对apk进行签名,命令如下

jarsigner -verbose -keystore abc.keystore -signedjar testx.apk src.apk abc.keystore

直接反编译的apk产生上述错误

但是只编译资源文件的apk安装时

发现没有使用V2进行签名,这时候进行V2签名, (apksigner,默认同时使用V1和V2签名 )

所以先对只编译资源文件的apk进行V2尝试看能否成功

重复1(进行apktool -r d apk名字.apk)-->2 -->3 -->4( 不使用jarsigner而使用apksigner )

将生成的abc.keystore和打包回的apk( apktool\app-debug\dist 里的app-debug.apk)放入 C:\Users\taowei.lian\AppData\Local\Android\Sdk\build-tools\30.0.3 下,因为Android studio的SDK下有apksigner.bat.

对jarsigner只是apk进行了V1签名;在Android7.0引入了V2签名,因此,当进入sdk\25.0.0及后续版本,会发现一个apksigner.bat执行脚本。

我们可以通过apksigner进行V2签名,当然,apksigner默认是同时支持V1与V2的,于是:

学习了公钥和密钥的使用和区别,使用私钥的加密算法称为对称加密算法,这种算法实现是接收方和发送方公用一道密钥,优点是效率高,缺点是安全性差,如果被第三人得知密钥则信息泄露,由此衍生了公钥加密算法,也就是非对称加密算法,这个算法是接收方给发送方公钥,发送方用公钥加密后发给接收方,接受方再用私钥解密。这样即使所有人知道公钥也不会造成信息泄露。缺点是效率非常低。

此外了解了RSA签名的大致过程,发送方拥有公钥和私钥,对信息进行摘要然后把摘要通过密钥进行签名,然后把签名和信息一起发出去,那么如何验证该信息就是发送方发出的呢,这时候就使用到了公钥验证,通过公钥对信息进行解签,然后使用一样的摘要算法得到摘要,如果得到的摘要和解签后的内容一致则说明是发送方发出。

总结就是公钥加密,私钥解密。公钥验证,私钥签名

RSA 密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。由公钥加密的内容可以并且只能由私钥进行解密,而由私钥加密的内容可以并且只能由公钥进行解密。也就是说,RSA 的这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容可以由并且只能由对方进行解密。

因为公钥是公开的,任何公钥持有者都可以将想要发送给私钥持有者的信息进行加密后发送,而这个信息只有私钥持有者才能解密。

它和加密有什么区别呢?因为公钥是公开的,所以任何持有公钥的人都能解密私钥加密过的密文,所以这个过程并不能保证消息的安全性,但是它却能保证消息来源的准确性和不可否认性,也就是说,如果使用公钥能正常解密某一个密文,那么就能证明这段密文一定是由私钥持有者发布的,而不是其他第三方发布的,并且私钥持有者不能否认他曾经发布过该消息。故此将该过程称为「签名」。

Android 签名机制 v1、v2、v3

进入JDK/bin, 输入命令

参数:

进入Android SDK/build-tools/SDK版本, 输入命令

参数:

例如:

最后安装加 -t :

附上参考链接:

配置NDK的时候如果按钮是灰色的,手动配置

直接在javac后面指定编码是UTF-8就是了。

需要注意的是要加上* -classpath .其中classpath后面的一个黑点是不能省略的。

编译好后如何导入so库

成功运行后发现lib目录下已经apk编进去so了

本节所有到的工具和Demo

IDA

链接:

密码:ftie Demo

链接:

密码:u1an 找到so并打开它 因为我的机型是支持arm的所以我这里打开的是armeabi文件夹下的so 如果机型是x86模式的那么这里要打开x86模式下的libJniTest.so

编译过程:

按住键盘组合键 shift + f12 打开字符串窗口 这个窗口将会列举出so中所包含的所有字符串 因为上节课我们只编写了一个字符串 所以这里只有一个hello 52pojie! 如果打开的是x86的so这里还会有一些.so 但是字符串只有这一个

鼠标点在hello 52pojie!字符串上,打开 Hex dump窗口,修改hello 52pojie!对应内存地址的内容

关于字符对应的16进制可以在百度百科搜索ascii码表 找到字符所对应的16进制

因为我要把hello 52pojie!修改成hello world! 是不是只要找到每个字符所对应的hex修改就好了

这里我看到 hello 52pojie!对应的hex是:68 65 6C 6C 6F 20 35 32 70 6F 6A 69 65 21

我在ascii码表上找到world所对应的十六进制是:77 6F 72 6C 64

所以hello world! 对应的十六进制是:68 65 6C 6C 6F 20 77 6F 72 6C 64 21

注意编辑的时候光标暂停的位置只有先输入字母才能更改成功,修改好后 右键Apply changes应用

退出后保存

此时已经so修改完毕

大功告成,hello 52pojie! --> hello world!

一周热门