Android逆向-Android逆向基础11(so demo分析)
# 0x00 前言## 导航
博客导航[戳这里](http://blog.csdn.net/qq_36869808/article/details/79270225)
这里有所有博客的集合,以及每一个博客的内容。
练习资源[戳这里](http://blog.csdn.net/qq_36869808/article/details/79290420)
这里有很多可以练习的资源,一起其他网上找不到的资源。
## 说明
感谢鬼哥的,跟着鬼哥学so分析系列。也感谢鬼哥提供的练习apk。
别人走的路,你总得走一下,才知道是什么感觉。看着别人走,得到的总没有自己走一走
## 内容
1.金币修改demo
2.用户等级更改demo
# 0x01 金币修改demo
## 样本地址
http://blog.csdn.net/qq_36869808/article/details/79290420
## 测试
找到需要进行实战的apk。
![这里写图片描述](http://t1.aixinxi.net/o_1c6cmrckuoselae3f3pltaj3a.png-j.jpg)
## 分析
这里出现的英文以及数值。
Current Coin is:目前的硬币
当前是100。
那么我们需要修改的就是这个数值了。
还是分析别人写的好。
## start
虽然知道这里一个so层分析,但是还是按照不知道的步骤进行分析吧。
### 反编译
![这里写图片描述](http://t1.aixinxi.net/o_1c6cnn05u9cd15di1b39niihh2a.png-j.jpg)
直接看到这里有一句getCoin,并且是Lcom/ggndktest1/JniGg,这个里面的函数。
打开JniGg
```
.method public static native getCoin()I
.end method
.method public static native ggPrintHello()Ljava/lang/String;
.end method
```
这里就是NDK函数的部分了。
### 尝试smali层修改。
```
invoke-static {}, Lcom/ggndktest1/JniGg;->getCoin()I
move-result v2
const/16 v2,0x100
```
因为之前的基础所以更改smali层很简单。
![这里写图片描述](http://t1.aixinxi.net/o_1c6cot3trllfrogu1uvovrvva.png-j.jpg)
当然smali层不是我们的终点,只是顺便做一个练习。
### so分析start
打开IDA。然后找到输出函数getCoin
![这里写图片描述](http://t1.aixinxi.net/o_1c6cpb3571ko11fvfohr9j51u3fa.png-j.jpg)
这个就是我们主要的修改的地方了。
### getCoin 分析
```
MOVS R0, #0x64 ; 'd'
.text:00000C06 BX LR
```
恩。。。就两句话,本来准备好好分析一下的。
```
MOVS R0, #0x64 ;
```
R0=100
```
BX LR
```
BX: 带状态切换的跳转。最低位为1时,切换到Thumb指令执行,为0时,解释为ARM指令执行。
我们只要修改一下 R0的数值就可以了。
### F5插件辅助(请勿依赖)
![这里写图片描述](http://t1.aixinxi.net/o_1c6cpm4um1dot10ir1v0i18so1ggpa.png-j.jpg)
怎么说呢,简单明了。
## 修改
### 把so文件加载到FlexHex中
进行对照。
![这里写图片描述](http://t1.aixinxi.net/o_1c6d2cqvrpqj15q6am31mimg1la.png-j.jpg)
然后找到相同的位置进行修改。
![这里写图片描述](http://t1.aixinxi.net/o_1c6d2h2d3j1b1ihg1picen1hjoa.png-j.jpg)
然后修改保存。
![这里写图片描述](http://t1.aixinxi.net/o_1c6d2n0ov1j2rd5a1l0hb9418aea.png-j.jpg)
## 回编测试
记得关了IDA
![这里写图片描述](http://t1.aixinxi.net/o_1c6d37vce9im1v8e17sq14mj1buca.png-j.jpg)
# 0x02 用户等级更改demo
## 样本地址
http://blog.csdn.net/qq_36869808/article/details/79290420
## 样本分析
![这里写图片描述](http://t1.aixinxi.net/o_1c6el8b5c104316eo1j69kba14bta.png-j.jpg)
## smali层分析
还是用smali层来进行。
目的:
1.smali层分析
2.复习
### 1.反编译,分析
![这里写图片描述](http://t1.aixinxi.net/o_1c6elk0p8eckjekv1u1vf1dha.png-j.jpg)
发现重点函数部分。我们把这一句拿出来看一下。
```
invoke-static {v0}, Lcom/ggndktest1/JniGg;->VipLevel(I)Ljava/lang/String;
```
这里看到了VipLevel(I),证明传进去了一个参数。这个参数就是v0。我们继续往上找。
找到了这样一句话。
```
const/4 v0, 0x5
```
综合一下就是 把v0的值传入VipLevel(I)函数。然后这个函数会返回一个字符串。也就是说我穿进去是5的时候,返回的是这个,那么我要是改成1的话,可能就返回是其他东西了,我们进行简单的修改测试
### 2.测试
![这里写图片描述](http://t1.aixinxi.net/o_1c6en6ct5mqsl5elmd1sqeisga.png-j.jpg)
恩,成功更改,但是这个肯定不是我的主菜。我们的主菜就是so文件分析
## so层分析
### ida打开
在IDA输出窗口中找到我们的函数。VipLevel,双击进入。
![这里写图片描述](http://t1.aixinxi.net/o_1c6eo4eddb0e40619sf1l7fghra.png-j.jpg)
#### 首先来看流程图
![这里写图片描述](http://t1.aixinxi.net/o_1c6eo7d76hlm1826hp01cun178ja.png-j.jpg)
之前我们分析过的demo,可以轻而易举的看出这个是switch结构,好,我们进入窗口看一下。
#### 分析
```
__unwind {
.text:00000C40 PUSH {R3,LR}
.text:00000C42 CMP R2, #2
.text:00000C44 BEQ loc_C60
.text:00000C46 CMP R2, #3
.text:00000C48 BEQ loc_C54
.text:00000C4A CMP R2, #1
.text:00000C4C BNE loc_C5A
.text:00000C4E LDR R1, =(aGoldVip - 0xC54)
.text:00000C50 ADD R1, PC ; "Gold Vip"
.text:00000C52 B loc_C64
```
这个是开始的部分。
```
PUSH {R3,LR}
```
创建环境
```
CMP R2, #2
```
比较R2和#2是否相等。
R2是我们输入的的东西,你问我咋知道,其实我也不知道,但是我可以猜出来。
```
BEQ loc_C60
```
相等跳转到loc_c60
```
loc_C60 ; CODE XREF: Java_com_ggndktest1_JniGg_VipLevel+4↑j
.text:00000C60 LDR R1, =(aSilveryVip - 0xC66)
.text:00000C62 ADD R1, PC ; "Silvery Vip"
```
如果输入的是2,那么就是"Silvery Vip"
剩下的类似,我就不往下看了。
#### 修改
![这里写图片描述](http://t1.aixinxi.net/o_1c6eq7rqe1feu1dm9ub319ad10rea.png-j.jpg)
我的改法就是把R2重新赋值。
![这里写图片描述](http://t1.aixinxi.net/o_1c6eqaiu6oofv0l1dach8sd31a.png-j.jpg)
这里我们发现是16位的ARM,也就是Thumb。
我们这里使用一个新工具。armCode。
![这里写图片描述](http://t1.aixinxi.net/o_1c6eqf63s1odm1edgvdjq081ugka.png-j.jpg)
然后进行机器码转换
![这里写图片描述](http://t1.aixinxi.net/o_1c6eqngnmc3mca34b22faad7a.png-j.jpg)
然后用16进制软件修改就行,当然你也可也以直接把前面的16进制码全部删掉,但是建议达到目的就行,能少该就少改。
#### 测试
![这里写图片描述](http://t1.aixinxi.net/o_1c6epsi3p131o1n4an1ovnkf6ta.png-j.jpg)
# 0x03 小黄人demo分析
## 说明
这个demo还是鬼哥的,不过鬼哥的链接好像失效了,这个是我自己找的。
http://blog.csdn.net/qq_36869808/article/details/79290420
## smali层分析
这是一个和游戏,之前写了破解方式,挨着进行搜索就行了。
搜索onresult,然后跳转switch语句即可
```
.method public final onResult(ILjava/lang/String;Ljava/lang/Object;)V
.locals 2
const/4 v1, 0x1
const/4 v0, 0x0
goto :pswitch_0
packed-switch p1, :pswitch_data_0
sput-boolean v0, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->w:Z
invoke-static {}, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->nativeShowedBilling()V
invoke-static {v1}, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->nativeActiveoffline(I)V
:goto_0
return-void
:pswitch_0
sput-boolean v0, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->w:Z
sget v0, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->m:I
invoke-static {v0}, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->nativeBillingDone(I)V
goto :goto_0
:pswitch_1
sput-boolean v0, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->w:Z
invoke-static {}, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->nativeShowedBilling()V
invoke-static {v1}, Lcom/gameloft/android/ANMP/GloftDMHM/Game;->nativeActiveoffline(I)V
goto :goto_0
nop
:pswitch_data_0
.packed-switch 0x1
:pswitch_0
:pswitch_1
.end packed-switch
.end method
```
## 测试
![这里写图片描述](http://t1.aixinxi.net/o_1c6ff2o4ch854v7rns11kb7jma.png-j.jpg)
## so层分析
![这里写图片描述](http://t1.aixinxi.net/o_1c6ff8qbaqhp1l06jjjhi1hcra.png-j.jpg)
### 数量分析
![这里写图片描述](http://t1.aixinxi.net/o_1c6ffb3euv7016qi112u3c6qaja.png-j.jpg)
这里分析之后 当输入的数值是7,8,9的时候,香蕉的数字就会变成18888。
也就是更改我们输入的值就可以了。
### 数量修改
![这里写图片描述](http://t1.aixinxi.net/o_1c6ffj4cr1gr34h8r981jne1fofa.png-j.jpg)
这里是32位ARM汇编。
C8 19 04 E3
这里我们想要更改数据,就要知道这些含义是什么。
原来的数值是 #0x49C8
和我们的数据进行对比。
c8 对应的是第一位,49被拆在了中间。
那么我们要更改的时候就是 ff 1f 0f E3
分析是可以这样分析的,但是对于学术研究的时候,还是要知根知底比较好。
这里的E3就是 mov
因为这里的数据是反的,先入高位,再入低位,实际顺序就是 E3 01 ff ff。
然后进行修改即可。
# 0x04 TTX连萌
这个demo也是鬼哥提供的,当然我们先不看鬼哥分析的,我们自己来搞
## 试玩
就是一个类似消消乐的东西。
![这里写图片描述](http://t1.aixinxi.net/o_1c6fj6vvf1fefb591v3booq13uoa.png-j.jpg)
## smlai层分析
### 内购破解
mm应用。
搜索:onBillingFinish
删掉判断逻辑即可。
```
.method public onBillingFinish(ILjava/util/HashMap;)V
.locals 4
.param p1, "code" # I
.param p2, "arg1" # Ljava/util/HashMap;
.prologue
.line 54
const-string v1, "IAPListener"
new-instance v2, Ljava/lang/StringBuilder;
invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
const-string v3, "billing finish, status code = "
invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v2
invoke-virtual {v2, p1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v2
invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
.line 55
const-string v0, "\u8ba2\u8d2d\u7ed3\u679c\uff1a\u8ba2\u8d2d\u6210\u529f"
.line 57
.local v0, "result":Ljava/lang/String;
.line 61
:cond_0
const-string v1, "IAPListener"
const-string v2, "Success"
invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
sget-object v1, Lcom/PopStar/org/PopStar;->mMain:Lcom/PopStar/org/PopStar;
invoke-static {v1}, Lcom/sdk/wraper/SDKInvoker;->getInstance(Landroid/content/Context;)Lcom/sdk/wraper/SDKInvoker;
move-result-object v1
const/4 v2, 0x0
const-string v3, ""
invoke-virtual {v1, v2, v3}, Lcom/sdk/wraper/SDKInvoker;->onBillingFinish(ILjava/lang/String;)V
.line 70
:goto_0
const-string v1, "IAPListener"
invoke-static {v1, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
.line 72
return-void
.line 67
:cond_1
new-instance v1, Ljava/lang/StringBuilder;
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
const-string v2, "\u8ba2\u8d2d\u7ed3\u679c\uff1a"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-static {p1}, Lmm/purchasesdk/Purchase;->getReason(I)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v0
goto :goto_0
.end method
```
修改后的代码。
### 反编译测试
![这里写图片描述](http://t1.aixinxi.net/o_1c6h2d21v35v144fai27lj8v9a.png-j.jpg)
### so层分析
溯源找到nativeAddCoin。
```
sput-object v0, Lcom/PopStar/org/PopStar;->mHandler:Landroid/os/Handler;
const-string v0, "xinxin"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
```
根据这个更改so文件。
打开IDA
![这里写图片描述](http://t1.aixinxi.net/o_1c6h42h1nd7i1lrm94a1mpl5p1a.png-j.jpg)
```
loc_AA722 ; CODE XREF: Java_com_PopStar_org_PopStar_nativeAddCoin+24↑j
.text:000AA722 ; Java_com_PopStar_org_PopStar_nativeAddCoin+30↑j ...
.text:000AA722 BL _ZN8GameMain11useGameCoinEi ; GameMain::useGameCoin(int)
```
跳转之后发现_ZN8GameMain11useGameCoinEi这样一个函数。
![这里写图片描述](http://t1.aixinxi.net/o_1c6h49k7m1dkntohd68173f15tba.png-j.jpg)
然后就是把R0的数值进行更改
修改这里即可。
![这里写图片描述](http://t1.aixinxi.net/o_1c6h54d3e31g1jgk1h4v1kup1o3oa.png-j.jpg)
具体可以看鬼哥的so分析。
# 0x04 结束语
## 收获
1.对ARM汇编进行一个了解。
2.对ARM进行一个熟练应用
3.对之前的内容进行一个复习。
# 以上。 请问楼主一个问题比如我拿到一个未知的程序 怎么确定他调用自定义的那个函数呢?
比如返回失败。 这个字眼在smail层的名字确定了叫onresult
那么在IDA里面是否可以去搜索onresult 来分析确定关键点? 花了10多个小时终于过了0x02 找工具几小时 找到了又弄了几小时
本来想把一款学习英语的app打通关在来学你的所有教程 瞟一下看到有游戏实战的图片就跟着做了 感谢楼主持续更新,学习了 感谢楼主持续更新,过程真详细 谢谢分享。
最好IDA 反汇编时,同步显示Hex代码。否则怎么知道赋值语句MOVS R0, #0x64 ;是 0x64 x20? 教程挺详细的,看看有没有时间学学{:1_907:} 有没有研究物联网设备的呢 这玩意没安卓的基础,好学吗 感谢楼主。 最近学习修改qq
谢谢大佬
页:
[1]
2