动态调试破解Ali_android_1程序[第三天/3h]
# 动态调试破解Ali_android_1程序[第三天/3h]## 静态调试
### 方法一【代码逻辑+图片隐写】
老方法反编译代码可以代码主要逻辑->用户输入的密码enPassword经过密码表table的转换同内置的密码pw进行比对
!(https://s2.loli.net/2024/07/03/h3JuRcOolTH76L9.png)
转换逻辑->用户输入密码enPassword经utf-8编码后取低八位,作为table的寻址下标,逐个转化。
也可以看到从图片中获取正确密码,密码表同理
!(https://s2.loli.net/2024/07/03/dYHmogWRGKkrvuw.png)
### 图片隐写
图片本身就是一定格式的二进制串,利用图片细微变化不易引起人眼察觉的特点隐藏信息
!(https://s2.loli.net/2024/07/03/48APVF6HhwIxfUp.png)
(https://blog.csdn.net/Hardworking666/article/details/120932217)
- **最低有效位隐写术**:就像在书页的最后一行添加小字注释,变化微小但可以嵌入信息。
- **频域隐写术**:就像在音乐的高频音中嵌入信息,整体听感不变但可以检测到细微变化。
- **调色板隐写术**:就像调整调色板中的颜色顺序,实际颜色不变但可以解码隐藏的信息。
这里可以利用反编译的代码逻辑获取密码表和内置密码
!(https://s2.loli.net/2024/07/10/JxPcjWMtKQrLe9S.png)
根据加密代码逻辑,写出解码代码,得到581026,即破解成功
!(https://s2.loli.net/2024/07/10/fCRIMPSBFpWtVaw.png)
------
## 动态调试
### 环境配置
(https://blog.csdn.net/kenbo_257/article/details/122726128)
(https://blog.csdn.net/qq_42177292/article/details/121261627)
### smali代码逻辑
```smali
.method public onClick(View)V
.registers 11
# 获取 MainActivity$1 类中的 val$edit 字段,这是一个 EditText 对象
iget-object v6, p0, MainActivity$1->val$edit:EditText
# 调用 EditText 的 getText 方法,返回 Editable 对象
invoke-virtual EditText->getText()Editable, v6
move-result-object v6
# 调用 Editable 的 toString 方法,将文本内容转换为 String 对象
invoke-interface Editable->toString()String, v6
move-result-object v3
# 获取 MainActivity$1 类中的 this$0 字段,这是 MainActivity 对象的引用
iget-object v6, p0, MainActivity$1->this$0:MainActivity
# 调用 MainActivity 的 getTableFromPic 方法,返回字符串 v5
invoke-virtual MainActivity->getTableFromPic()String, v6
move-result-object v5
# 获取 MainActivity$1 类中的 this$0 字段,这是 MainActivity 对象的引用
iget-object v6, p0, MainActivity$1->this$0:MainActivity
# 调用 MainActivity 的 getPwdFromPic 方法,返回字符串 v4
invoke-virtual MainActivity->getPwdFromPic()String, v6
move-result-object v4
# 打印日志,输出获取到的表格字符串 v5
const-string v6, "lil"
new-instance v7, StringBuilder
const-string v8, "table:"
invoke-direct StringBuilder-><init>(String)V, v7, v8
invoke-virtual StringBuilder->append(String)StringBuilder, v7, v5
move-result-object v7
invoke-virtual StringBuilder->toString()String, v7
move-result-object v7
invoke-static Log->i(String, String)I, v6, v7
# 打印日志,输出获取到的密码字符串 v4
const-string v6, "lil"
new-instance v7, StringBuilder
const-string v8, "pw:"
invoke-direct StringBuilder-><init>(String)V, v7, v8
invoke-virtual StringBuilder->append(String)StringBuilder, v7, v4
move-result-object v7
invoke-virtual StringBuilder->toString()String, v7
move-result-object v7
invoke-static Log->i(String, String)I, v6, v7
# 将字符串 v3 转换为 UTF-8 编码的字节数组,并存储到 v6 中
:try_80
const-string v6, "utf-8"
invoke-virtual String->getBytes(String)[B, v3, v6
move-result-object v6
# 调用 MainActivity 中的 access$0 方法,传递参数 v5 和 v6,并将返回值存储到 v2 中
invoke-static MainActivity->access$0(String, [B)String, v5, v6
move-result-object v2
# 打印日志,输出加密后的密码字符串 v2
const-string v6, "lil"
new-instance v7, StringBuilder
const-string v8, "enPassword:"
invoke-direct StringBuilder-><init>(String)V, v7, v8
invoke-virtual StringBuilder->append(String)StringBuilder, v7, v2
move-result-object v7
invoke-virtual StringBuilder->toString()String, v7
move-result-object v7
invoke-static Log->i(String, String)I, v6, v7
:tryend_BC
# 捕获 UnsupportedEncodingException 异常,打印异常堆栈信息
.catch UnsupportedEncodingException {:try_80 .. :tryend_BC} :catch_E8
:tryend_BC
# 如果 v4 不为空且不等于空字符串,则执行下面的代码块
if-eqz v4, :F2
:C0
const-string v6, ""
invoke-virtual String->equals(Object)Z, v4, v6
move-result v6
if-nez v6, :F2
# 如果 v4 不为空且不等于空字符串,并且不等于 v2,则执行下面的代码块
:D0
invoke-virtual String->equals(Object)Z, v4, v2
move-result v6
if-eqz v6, :F2
:DC
# 获取 MainActivity$1 类中的 this$0 字段,这是 MainActivity 对象的引用
iget-object v6, p0, MainActivity$1->this$0:MainActivity
# 调用 MainActivity 的 access$1 方法,传递 MainActivity 对象 v6
invoke-static MainActivity->access$1(MainActivity)V, v6
:E6
# 方法结束,返回空
return-void
:catch_E8# used for: Ljava/io/UnsupportedEncodingException;
# 捕获 UnsupportedEncodingException 异常,打印异常堆栈信息
move-exception v1
invoke-virtual UnsupportedEncodingException->printStackTrace()V, v1
goto :tryend_BC
# 如果条件不成立,则执行下面的代码块
:F2
new-instance v0, AlertDialog$Builder
# 创建 AlertDialog.Builder 对象,并传递 MainActivity 对象的引用
iget-object v6, p0, MainActivity$1->this$0:MainActivity
invoke-direct AlertDialog$Builder-><init>(Context)V, v0, v6
const v6, 0x7F0A0011# string:dialog_error_tips "密码不对,请继续破解"
# 设置对话框的消息内容为字符串资源 0x7F0A0011
invoke-virtual AlertDialog$Builder->setMessage(I)AlertDialog$Builder, v0, v6
const v6, 0x7F0A0010# string:dialog_title "提示"
# 设置对话框的标题为字符串资源 0x7F0A0010
invoke-virtual AlertDialog$Builder->setTitle(I)AlertDialog$Builder, v0, v6
const v6, 0x7F0A0013# string:dialog_ok "确定"
new-instance v7, MainActivity$1$1
# 创建 MainActivity$1$1 匿名内部类,并传递 MainActivity$1 对象的引用
invoke-direct MainActivity$1$1-><init>(MainActivity$1)V, v7, p0
# 设置对话框的确定按钮为字符串资源 0x7F0A0013,并设置点击事件监听器为匿名内部类对象 v7
invoke-virtual AlertDialog$Builder->setPositiveButton(I, DialogInterface$OnClickListener)AlertDialog$Builder, v0, v6, v7
# 显示对话框
invoke-virtual AlertDialog$Builder->show()AlertDialog, v0
goto :E6
.end method
```
断点进行调试,得出密码表和内置密码
!(https://s2.loli.net/2024/07/09/pUZlE57awRsS3Qr.png)
解密代码同上
------
## 改变程序
> 想要考到一百分,一是写对答案,二是修改正确答案
依据输错的错误提示字符,在androidkiller反编译后查找
!(https://s2.loli.net/2024/07/10/XKcBTvx5OEeHbfF.png)
继续查找name
!(https://s2.loli.net/2024/07/10/kWlBF358eNcfn9v.png)
继续查找id,可以看到错误提示字符串赋给了v6,而:cond_0是个代码块
!(https://s2.loli.net/2024/07/10/x48Unb3lJ5WKwHq.png)
上翻寻找跳转到cond_0的逻辑,可以看到三个if跳转语句
!(https://s2.loli.net/2024/07/10/UZwyx4sFaijcP6I.png)
直接删除跳转语句,使得程序直接执行.line 55 的成功注册逻辑,修改后保存,
!(https://s2.loli.net/2024/07/10/EV4fKsnYFCxbQ58.png)
经过androidkill编译后,重新运行,不论输入什么都出现破解成功。
!(https://s2.loli.net/2024/07/10/zK9jST5pM8Drtqw.png)
# 今日总结
最近一方面因为工期任务紧,一方面家里的琐事比较多,故懈怠了好些天。今天重拾了smali语言顺便了解了android动态调试的过程(用真机调试感觉没有PC端逆向的olldbg那样好使)。基础知识感觉没学到太多,只能说,熟悉了一些工具的使用。另外感觉自己的smali语言还得多熟悉熟悉。 短时间不建议开多个相同类型主题,比如学习主题类的,可以编辑到之前主题一起,或者通过回复更新到一个帖子里。 感谢分享,认真学习 谢谢大师技术分享! AI破解么
页:
[1]