好友
阅读权限10
听众
最后登录1970-1-1
|
Eacho
发表于 2018-2-27 23:59
本帖最后由 Eacho 于 2018-2-28 00:06 编辑
初学勿喷,如果有什么错误的地方,还请指点一下
因为初学,想找一些APP练手,说来惭愧,我被https://www.52pojie.cn/thread-656493-1-1.html这个帖子里的app难住了,看了一天,都没成功破解,明天再努力努力看看能不能破解,不行我要来发帖提问了
然后这次是从这里看到的帖子https://www.52pojie.cn/thread-702259-1-1.html,我和这位楼主的想法一样,用自己学到的一些知识尝试破解,我破解完然后回过头来看他的方法(本来以为这个也破解不出来,可以参考他的方法,或者跟着他的方法去做,但是似乎不用了),思路还是不同的
0x1 预备知识
Java基础
Smali语法
0x2 准备工具
AndroidKiller/ApkIDE/IDA..等等自己挑一个,我选AndroidKiller,我感觉界面比较舒服
jadx-gui/Java Decompiler/jd-gui/jeb..等等自己挑一个,我这次选了jeb,因为都说这是神器,我就来用用看,感觉都差不多,可能我打开方式不对
0x3 望
先打开APP看看长什么样的进入商城,跟其他APP都一个样
随便点一个购买看看,弹出了支付方式选择窗口
点取消看看,toast了一个支付取消信息,那第一破解反应就是点取消执行成功的代码(APP是破解后才写的,懒得装原版的了,点取消就购买成功了,打码的地方是购买成功提示)
0x4 闻
拖到jeb里看看进去先搜字符串,像这种内购的,虽然我之前仅仅CM了两个内购,但是经验已经总结起来了,字符串直接搜"支付","Pay"基本都能应付这是搜到的字符串,往下一拖 就能看到之前的那个提示 “道具支付已取消”
双击这个关键词,进入到关键词所在代码,jeb首先跳转到的是smali里,我们右键反编译一下,就能获取到java源码
可以看到关键词所在的方法名为payCancel,里面的代码也很简单
给v1赋值提示语句 String v1 = String.valueOf("道具支付已取消") + "\nalias: " + arg6.get("toolsAlias");
点取消后看到的提示内容Toast.makeText(Telecom3Pay.this.mContext, ((CharSequence)v1), 0).show();
日志Log.i("KengSDK", v1);
最后有一个调用代码,从前面几行代码可以看到,都是跟支付取消业务逻辑没有一点关系的代码,那么总要有一个地方来处理取消支付后该怎么运行吧?所以这一行一定是支付取消后的业务逻辑
Telecom3Pay.this.mOnPayListener.onPostPay(false, Telecom3Pay.this._id);
往下翻,还可以看到payFailed和paySuccess两个方法,通过名字我们也知道这两个方法是干嘛的吧,一个支付失败,一个支付成功
我们对比一下,发现在最后都有调用Telecom3Pay.this.mOnPayListener.onPostPay(参数...)
只是参数不太一样,我们全部复制下来 就能很清楚的看到他们的参数有什么不同了
支付取消 Telecom3Pay.this.mOnPayListener.onPostPay(false, Telecom3Pay.this._id);
支付失败 Telecom3Pay.this.mOnPayListener.onPostPay(false, Telecom3Pay.this._id);
支付成功 Telecom3Pay.this.mOnPayListener.onPostPay(true, Telecom3Pay.this._id);
很明显,未支付成功的,第一个参数都是false,所以我们只要在smali里把这个false改成true就ok了
0x5 问
把apk拖到AndroidKiller
找到关键词所在的smali文件Telecom3Pay.smali
但是好像有好几个类似的文件名
带$符号的代表是内部类,这个是java基础里的
那就算不知道这个也没关系,也就4个文件吗,一个个的打开找也可以,反正我知道也是一个个打开来找的,或者从工程搜索里搜索关键词都行,很简单就能找到payCancel方法虽然在Java里看起来只有几行代码,但是在smali还是很长的,这是整个payCanel方法代码
[Shell] 纯文本查看 复制代码 .method public payCancel(Ljava/util/Map;)V
.locals 5
.parameter
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Ljava/util/Map",
"<",
"Ljava/lang/String;",
"Ljava/lang/String;",
">;)V"
}
.end annotation
.prologue
.local p1, params:Ljava/util/Map;,"Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;"
const/4 v4, 0x0
.line 139
const-string v1, "\u9053\u5177\u652f\u4ed8\u5df2\u53d6\u6d88"
.line 140
.local v1, msg:Ljava/lang/String;
new-instance v2, Ljava/lang/StringBuilder;
invoke-static {v1}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
move-result-object v3
invoke-direct {v2, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
const-string v3, "\nalias: "
invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v3
.line 141
const-string v2, "toolsAlias"
invoke-interface {p1, v2}, Ljava/util/Map;->get(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/String;
invoke-virtual {v3, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v2
.line 140
invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
.line 142
iget-object v2, p0, Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay$1;->this$0:Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;
#getter for: Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;->mContext:Landroid/content/Context;
invoke-static {v2}, Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;->access$2(Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;)Landroid/content/Context;
move-result-object v2
invoke-static {v2, v1, v4}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v2
invoke-virtual {v2}, Landroid/widget/Toast;->show()V
.line 143
const-string v2, "KengSDK"
invoke-static {v2, v1}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I
.line 145
iget-object v2, p0, Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay$1;->this$0:Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;
#getter for: Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;->_id:I
invoke-static {v2}, Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;->access$0(Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;)I
move-result v0
.line 146
.local v0, id:I
iget-object v2, p0, Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay$1;->this$0:Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;
#getter for: Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;->mOnPayListener:Lzygame/ipk/pay/OnPayListener;
invoke-static {v2}, Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;->access$1(Lcom/ipeaksoft/pay/libpaytelecom3/Telecom3Pay;)Lzygame/ipk/pay/OnPayListener;
move-result-object v2
invoke-interface {v2, v4, v0}, Lzygame/ipk/pay/OnPayListener;->onPostPay(ZI)V
.line 147
return-void
.end method
我们到最后找到调用onPostPay的代码就好了invoke-interface {v2, v4, v0}, Lzygame/ipk/pay/OnPayListener;->onPostPay(ZI)V
到这不知道该哪个参数怎么办,没关系,我们找到paySuccess的调用代码就好了
const/4 v3, 0x1
invoke-interface {v2, v3, v0}, Lzygame/ipk/pay/OnPayListener;->onPostPay(ZI)V
可以看到唯一不同的就是v4和v3
那么在paySuccess里v3 是赋了个0x1的值,我们就回到payCancel里把他的v4赋个0x1的值
也就是在调用onPostPay前面加一个赋值代码const/4 v4, 0x1最终结果就是加一行代码就可以CM了
0x6 切
用Andriod Killer把apk回编就好了
样本文件的话,从原帖里去下https://www.52pojie.cn/thread-697256-1-1.html
破解文件的话,第一版破解的应该比我的更完美,还是下载他的吧
|
免费评分
-
查看全部评分
|