Android 一个抽奖应用的逆向破解全流程之加固自己应用

简介: 转自: http://www.pedant.cn/2014/07/22/crack-a-draw-app/    东窗事发 偶然见到一个应用内有抽奖的活动(应用具体名称就不便告知),而且是每天都可以抽。

转自:

<a href="http://www.pedant.cn/2014/07/22/crack-a-draw-app/">http://www.pedant.cn/2014/07/22/crack-a-draw-app/</a>

  

东窗事发

偶然见到一个应用内有抽奖的活动(应用具体名称就不便告知),而且是每天都可以抽。同时抽奖之前也不需要用户登录什么的,但限定了用户一天(自然天)只能抽奖一次。那么应用的服务端在用户没有登录的情况下是依据什么来判定当前用户今天是否已抽过奖了呢?这当中判断的依据是否可靠,能否被伪造然后实现一天多次抽奖呢?带着这些问题,让我们来剥开应用的层层外纱。

初识庐山

首先在PC端打开LogCat,然后手机连接PC,最后手机上打开该应用的抽奖界面。这时我们在LogCat中发现了该应用输出的如下日志:

image

里面有onPageStart并且包含了被加载网页的url。由此可以得出结论,抽奖页是用WebView加载网页实现的。那加载这个WebView的Activity又是什么呢?

在PC端打开Android DDMS,在进程列表中找到该应用包对应的进程(如下图的进程ID为21641),然后查看Activity Manager State。

image

这时我们得到的Activity Stack就像这样。

image

由此我们就可以大概知道它Java内部的实现结构是怎样的了。首先创建的是ActivityToolsExplorer,然后在其中嵌入了一个名为FragmentToolsExplorer的Fragment,最后由FragmentToolsExplorer在onCreate里实现WebView加载网页的过程。

顺水推舟

由上面我们知道了抽奖页的Url。好了,我们首先在浏览器上打开这个Url,看看它的抽奖是怎样一步步实现的。

这个页面打开后,在页面正中间有一个用来作抽奖操作的按钮,嵌套样式名为.lucky-btn .lucky-cell-conn。当然在浏览器上这个程序是运行不起来的,我们关心的只是开始抽奖这个动作是怎样发起的。查看源码打开main.js。js文件竟然没有压缩,就更方便我们逆向跟踪了。我们找到对这个按钮绑定点击事件的位置:

main.js

 

function init(info) {
...
var deviceID=info.deviceId;
checkDrawEnable(drawingObject,deviceID);
$(".lucky-btn .lucky-cell-conn").on("click",function(e){
...
window.setTimeout(function(){
..
getJSONP(BASE_URL+"draw/"+deviceID,function(data){
drawResult(drawingObject,data);
});
},Math.random()*1000+1000);
});
 
}

  

ok,在这里我们就直接发现了,服务端用来判断用户当天已抽奖的依据是DeviceId(设备ID)。现在我们需要的是一步步逆向跟踪,找到是谁调用了init函数并带入的info参数是怎样构成的,这样似乎整个程序逻辑就会变得清晰起来。

这个网页中bridge对象为java层注入的对象,而脚本中一些初始化信息也是通过调用java方法获得的。那么我们要跟踪整个代码流程,就必须对java代码也进行逆向分析。首先拿到应用的apk包,unzip后使用baksmali将classes.dex解为smali代码包。结合脚本代码,对代码调用层次一步步追踪,这个过程需要你对smali代码也比较熟悉。最后得到如下图所示的调用流程图(具体追踪过程就不在这展开):

image

由此,我们就知道deviceId串是主要就由Lcom/xx/util/e;->a(Landroid/content/Context;)Ljava/lang/String;方法负责生成。这个方法中获取到AndroidID与DeviceId后用”_”符连接。

Lcom/xx/util/e;->j(Landroid/content/Context;)Ljava/lang/String;就是获取DeviceId的方法,具体的smali代码为:

Lcom/xx/util/e;->j(Landroid/content/Context;)Ljava/lang/String;

 

method public static j(Landroid/content/Context;)Ljava/lang/String;
.registers 2
 
const-string v0, "phone"
 
invoke-virtual {p0, v0}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
 
move-result-object v0
 
check-cast v0, Landroid/telephony/TelephonyManager;
 
invoke-virtual {v0}, Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;
 
move-result-object v0
 
return-object v0
.end method

  


偷梁换柱
至此找到获取DeviceId真正的位置,我们就破案了。

上面我们知道了,服务端用来判断用户当天已抽奖的依据是DeviceId,同时我们也追踪到了代码中获取DeviceId具体位置。这样,程序每次获取DeviceId时我们就可以伪造返回值(每次伪造的结果都不能相同),就实现一天无限次抽奖了。那怎样伪造这样的返回值呢,下面的简单一句Java代码就可以实现了。

1
return String.valueOf(System.currentTimeMillis() ^ 537400335373457L);

把上面这句翻译成smali代码后,替换掉j(Landroid/content/Context;)Ljava/lang/String;方法内原来的全部smali代码,偷梁换柱。

registers 9
 
invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
 
move-result-wide v0
 
const-wide v2, 0x1e8c344179491L
 
xor-long/2addr v0, v2
 
invoke-static {v0, v1}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;
 
move-result-object v0
 
return-object v0

  


魔高一尺,道高一丈

最后用smali.jar打包回去,签名后安装。运行起来后应用在抽奖页面已经没有了次数限制。

学习破解的目的不是为了走更多的捷径。有个道理大家都知道,最好的防守就是进攻。我们只有了解怎样去破解一个应用,才知道应该如何去加固自己的应用。就比如这个应用中,有下面这些问题可以改进来加大各方面破解的难度:

  • Debug日志不应该存在于发布版本,Error日志也尽量少暴露敏感信息。
  • 线上网页的脚本代码及样式应该压缩,压缩后可以增加逆向时阅读及追踪上的难度。
  • 不能以客户端上任何固有参数作为服务端上的关键凭据,比如这里的抽奖凭据依赖了客户端的DeviceID。
  • Java代码混淆还是需要的,虽然代码仍可以被一步步逆向跟踪,但语义上的隔离会加大追踪的时间成本。
目录
相关文章
|
3月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
340 4
|
15天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
115 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
12天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
36 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
28天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
79 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
1月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
36 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
1月前
|
测试技术 Android开发 开发者
【03】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第三篇安卓APP上架华为商店后面的步骤-华为应用商店相对比较麻烦一些-华为商店安卓上架
【03】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第三篇安卓APP上架华为商店后面的步骤-华为应用商店相对比较麻烦一些-华为商店安卓上架
53 16
|
2月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
91 14
|
2月前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
2月前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
2月前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
85 0

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Android学习自定义View(四)——继承控件(滑动时ListView的Item出现删除按钮)