游戏原文件:a.apk
二:去除游戏Zoo Trip中的广告,完美去广告是指删掉程序中一切跟广告调用相关的类,方法,视图
将apk文件拷贝到 d:\android\crack\apktool 目录下,为方便操作,重命名为a.apk
打开cmd窗口
输入:
cd d:\android\crack\apktool
d:
输入:adb devices
检测虚拟设备是否连上,正常的会返回:emulator-5554 device 类似信息
输入:adb install a.apk
在虚拟设备上安装原apk文件,并运行查看效果,先玩一通,看下广告都在哪
广告总共出现在四处:
第一处:程序启动界面
第二处:游戏结束界面(此处有两个广告,中间的那个大的对话框样的为非google广告)
第三处:分数提交界面
第四处:更多游戏界面
接下来我们来看apk文件的内部
输入:apktool d a.apk
反编译apk文件,得到目录a
输入:apktool b a
看文件能否顺利编译回去。
一切正常后,打开 a\build\apk 把里面的classes.dex拷贝到:d:\android\crack\dex 目录下,将文件拖动到dex2jar.bat上面,将自动转成jar文件,然后运行jd-gui.exe,打开刚刚生成的classes.dex.dex2jar.jar,然后会看到对应的java代码,这种方式查看到的代码并不是完整的源码,有很多的出入,仅供参考。
接下来的过程需要很大的耐心与细心,进行以下操作前,请认真学习常用Dalvik指令集(至少要花一天时间),保证能看懂一般的smali代码!!!
打开里面的AndroidManifest.xml文件
找到以
我们首先来删掉主界面的广告
通过AndroidManifest.xml中的描述,我们知道主界面对应的类的名称是:".CoverActivity" 字符"."前面的东西是程序命名空间,在AndroidManifest.xml 中的package="com.droidhen.game.zootrip" 中定义,也就是说主界面的类名是:
com.droidhen.game.zootrip.CoverActivity,所以我们依次展开 smali\com\droidhen\game\zootrip 在里面找到CoverActivity.smali文件并打开,
这里可以看到两个以CoverActivity打头的,其中的CoverActivity$1.smali是CoverActivity中的子类,可以不用看
用编辑器在 smali\com\droidhen 文件夹中查找 GoogleAdView(GoogleAdView这个是google广告的标志)
共找到四个文件:MoreActivity.smali Ad.smali AdController.smali OnlineScoreActivity.smali,都打开
第一个对应的是:更多游戏的界面,第二个只是定义了一个结构,第三个里面出现最多,是广告的实际控制类,第四个是在线排行的界面
接下来回到第一屏的CoverActivity.smali,在里面搜索 AdController
第一处:
Code : .method private tryMore()V .locals 1 .prologue .line 83 sget-object v0, Lcom/droidhen/game/zootrip/global/AdController;->INSTANCE:Lcom/droidhen/game/zootrip/global/AdController; invoke-static {p0, v0}, Lcom/droidhen/activity/MoreHelper;->showMoreGames(Landroid/content/Context;Lcom/droidhen/Ad;)V .line 84 return-void .end method |
Code : package com.droidhen.activity; import com.droidhen.Ad; class MoreHelper{ public static Ad AD; public void showMoreGames(Context context, Ad ad){ Intent intent = new Intent(context, MoreActivity.class); MoreHelper.AD=ad; context.startActivity(intent); } } |
Code :.line 35 sget-object v0, Lcom/droidhen/activity/MoreHelper;->AD:Lcom/droidhen/Ad; |
Code :.line 36 .local v0, ad:Lcom/droidhen/Ad; |
Code : if-eqz v0, :cond_0 .line 37 new-instance v2, Lcom/google/ads/GoogleAdView; invoke-direct {v2, p0}, Lcom/google/ads/GoogleAdView;-> .line 38 .local v2, googleAdView:Lcom/google/ads/GoogleAdView; new-instance v3, Landroid/widget/LinearLayout$LayoutParams; .end local v3 #params:Landroid/widget/LinearLayout$LayoutParams; const/4 v7, -0x2 invoke-direct {v3, v9, v7}, Landroid/widget/LinearLayout$LayoutParams;-> .line 39 .restart local v3 #params:Landroid/widget/LinearLayout$LayoutParams; invoke-virtual {v4, v2, v3}, Landroid/widget/LinearLayout;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V .line 40 invoke-interface {v0, p0, v2, v10}, Lcom/droidhen/Ad;->show(Landroid/app/Activity;Lcom/google/ads/GoogleAdView;Z)V .line 42 .end local v2 #googleAdView:Lcom/google/ads/GoogleAdView; :cond_0 |
Code : .class public Lcom/droidhen/activity/MoreHelper; .super Ljava/lang/Object; .source "MoreHelper.java" # direct methods .method public constructor .locals 0 .prologue .line 8 invoke-direct {p0}, Ljava/lang/Object;-> return-void .end method .method public static showMoreGames(Landroid/content/Context;)V .locals 2 .parameter "context" .prologue .line 12 new-instance v0, Landroid/content/Intent; const-class v1, Lcom/droidhen/activity/MoreActivity; invoke-direct {v0, p0, v1}, Landroid/content/Intent;-> .line 13 .local v0, intent:Landroid/content/Intent; .line 14 invoke-virtual {p0, v0}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V .line 15 return-void .end method |
Code : .method private tryMore()V .locals 1 .prologue .line 83 invoke-static {p0}, Lcom/droidhen/activity/MoreHelper;->showMoreGames(Landroid/content/Context;)V .line 84 return-void .end method |
Code : .line 36 const/4 v1, 0x0 invoke-static {p0, v1}, Lcom/droidhen/game/zootrip/global/AdController;->initAdArea(Landroid/app/Activity;Z)V |
Code : E/AndroidRuntime( 509): FATAL EXCEPTION: main E/AndroidRuntime( 509): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.droidhen.game.zootrip/com.droidhen.game.zootrip.CoverActivity}:java.lang.RuntimeException: Binary XML file line #10: You must supply a layout_width attribute. |
现在开始去除第二屏的广告
首先我们需要知道用户点击 play 按纽时转向的是哪个活动(即Activity)
在上一节中有讲到cover.xml,但没有说怎么找到这个文件的,现在说下:
打开之前的CoverActivity.smali,在其中搜索setContentView,每一个android程序的Activity都必定有一个setContentView方法,setContentView中指定了本活动所使用的布局文件是哪一个。
我们可以看到这样的代码:
Code : .line 30 const/high16 v1, 0x7f03 invoke-virtual {p0, v1}, Lcom/droidhen/game/zootrip/CoverActivity;->setContentView(I)V |
Code : .line 78 new-instance v0, Landroid/content/Intent; const-class v1, Lcom/droidhen/game/zootrip/GameActivity; invoke-direct {v0, p0, v1}, Landroid/content/Intent;-> .line 79 .local v0, intent:Landroid/content/Intent; invoke-virtual {p0, v0}, Lcom/droidhen/game/zootrip/CoverActivity;->startActivity(Landroid/content/Intent;)V |
Code : android.content.Intent intent=new android.content.Intent(this, com.droidhen.game.zootrip.GameActivity.class); startActivity(intent); |
Code : .method more()V .locals 1 .prologue .line 151 sget-object v0, Lcom/droidhen/game/zootrip/global/AdController;->INSTANCE:Lcom/droidhen/game/zootrip/global/AdController; invoke-static {p0, v0}, Lcom/droidhen/activity/MoreHelper;->showMoreGames(Landroid/content/Context;Lcom/droidhen/Ad;)V .line 152 invoke-virtual {p0}, Lcom/droidhen/game/zootrip/GameActivity;->finish()V .line 153 return-void .end method |
Code : .method more()V .locals 1 .prologue .line 151 invoke-static {p0}, Lcom/droidhen/activity/MoreHelper;->showMoreGames(Landroid/content/Context;)V .line 152 invoke-virtual {p0}, Lcom/droidhen/game/zootrip/GameActivity;->finish()V .line 153 return-void .end method |
Code :invoke-static {p0, v4}, Lcom/droidhen/game/zootrip/global/AdController;->initAdArea(Landroid/app/Activity;Z)V |
Code : .line 57 const/high16 v2, 0x7f07 invoke-static {p0, v2, v4}, Lcom/droidhen/score/ScoreUtil;->showView(Landroid/app/Activity;IZ)V |
Code : .line 112 const/high16 v1, 0x7f07 const/4 v2, 0x1 invoke-static {p0, v1, v2}, Lcom/droidhen/score/ScoreUtil;->showView(Landroid/app/Activity;IZ)V |
第三处:方法submit
Code : .method submit()V .locals 4 .prologue .line 158 sget-object v0, Lcom/droidhen/game/zootrip/global/AdController;->INSTANCE:Lcom/droidhen/game/zootrip/global/AdController; const/4 v1, 0x1 sget-object v2, Lcom/droidhen/game/zootrip/GameActivity;->server:Ljava/lang/String; const/4 v3, 0x0 invoke-static {p0, v0, v1, v2, v3}, Lcom/droidhen/score/ScoreUtil;->redirectToSubmit(Landroid/app/Activity;Lcom/droidhen/Ad;ZLjava/lang/String;Z)V .line 159 return-void .end method |
Code : .method public static redirectToSubmit(Landroid/app/Activity;Lcom/droidhen/Ad;ZLjava/lang/String;Ljava/lang/String;ZZ)V .locals 2 .parameter "activity" .parameter "ad" .parameter "finishSelf" .parameter "server" .parameter "category" .parameter "asc" .parameter "isFloat" .prologue .line 60 invoke-static {p1}, Lcom/droidhen/score/OnlineScoreActivity;->setAdController(Lcom/droidhen/Ad;)V .line 61 new-instance v0, Landroid/content/Intent; const-class v1, Lcom/droidhen/score/OnlineScoreActivity; invoke-direct {v0, p0, v1}, Landroid/content/Intent;-> .line 62 .local v0, intent:Landroid/content/Intent; const-string v1, "server" invoke-virtual {v0, v1, p3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent; .line 63 const-string v1, "category" invoke-virtual {v0, v1, p4}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent; .line 64 const-string v1, "asc" invoke-virtual {v0, v1, p5}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Z)Landroid/content/Intent; .line 65 const-string v1, "float" invoke-virtual {v0, v1, p6}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Z)Landroid/content/Intent; .line 66 invoke-virtual {p0, v0}, Landroid/app/Activity;->startActivity(Landroid/content/Intent;)V .line 67 if-eqz p2, :cond_0 .line 68 invoke-virtual {p0}, Landroid/app/Activity;->finish()V .line 70 :cond_0 return-void .end method |
Code : .method public static redirectToSubmit(Landroid/app/Activity;Lcom/droidhen/Ad;ZLjava/lang/String;Z)V .locals 7 .parameter "activity" .parameter "ad" .parameter "finishSelf" .parameter "server" .parameter "asc" .prologue .line 55 const-string v4, "0" const/4 v6, 0x0 move-object v0, p0 move-object v1, p1 move v2, p2 move-object v3, p3 move v5, p4 invoke-static/range {v0 .. v6}, Lcom/droidhen/score/ScoreUtil;->redirectToSubmit(Landroid/app/Activity;Lcom/droidhen/Ad;ZLjava/lang/String;Ljava/lang/String;ZZ)V .line 56 return-void .end method |
Code : .method public static redirectToSubmit(Landroid/app/Activity;ZLjava/lang/String;Ljava/lang/String;ZZ)V .locals 2 .parameter "activity" .parameter "finishSelf" .parameter "server" .parameter "category" .parameter "asc" .parameter "isFloat" .prologue .line 61 new-instance v0, Landroid/content/Intent; const-class v1, Lcom/droidhen/score/OnlineScoreActivity; invoke-direct {v0, p0, v1}, Landroid/content/Intent;-> .line 62 .local v0, intent:Landroid/content/Intent; const-string v1, "server" invoke-virtual {v0, v1, p2}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent; .line 63 const-string v1, "category" invoke-virtual {v0, v1, p3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent; .line 64 const-string v1, "asc" invoke-virtual {v0, v1, p4}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Z)Landroid/content/Intent; .line 65 const-string v1, "float" invoke-virtual {v0, v1, p5}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Z)Landroid/content/Intent; .line 66 invoke-virtual {p0, v0}, Landroid/app/Activity;->startActivity(Landroid/content/Intent;)V .line 67 if-eqz p2, :cond_0 .line 68 invoke-virtual {p0}, Landroid/app/Activity;->finish()V .line 70 :cond_0 return-void .end method |
Code : .method public static redirectToSubmit(Landroid/app/Activity;ZLjava/lang/String;Z)V .locals 7 .parameter "activity" .parameter "finishSelf" .parameter "server" .parameter "asc" .prologue .line 55 const-string v3, "0" const/4 v5, 0x0 move-object v0, p0 move v1, p1 move-object v2, p2 move v4, p3 invoke-static/range {v0 .. v5}, Lcom/droidhen/score/ScoreUtil;->redirectToSubmit(Landroid/app/Activity;ZLjava/lang/String;Ljava/lang/String;ZZ)V .line 56 return-void .end method |
Code : .method submit()V .locals 4 .prologue .line 158 const/4 v1, 0x1 sget-object v2, Lcom/droidhen/game/zootrip/GameActivity;->server:Ljava/lang/String; const/4 v3, 0x0 invoke-static {p0, v1, v2, v3}, Lcom/droidhen/score/ScoreUtil;->redirectToSubmit(Landroid/app/Activity;ZLjava/lang/String;Z)V .line 159 return-void .end method |
接下来,我们检查下游戏结束界面的几个按纽点击是否正常
点击 submit 提交分数时程序报了异常
还是用adb logcat来查看具体错误
关于如何使用adb logcat定位错误:
CMD窗口输入adb logcat后,待窗口文字滚动速度慢下来时(大概一秒一行),按下ctrl+c,停止logcat,然后滚动鼠标查找最后一个:Shutting down VM
在这行下面就能找到具体错误
这次的错误是:
Code : E/AndroidRuntime( 244): FATAL EXCEPTION: main E/AndroidRuntime( 244): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.droidhen.game.zootrip/com.droidhen.score.OnlineScoreActivity}: java.lang.RuntimeException: Binary XML file line #49: You must supply a layout_width attribute. |
Code : |
Code : |
Code : |
Code :android:layout_height="wrap_content" android:layout_width="wrap_content" |
Code :.field private static adController:Lcom/droidhen/Ad; |
Code : .line 111 const/high16 v1, 0x7f07 invoke-virtual {p0, v1}, Lcom/droidhen/score/OnlineScoreActivity;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Lcom/google/ads/GoogleAdView; .line 112 .local v0, adView:Lcom/google/ads/GoogleAdView; sget-object v1, Lcom/droidhen/score/OnlineScoreActivity;->adController:Lcom/droidhen/Ad; if-eqz v1, :cond_0 .line 113 sget-object v1, Lcom/droidhen/score/OnlineScoreActivity;->adController:Lcom/droidhen/Ad; const/4 v2, 0x0 invoke-interface {v1, p0, v0, v2}, Lcom/droidhen/Ad;->show(Landroid/app/Activity;Lcom/google/ads/GoogleAdView;Z)V |
Code : GoogleAdView adView=(GoogleAdView)findViewById(0x7f070000); if(this.adController!=null){ this.adController.show(this,adView,false); } |
Code : |
Code : .line 38 invoke-static {p0}, Lcom/droidhen/recommend/RecommendUtil;->fetch(Landroid/content/Context;)V |
Code : .line 113 invoke-static {p0}, Lcom/droidhen/recommend/RecommendUtil;->show(Landroid/content/Context;)V |
Code : .line 37 invoke-static {p0}, Lcom/droidhen/game/zootrip/global/TrackUtil;->track(Landroid/content/Context;)V |
Code : .line 43 invoke-static {}, Lcom/droidhen/game/zootrip/global/TrackUtil;->stopTrack()V |
最后我们可以修改一下smali中的那个显示更多游戏的方法,使用户点击more按纽时直接打开地瓜游戏
将MoreHelper.smali中的如下代码:
Code : .method public static showMoreGames(Landroid/content/Context;)V .locals 2 .parameter "context" .prologue .line 12 new-instance v0, Landroid/content/Intent; const-class v1, Lcom/droidhen/activity/MoreActivity; invoke-direct {v0, p0, v1}, Landroid/content/Intent;-> .line 13 .local v0, intent:Landroid/content/Intent; .line 14 invoke-virtual {p0, v0}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V .line 15 return-void .end method |
Code : .method public static showMoreGames(Landroid/content/Context;)V .locals 3 .parameter "context" .prologue .line 12 new-instance v0, Landroid/content/Intent; const-string v1, "android.intent.action.VIEW" invoke-direct {v0, v1}, Landroid/content/Intent;-> .line 13 .local v0, i:Landroid/content/Intent; const-string v1, "com.diguayouxi" const-string v2, "com.diguayouxi.activity.BackGroundActivity" invoke-virtual {v0, v1, v2}, Landroid/content/Intent;->setClassName(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent; .line 14 invoke-virtual {p0, v0}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V .line 15 return-void .end method |
Code : .method public static showMoreGames(Landroid/content/Context;)V .locals 7 .parameter "context" .prologue const-string v6, "android.intent.action.VIEW" .line 12 :try_start_0 new-instance v1, Landroid/content/Intent; const-string v4, "android.intent.action.VIEW" invoke-direct {v1, v4}, Landroid/content/Intent;-> .line 13 .local v1, i:Landroid/content/Intent; const-string v4, "com.diguayouxi" const-string v5, "com.diguayouxi.activity.BackGroundActivity" invoke-virtual {v1, v4, v5}, Landroid/content/Intent;->setClassName(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent; .line 14 invoke-virtual {p0, v1}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V :try_end_0 .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0 .line 18 .end local v1 #i:Landroid/content/Intent; :goto_0 return-void .line 15 :catch_0 move-exception v4 move-object v0, v4 .line 16 .local v0, e:Ljava/lang/Exception; const-string v4, "http://a.d.cn" invoke-static {v4}, Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri; move-result-object v3 .line 17 .local v3, uri:Landroid/net/Uri; new-instance v2, Landroid/content/Intent; const-string v4, "android.intent.action.VIEW" invoke-direct {v2, v6, v3}, Landroid/content/Intent;-> .line 18 .local v2, intent:Landroid/content/Intent; invoke-virtual {p0, v2}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V goto :goto_0 .end method |