吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 45681|回复: 103
收起左侧

[Android 原创] 【Android】安卓手机下xx.apk JAVA破解之旅

    [复制链接]
元亨利之贞 发表于 2013-4-7 20:18
前言:
看到吾爱安卓方面的文章较少,发篇以前的文章 赚点cb 嘿嘿
这几天手机上装了个软件,用了没多久就收费了,颇为不爽,于是便想看看能否破解,便有了下文,

请注意该文章只为  技术交流,请不要进行非法破解。技术有限  难免有疏漏之处  还望海涵

软件描述:这个apk使用一定次数后就会扣掉积分 当积分少于0的时候 便不能使用,每次启动程序的时候便会提示积分为0,需要注册,
这说明程序在启动的时候就已经检测了积分,刚好可以利用这点
下载地址:
[AppleScript] 纯文本查看 复制代码
http://pan.baidu.com/share/link?shareid=64695&uk=201738998

220545luw4lo5abw14qwi4.png
1.环境配置
   首先请下载好最新的jdk,网络上到处都是,记得配置环境变量,网络都有
   其次下载工具(请注意使用的时候所有路径要是英文的)
[AppleScript] 纯文本查看 复制代码
http://code.google.com/p/gapktool/downloads/list
   以及签名工具: Auto-sign_aW.zip (9.82 KB, 下载次数: 215)
   另外附加一个网址 是翻译java的反汇编代码的,大家看不懂可以参考这个网站:
   http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

2.开始反编译
(1)使用工具apktool1.4(现在有1.5了). 他在上面提供的工具的lib目录下,用前先将apk文件拷本到这个目录下,使用方法是,启动cmd,定位到该目录,然后键入命令:xxx.apk为你的apk
[AppleScript] 纯文本查看 复制代码
apktool d xxx.apk 

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

(2)打开Gapktool.bat,选择你的apk,及其反编译输出的路径,注意不要中文,请将两个勾选上,点击开始反编译就会生成反编译文件,过不了多久就会提示保存,以及自动打开java decompiler
213345wwxps4psw06bp4wd.jpg
(3)需要注意到是java decompiler里面的源代码似乎被混淆了,很多变量或者函数词不达意,需要自己去猜
(4)在自己设置的输出目录中,除了包含反编译的代码外,还有其他资源,图片等,这里可以手动DIY或者汉化
        如在res\values下  包含strings.xml  这个文件包含软件菜单的文件,可以汉化  
             res\values下 的drawable包含图片资源 可以替换等等  大家可以自己挖掘
214424e8ruxlhz6rg6rh0k.jpg

3.代码的定位
我们的目的是为了破解,那么代码的文件在smali文件夹下,通过分析可以知道,com文件夹是程序主要的代码,net主要包括广告代码,android应该是安卓系统的库代码吧,在com文件夹加内包括许多smail的文件这些都是主程序的核心代码,但是命名都没有规则,你不知道他们是拿来干什么的
214833u61xososc2s0tys1.jpg
所幸的是 部分文件还是可以猜出来的 ,比如activity_register.smali,An_QimenActivity.smali这些一看就知道是与注册相关的文件
(1)既然如此,我们就在Java Decompiler中查看下activity_register.java,代码很明显:
[AppleScript] 纯文本查看 复制代码
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  观察代码:拉到最后,代码比较长 我们不关心别的
[AppleScript] 纯文本查看 复制代码
.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 1

invoke-direct {p0}, Landroid/app/Activity;-><init>()V

new-instance v0, Lcom/nfbazi/qimen/a/a;

invoke-direct {v0, p0}, Lcom/nfbazi/qimen/a/a;-><init>(Landroid/content/Context;)V

iput-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 1

iget-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 0

iput-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 4

const/4 v3, 0x1

invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

const v0, 0x7f030003

invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->setContentView(I)V

const v0, 0x7f07002c

invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;

move-result-object v0

check-cast v0, Landroid/widget/EditText;

const v1, 0x7f07002e

invoke-virtual {p0, v1}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;

move-result-object v1

check-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;)V

invoke-virtual {v1, v3}, Landroid/widget/EditText;->setFocusable(Z)V

invoke-virtual {v1, v3}, Landroid/widget/EditText;->setFocusableInTouchMode(Z)V

const v0, 0x7f070030

invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;

move-result-object v0

check-cast v0, Landroid/widget/Button;

const v2, 0x7f070031

invoke-virtual {p0, v2}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;

move-result-object v2

check-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;)V

invoke-virtual {v0, v3}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V

