前言

这几天手机上装了个软件,用了没多久就收费了,颇为不爽,于是便想看看能否破解,便有了下文,请注意该文章只为技术交流,请不要进行非法破解。

软件描述

这个apk使用一定次数后就会扣掉积分 当积分少于0的时候 便不能使用,每次启动程序的时候便会提示积分为0,需要注册,这说明程序在启动的时候就已经检测了积分,刚好可以利用这点

练手软件

http://pan.baidu.com/share/link?shareid=64695&uk=201738998

1、环境配置   
首先请下载好最新的jdk,网络上到处都是,记得配置环境变量,网络都有其次下载工具(请注意使用的时候所有路径要英文)

http://code.google.com/p/gapktool/downloads/list

2.开始反编译
(1)使用工具apktool1.4. 他在上面提供的工具的lib目录下,用前先将apk文件拷本到这个目录下,使用方法是,启动cmd,定位到该目录,然后键入命令:xxx.apk为你的apk

apktool d xxx.apk

然后就会在该目录下生成反编译的文件,包括资源,源代码(是java的反编译文件),我们将在这里修改源代码

(2)打开Gapktool.bat,选择你的apk,及其反编译输出的路径,注意不要中文,请将两个勾选上,点击开始反编译就会生成反编译文件,过不了多久就会提示保存,以及自动打开java decompiler

(3)需要注意到是java decompiler里面的源代码似乎被混淆了,很多变量或者函数词不达意,需要自己去猜
(4)在自己设置的输出目录中,除了包含反编译的代码外,还有其他资源,图片等,这里可以手动DIY或者汉化如在res\values下  包含strings.xml  这个文件包含软件菜单的文件,可以汉化res\values下 的drawable包含图片资源 可以替换等等  大家可以自己发觉

3.代码的定位   
我们的目的是为了破解,那么代码的文件在smali文件夹下,通过分析可以知道,com文件夹是程序主要的代码,net主要包括广告代码,android应该是安卓系统的库代码吧,在com文件夹加内包括许多smail的文件这些都是主程序的核心代码,但是命名都没有规则,你不知道他们是拿来干什么的

所幸的是 部分文件还是可以猜出来的 ,比如activity_register.smali,An_QimenActivity.smali这些一看就知道是与注册相关的文件

(1)既然如此,我们就在Java Decompiler中查看下activity_register.java,代码很明显:

