|
本帖最后由 csky6688 于 2015-7-24 20:07 编辑
今天不知道怎么的,论坛登录不了,所以在某首发了
-----------------------------------------------------------------------
最近刚接触android逆向,因此,分析的比较简单,请多多包涵。
apk来源于本论坛,当时帖子的作者,通过修改积分数值,对软件进行了逆向,但并未找出注册机制等等,因此下面将对注册机制进行分析。
刚拿到该APK,先安装看看效果,但是安装后会闪退,并给出提示如下:
因此,猜测该APK应该会检查更新,如果有更新,就退出,并提示安装新版本。
载入JEB,进行分析,发现代码进行了混淆。虽然如此,但可以找到activity_register,An_QimenActivity。activity_register用处不是特别大,找到An_QimenActivity中的onCreate方法,发现如下代码:
- this.getWindow().setSoftInputMode(3);
- if(this.b()) {
- Toast.makeText(this.getApplicationContext(), "本程序已有升级版,可在南方周易程序网站升级更新:www.nfbazi.com", 1)
- .show();
- this.finish();
- }
- else {。。。}
复制代码 可以看到,我们的猜测是对的,因此首先去掉该限制,利用apktool反编译,找到An_QimenActivity.smali中的onCreate方法,找到如下代码:
- if-eqz v0, :cond_0
- invoke-virtual {p0}, Lcom/nfbazi/qimen/An_QimenActivity;->getApplicationContext()Landroid/content/Context;
- move-result-object v0
- const-string v1, "\u672c\u7a0b\u5e8f\u5df2\u6709\u5347\u7ea7\u7248\uff0c\u53ef\u5728\u5357\u65b9\u5468\u6613\u7a0b\u5e8f\u7f51\u7ad9\u5347\u7ea7\u66f4\u65b0\uff1awww.nfbazi.com"
- invoke-static {v0, v1, v7}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
- move-result-object v0
- invoke-virtual {v0}, Landroid/widget/Toast;->show()V
- invoke-virtual {p0}, Lcom/nfbazi/qimen/An_QimenActivity;->finish()V
- :goto_0
复制代码 将if-eqz v0修改为if-nez v0,重新打包,签名,即可运行。
分析发现,该软件有10次的限制,10后积分会减为0,当然针对积分的限制,原帖作者已经给出了分析方法。而本文重点介绍该软件的注册机制
点击菜单可以发现注册窗口,因此需要分析该软件的注册机制,找到注册码。
在JEB中找到bp类,并找到onClick方法,代码如下:
- public void onClick(View arg6) {
- int v3 = -16776961;
- if(a.q) {
- this.a.finish();
- }
- else {
- View v0 = this.a.findViewById(2131165230);
- View v1 = this.a.findViewById(2131165231);
- String v0_1 = ((EditText)v0).getText().toString().trim();
- if(v0_1.length() == 0) {
- ((TextView)v1).setTextColor(v3);
- ((TextView)v1).setText("您还没有输入注册码。");
- }
- else if(!d.a(a.o, v0_1)) {
- ((TextView)v1).setTextColor(v3);
- ((TextView)v1).setText("您输入的注册码不对。");
- }
- else {
- ((TextView)v1).setTextColor(-65536);
- ((TextView)v1).setText("注册成功,点击“退出”。");
- activity_register.a(this.a, this.a.getSharedPreferences("pcr", 0));
- activity_register.a(this.a).edit().putString("acc", this.a.a.a(v0_1)).commit();
- activity_register.a(this.a).edit().putString("bcc", this.a.a.a(a.o)).commit();
- a.c("pcr");
- }
- a.p = "a@^*(^*ga$(&%io";
- }
- }
复制代码 看到注册部分的代码了吧,主要是提取我们输入的注册码,与该软件的真正的注册码进行比较判断。
跟入a.o 发现是一个string
- public class a {
- ....
- public static String o;
- ....
- static {
- .....
- a.o = "";
- }
- }
复制代码 然后查看什么时候对a.o进行的赋值,如下:
- public boolean b() {
- int v6 = 8;
- int v5 = 7;
- Object v0 = this.G.getSystemService("phone");
- String v1 = ((TelephonyManager)v0).getDeviceId();
- String v2 = ((TelephonyManager)v0).getSubscriberId();
- String v0_1 = ((TelephonyManager)v0).getSimSerialNumber();
- if(v1 == null) {
- v1 = "";
- }
- if(v2 == null) {
- v2 = "";
- }
- if(v0_1 == null) {
- v0_1 = "";
- }
- if(a.l == null) {
- a.l = "";
- }
- if(!v1.equals("")) {
- v1 = v1.toUpperCase();
- }
- if(!v2.equals("")) {
- v2 = v2.toUpperCase();
- }
- if(!v0_1.equals("")) {
- v0_1 = v0_1.toUpperCase();
- }
- if(!a.l.equals("")) {
- a.l = a.l.toUpperCase();
- }
- if(v1.length() >= v6) {
- v1 = v1.substring(v1.length() - 7);
- }
- if(v2.length() >= v6) {
- v2 = v2.substring(v2.length() - 7);
- }
- if(v0_1.length() >= v6) {
- v0_1 = v0_1.substring(v0_1.length() - 7);
- }
- if(a.l.length() >= v6) {
- a.l = a.l.substring(a.l.length() - 7);
- }
- if(v1.length() != v5 || (this.d(v1))) {
- if(v2.length() == v5 && !this.d(v2)) {
- v0_1 = String.valueOf(v2) + "B";
- goto label_71;
- }
- if(v0_1.length() == v5 && !this.d(v0_1)) {
- v0_1 = String.valueOf(v0_1) + "C";
- goto label_71;
- }
- if(a.l.length() == v5 && !this.d(a.l)) {
- v0_1 = String.valueOf(a.l) + "E";
- goto label_71;
- }
- v0_1 = this.c();
- }
- else {
- v0_1 = String.valueOf(v1) + "A";
- }
- label_71:
- a.o = String.valueOf(v0_1) + "-2414";
- boolean v0_2 = v0_1.length() > 0 ? true : false;
- return v0_2;
- }
复制代码 上面便是注册码的产生计算的过程。继续查看class d 类。
- public static boolean a(String arg3, String arg4) {
- boolean v0 = true;
- a.p = d.a(d.a.a(arg3));
- if(a.p.equals(arg4)) {
- a.q = true;
- }
- else {
- a.q = false;
- v0 = false;
- }
- return v0;
- }
复制代码 其中a.p中保存了真正的注册码,其中深入分析可知a.p实际上也是一个string。
注册机制的分析就到此结束了。
知道了注册机制,下面就让程序把自己的注册码吐出来
打开反编译的文件d.smali,找到如下代码:
- .method public static a(Ljava/lang/String;Ljava/lang/String;)Z
- .locals 3
- const/4 v0, 0x1
- const/4 v1, 0x0
- sget-object v2, Lcom/nfbazi/qimen/a/d;->a:Lcom/nfbazi/qimen/a/b;
- invoke-virtual {v2, p0}, Lcom/nfbazi/qimen/a/b;->a(Ljava/lang/String;)Ljava/lang/String;
- move-result-object v2
- invoke-static {v2}, Lcom/nfbazi/qimen/a/d;->a(Ljava/lang/String;)Ljava/lang/String;
- move-result-object v2
- sput-object v2, Lcom/nfbazi/qimen/a/a;->p:Ljava/lang/String;
- sget-object v2, Lcom/nfbazi/qimen/a/a;->p:Ljava/lang/String;
- invoke-virtual {v2, p1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
- move-result v2
复制代码 这个便是上面的 public static boolean a(String arg3, String arg4)方法,修改如下:
然后打包,签名,允许程序,并注册,其中注册码随便写。
然后在cmd中输入adb logcat -s SN:V
可以得到注册码如下所示:
然后用程序自己吐出来的注册码进行注册,提示注册成功,并可以升级该apk
|
评分
-
参与人数 26 | 威望 +1 |
HB +36 |
THX +18 |
收起
理由
|
猫妖的故事
| |
|
+ 1 |
|
动动
| |
|
+ 1 |
|
24567
| |
|
+ 1 |
|
行行行行行行
| |
|
+ 1 |
|
消逝的过去
| |
|
+ 1 |
|
娄胖胖
| |
+ 1 |
|
|
sjtkxy
| |
+ 1 |
|
|
冷亦飞
| |
+ 1 |
|
|
zxjzzh
| |
|
+ 1 |
[吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少! |
akk1898
| |
|
+ 1 |
[吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩! |
zyyujq
| |
|
+ 1 |
|
xgbnapsua
| |
|
+ 1 |
|
jaunic
| |
+ 2 |
|
|
lies
| |
|
+ 1 |
|
hnymsh
| |
|
+ 1 |
|
mengzhisuoliu1
| |
+ 1 |
|
|
小虫儿
| |
+ 1 |
|
[快捷评语]--你将受到所有人的崇拜! |
a5691409
| |
+ 5 |
+ 1 |
[快捷评语]--评分=感恩!简单却充满爱!感谢您的作品! |
kiaakiaa2
| |
+ 1 |
+ 1 |
[快捷评语] - 吃水不忘打井人,给个评分懂感恩! |
过林黑马
| |
+ 1 |
|
[快捷评语] - 吃水不忘打井人,给个评分懂感恩! |
tony2526
| |
+ 3 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
A00
| |
+ 1 |
|
评分=感恩!简单却充满爱!感谢您的作品! |
Shark恒
| + 1 |
+ 10 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
逍遥枷锁
| |
+ 4 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
雪里红
| |
+ 2 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
寻寻觅觅
| |
+ 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
查看全部评分
|