new-instance v0, Lcom/nfbazi/qimen/bo;

invoke-direct {v0, p0}, Lcom/nfbazi/qimen/bo;-><init>(Lcom/nfbazi/qimen/activity_register;)V

invoke-virtual {v2, v0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V

const v0, 0x7f07002f

invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View;

move-result-object v0

check-cast v0, Landroid/widget/TextView;

sget-boolean v2, Lcom/nfbazi/qimen/a/a;->q:Z

if-eqz v2, :cond_0 //这里的if-eqz 就是说 如果v2变量等于0的平方那么就跳...,我们将他删除掉

const v2, -0xffff01 //定义常量v2

invoke-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;)V

const-string v0, "************" //将文本框设置为********** 之后再设置为灰色

invoke-virtual {v1, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V

const/4 v0, 0x0

invoke-virtual {v1, v0}, Landroid/widget/EditText;->setEnabled(Z)V

:cond_0
return-void
[/backcolor].end method


所以完整的代码是:
[AppleScript] 纯文本查看 复制代码
 上面部分一样 从这里开始
const v2, -0xffff01

invoke-virtual {v0, v2}, Landroid/widget/TextView;->setTextColor(I)V

const-string v2, "\u60a8\u5df2\u7ecf\u6ce8\u518c\u4e86\u672c\u7a0b\u5e8f\u3002"

invoke-virtual {v0, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V

const-string v0, "************"

invoke-virtual {v1, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V

const/4 v0, 0x0

invoke-virtual {v1, v0}, Landroid/widget/EditText;->setEnabled(Z)V

:cond_0
return-void
.end method


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

(2)那么既然这个文件没用  我们就看另一个An_QimenActivity.java这个文件,通过搜索“积分”我们可以看到这样的代码:
[AppleScript] 纯文本查看 复制代码
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()代码;
[AppleScript] 纯文本查看 复制代码
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()方法(方法名是一样的,只是汇编代码不一样) 代码如下:
[AppleScript] 纯文本查看 复制代码
.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_0

move-result v0 //将积分赋给v0返回,,我们可以在这行代码上面修改v0的值 这样不管他返回多少 都会被我们覆盖 我们可以这样修改const/4 v3,0xxxx xxx为你需要的积分

:goto_0
return v0

:catch_0 //处理异常部分
move-exception v0

const/4 v0, 0x0

goto :goto_0
.end method


修改后的代码是:其他都一样 这里只显示c()
[AppleScript] 纯文本查看 复制代码
.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_0
const/4 v0,0x5  //关键一句
move-result v0

:goto_0
return v0

:catch_0
move-exception v0

const/4 v0, 0x0

goto :goto_0
.end method


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

4. apk的打包和签名
(1)同样使用apktool1.4,命令格式为:
[AppleScript] 纯文本查看 复制代码
apktool b xxxx

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

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

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


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


五:遗留的一些问题
其实这个破解不是真正意义上的破解,我只是修改了积分,还是再研究下达到程序的注册,去广告等。
另外程序在修改积分的时候 我发现除了修改为0x5以外  其他的值都会奔溃,不知道为什么
希望有高手可以解答下







免费评分

参与人数 7热心值 +7 收起 理由
吾爱破解1990 + 1 我很赞同!
szs6008 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.
这只猪 + 1 啊啊啊啊!不小心手贱点到了反对。。。不好.
youdeath + 1 新手的福音。好东东。今天也是第一次评分,.
qq1129209565 + 1 我很赞同!
781732825 + 1 我很赞同!
okman110 + 1 这样的帖子 居然没人加热心和分 没天理啊!

查看全部评分

本帖被以下淘专辑推荐:

  • · 教程|主题: 123, 订阅: 88

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Rocfly 发表于 2014-7-12 16:54








                       我是为了来涨姿势的
头像被屏蔽
xiawei1203 发表于 2013-4-7 20:23
zxxz2002 发表于 2013-4-7 20:24
q2533714 发表于 2013-4-7 20:24
哈哈哈 学习了 谢谢分享
kuwo911 发表于 2013-4-7 20:28
强力教程    非常精彩
furedelu 发表于 2013-4-7 20:33
前来学习学习
qq7156792 发表于 2013-4-7 20:34
一种破解思路,很不错的说,谢谢分享
jerry828 发表于 2013-4-7 20:40
学习了!
Apocalypse 发表于 2013-4-7 20:51
值得分享 不过有些数据加密就比较困难
niucaidi 发表于 2013-4-7 20:55
虽然我看不懂!  但是我果断要顶!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-28 01:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表