package com.nfbazi.qimen;import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.nfbazi.qimen.a.a;public class activity_register extends Activity
{a a = new a(this);private SharedPreferences b;protected void onCreate(Bundle paramBundle){super.onCreate(paramBundle);setContentView(2130903043);EditText localEditText1 = (EditText)findViewById(2131165228);EditText localEditText2 = (EditText)findViewById(2131165230);localEditText1.setText(a.o);localEditText2.setFocusable(true);localEditText2.setFocusableInTouchMode(true);Button localButton1 = (Button)findViewById(2131165232);Button localButton2 = (Button)findViewById(2131165233);localButton1.setOnClickListener(new bp(this));localButton2.setOnClickListener(new bo(this));TextView localTextView = (TextView)findViewById(2131165231);if (a.q)   //如果对象a.q字段不为0{localTextView.setTextColor(-16776961);    //那么设置文字颜色localTextView.setText("您已经注册了本程序。");  //设置文本localEditText2.setText("************");   //设置文本localEditText2.setEnabled(false);  //     将填写注册码的文本框变灰 因为已经注册了}}
}

那么我们只要简单的 把if(a.q)去掉就不就可以了?

(2)我们打开activity_register.smali  观察代码:拉到最后,代码比较长 我们不关心别的

.class public Lcom/nfbazi/qimen/activity_register;
.super Landroid/app/Activity;# instance fields
.field a:Lcom/nfbazi/qimen/a/a;.field private b:Landroid/content/SharedPreferences;# direct methods
.method public constructor <init>()V.locals 1invoke-direct {p0}, Landroid/app/Activity;-><init>()Vnew-instance v0, Lcom/nfbazi/qimen/a/a;invoke-direct {v0, p0}, Lcom/nfbazi/qimen/a/a;-><init>(Landroid/content/Context;)Viput-object v0, p0, Lcom/nfbazi/qimen/activity_register;->a:Lcom/nfbazi/qimen/a/a;return-void
.end method.method static synthetic a(Lcom/nfbazi/qimen/activity_register;)Landroid/content/SharedPreferences;.locals 1iget-object v0, p0, Lcom/nfbazi/qimen/activity_register;->b:Landroid/content/SharedPreferences;return-object v0
.end method.method static synthetic a(Lcom/nfbazi/qimen/activity_register;Landroid/content/SharedPreferences;)V.locals 0iput-object p1, p0, Lcom/nfbazi/qimen/activity_register;->b:Landroid/content/SharedPreferences;return-void
.end method# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V.locals 4const/4 v3, 0x1invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)Vconst v0, 0x7f030003invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->setContentView(I)Vconst v0, 0x7f07002cinvoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;move-result-object v0check-cast v0, Landroid/widget/EditText;const v1, 0x7f07002einvoke-virtual {p0, v1}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;move-result-object v1check-cast v1, Landroid/widget/EditText;sget-object v2, Lcom/nfbazi/qimen/a/a;->o:Ljava/lang/String;invoke-virtual {v0, v2}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)Vinvoke-virtual {v1, v3}, Landroid/widget/EditText;->setFocusable(Z)Vinvoke-virtual {v1, v3}, Landroid/widget/EditText;->setFocusableInTouchMode(Z)Vconst v0, 0x7f070030invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;move-result-object v0check-cast v0, Landroid/widget/Button;const v2, 0x7f070031invoke-virtual {p0, v2}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;move-result-object v2check-cast v2, Landroid/widget/Button;new-instance v3, Lcom/nfbazi/qimen/bp;invoke-direct {v3, p0}, Lcom/nfbazi/qimen/bp;-><init>(Lcom/nfbazi/qimen/activity_register;)Vinvoke-virtual {v0, v3}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)Vnew-instance v0, Lcom/nfbazi/qimen/bo;invoke-direct {v0, p0}, Lcom/nfbazi/qimen/bo;-><init>(Lcom/nfbazi/qimen/activity_register;)Vinvoke-virtual {v2, v0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)Vconst v0, 0x7f07002finvoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;move-result-object v0check-cast v0, Landroid/widget/TextView;sget-boolean v2, Lcom/nfbazi/qimen/a/a;->q:Zif-eqz v2, :cond_0   //这里的if-eqz 就是说 如果v2变量等于0的平方那么就跳...,我们将他删除掉const v2, -0xffff01  //定义常量v2invoke-virtual {v0, v2}, Landroid/widget/TextView;->setTextColor(I)V  //调用方法设置颜色,参数为v0和v2,那么v2应该是颜色信息const-string v2, "\u60a8\u5df2\u7ecf\u6ce8\u518c\u4e86\u672c\u7a0b\u5e8f\u3002" //定义字串也就是该程序已经注册invoke-virtual {v0, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)Vconst-string v0, "************" //将文本框设置为**********  之后再设置为灰色invoke-virtual {v1, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)Vconst/4 v0, 0x0invoke-virtual {v1, v0}, Landroid/widget/EditText;->setEnabled(Z)V:cond_0return-void
.end method

所以完整的代码是:

上面部分一样   从这里开始const v2, -0xffff01invoke-virtual {v0, v2}, Landroid/widget/TextView;->setTextColor(I)Vconst-string v2, "\u60a8\u5df2\u7ecf\u6ce8\u518c\u4e86\u672c\u7a0b\u5e8f\u3002"invoke-virtual {v0, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)Vconst-string v0, "************"invoke-virtual {v1, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)Vconst/4 v0, 0x0invoke-virtual {v1, v0}, Landroid/widget/EditText;->setEnabled(Z)V:cond_0return-void
.end method

事实上  经过以上修改之后,只是在注册窗口上显示注册了  而积分依旧是0  代码还需要定位  这里只是为了好看 如图:

(2)那么既然这个文件没用  我们就看另一个An_QimenActivity.java这个文件,通过搜索“积分”我们可以看到这样的代码:

public String d(){com.nfbazi.qimen.a.a.a = c();if (com.nfbazi.qimen.a.a.a < 5);for (String str = "剩余积分:" + Integer.toString(com.nfbazi.qimen.a.a.a) + " 分。 您的积分不足。" + 10 + "次试用期过后,如果没有注册,还想继续免费使用软件,可点击程序主页面右下角的“获取积分”," + "通过下载安装应用,免费获取一定积分。" + "您也可以付费注册本软件,无需通过积分方式使用。点击程序主页面左下角“菜单”里的帮助,查看如何注册。" + "注册后,不会再有积分事项显示。"; ; str = "剩余积分:" + Integer.toString(com.nfbazi.qimen.a.a.a) + " 分。 每次点击“时家奇门”会“日家奇门”,会消费积分 " + 5 + " 分。")return str;}

明显是注册的....通过判断对象a.a.a是否小于5,也就是积分是否小于5来进行提示,那么a.a.a的值使通过他上面的c()方法来得到的,我们现在在这个文件中搜索c()代码;

public int c(){try{int i2 = YoumiPointsManager.queryPoints(this);i1 = i2;return i1;   //返回的i1就是我们的积分,而i1是通过调用YoumiPointsManager.queryPoints(this)得到的,我们没必要深究这个方法的实现,只要修改返回的值就得到积分了}catch (Exception localException){while (true)int i1 = 0;}}

我们那么打开An_QimenActivity.smali定位到c()方法(方法名是一样的,只是汇编代码不一样) 代码如下:

.method public c()I.locals 1:try_start_0  //异常代码//得到积分invoke-static {p0}, Lnet/youmi/android/appoffers/YoumiPointsManager;->queryPoints(Landroid/content/Context;)I:try_end_0  //异常结束.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0move-result v0   //将积分赋给v0返回,,我们可以在这行代码上面修改v0的值 这样不管他返回多少 都会被我们覆盖 我们可以这样修改const/4 v3,0xxxx   xxx为你需要的积分:goto_0return v0:catch_0   //处理异常部分move-exception v0const/4 v0, 0x0goto :goto_0
.end method

修改后的代码是:其他都一样 这里只显示c()

.method public c()I.locals 1:try_start_0invoke-static {p0}, Lnet/youmi/android/appoffers/YoumiPointsManager;->queryPoints(Landroid/content/Context;)I:try_end_0.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0const/4 v0,0x5move-result v0:goto_0return v0:catch_0move-exception v0const/4 v0, 0x0goto :goto_0
.end method

这样我们就破解完成了.....

4.apk的打包和签名    
(1)同样使用apktool1.4,命令格式为:

apktool b xxxx

其中xxx为你的文件夹,如果环境配置没错,代码修改的也没错,那么将顺利编译,编译成功的文件在你的apk目录下的dist文件夹,将他拷贝出来,这时候还不能安装,因为没有签名

(2)打开签名工具auto-sign,将刚才生成的apk文件拷贝到这里,并且其改名为update.zip,然后运行sign.bat批处理,会自动生成一个update_signed.zip文件,这个文件就是签名后的文件,可以修改为xx.apk进行安装了

如图  这样的破解后的样子,每次点击起局都会固定返回5积分,至于你问我为什么不修改多点积分,我也想,每次修改为其他值就编译报错,估计是设计到安卓编程的设计,或者寄存器吧这个还有待研究...............另外提供的练手压缩包内的注册部分 我就没改了留给大家练手吧,把积分搞定了等于免费了,其实还可以搞其他的,如去广告,修改资源等等

破解到这里就基本完成了,可以看到手机软件写的比较简单,我们修改一个return就ok了,随着安卓平台的普及,相信未来安卓平台的趋势将会愈发重要

原文:https://bbs.pediy.com/thread-156786.htm

【移动安全实战篇】————1、Android手机下xx.apk JAVA破解之旅相关推荐

  1. android没有输入焦点类控件的输入法调用,Android 手机下输入框获取焦点时, 输入法会挡住输入框...

    // Android 手机下输入框获取焦点时, 输入法会挡住输入框 // 解决方法: // Android 手机下, input 或 textarea 元素聚焦时, 主动滚动 if (/Android ...

  2. [Android] Android 手机下 仿 微信 客户端 界面 -- 微聊

    Android 手机下 仿 微信 客户端 界面 -- 微聊 (包括聊天列表 + 聊天对话页 + 朋友圈列表页 + 我的/发现 列表页) 项目演示: 功能说明: 1)底部标签切换 (TabHost + ...

  3. linux手机摄像头,Android手机下开发摄像头拍摄

    SurfaceView可以直接访问一个画布,SurfaceView是提供给需要直接画像素而不是使用窗体部件的应用使用的.Android图形系统中的一个重要概念是Surface,View及其子类(如Te ...

  4. android手机下开发摄像头拍摄

    SurfaceView可以直接访问一个画布,SurfaceView是提供给需要直接画像素而不是使用窗体部件的应用使用的.Android图形系统中的一个重要概念是Surface,View及其子类(如Te ...

  5. android手机如何安装apk文件,如何安装APK文件到自己的android手机里?.doc

    如何安装APK文件到自己的android手机里? 很多朋友刚拿到G1的时候大概首先就是要往里面装软件了,在ANDROID平台下安装文件的后缀名为".apk",就好像PC上的安装文件 ...

  6. 实战:kali攻击Android手机

    1.Metasploit及其监听模块介绍 二.手机端渗透原理 三.制作恶意软件并获取shell权限 四.实战:远程控制 msf Metasploit是一个免费的.可下载的框架,通过它可以很容易地获取. ...

  7. [Android] Android 手机下 仿 今日头条 新闻客户端

    利用一个月的时间,自学了 Android 开发 ,为了检验学习成果,特意 开发了这个  仿 今日头条 新闻客户端 AppNews 包括图文新闻+视频新闻+图片新闻 预览演示如下: 功能说明: 1)底部 ...

  8. 〖Python APP 自动化测试实战篇③〗- Mac系统下 appium 环境的配置搭建

    订阅 Python全栈白宝书-零基础入门篇 可报销!白嫖入口-请点击我.推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 Python全栈白宝书专栏,免费阶段订阅数量43 ...

  9. Android Mac下安装Apk到模拟器上

    想要mac电脑的AVD上安装APK的方法 先打开AVD.然后按照下面的步骤做即可. 1. 打开"终端" 2.下载所需要的APK文件 3.找到SDK中得platform-tools文 ...

最新文章

  1. 如何查询并解决80端口 (转)
  2. 60行代码爬取知乎“神回复”,句句戳中泪点
  3. Mac下使用可执行脚本记录远程服务器账号和密码
  4. 分享一个超棒的响应式幻灯jQuery插件 - refineslide
  5. 张亚勤:从信息化生存到互联网化生存 百度重构互联网安全防护体系
  6. 实现一个简易的RPC
  7. c++内存管理-分配失败
  8. Paint.NET 3.0正式版发布了
  9. GCC 和 MDK (即 Keil) 手工指定其地址及指针
  10. Opencv--从CalibrateCamera到SolvePnp(一)
  11. 渗透测试入门6之权限提升
  12. 1-算法-hanoi汉诺塔问题- 递归
  13. 阿里 AI「一对多」挑战人类律师;谷歌或将推出自研手机和电脑芯片;JavaScript诞生25周年|极客头条...
  14. 看咒语,知情节?他们用《哈利·波特》让AI学习剧透
  15. uniapp Android离线打包Activity class {com.xxx.yyy/io.dcloud.PandoraEntry} does not exist.
  16. CAM350 使用,典型做钢网
  17. 网页title如何优化
  18. Tomcat之Directory Listing
  19. android 4.4 蓝牙开发总结(电视盒子)
  20. MTK 平台TP调试遇坑

热门文章

  1. sqlserver 新手入门(链接服务器,初始化操作,创建用户,数据库)
  2. python大一知识点总结_python 知识点总结
  3. Keil安装stm库文件方法及下载地址
  4. 中国配电自动化设备市场趋势报告、技术动态创新及市场预测
  5. 背景橡皮擦,通道抠图
  6. 华大单片机 HC32F460 驱动74HC595D
  7. 新股上市日、新股发行网上申购日的区别
  8. 前端根据银行卡号获取该银行卡的信息
  9. 2022年几款前沿的文本语义检索/Sentence Embedding方法:Gradient Cache, SGPT,ART,DPTDR,RocketQAv2, ERNIE-Search等
  10. 贾跃亭美国造车全调查,名下已几无资产|钛媒体深度