前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >反编译一款小说阅读软件 android逆向(三)

反编译一款小说阅读软件 android逆向(三)

作者头像
用户1127566
发布2018-06-04 17:58:57
1.6K0
发布2018-06-04 17:58:57
举报
文章被收录于专栏:Android 开发学习Android 开发学习

声明下,本文的内容仅用于技术讨论,不涉及到商业用途,如果用于商业用途请自行负责。

1 背景

最近无聊时,就去追小说玩,想使用免费的小说阅读软件,下载的时候阅读发现有Banner广告,这里多一句嘴,怎么实现bannner广告呢?(歪楼了,不过我想记录下,因为最近就用到过这个小的技巧,下一部分会提到)。继续说banner广告,特别烦,我司的app去年前的也是靠这个赚钱,去年年底考虑到用户体验就撤了,原因和我使用这个小说阅读软件类似,就是特别烦!!!

2 banner广告实现

貌似自己给自己挖坑。原理很简单,就是在 DecorView上添加view,因为该view是FrameLayout,故添加时,就在整个view的上层。这里再次歪下楼,android的几大布局中具有层次结构的FrameLayout, 还有个隐藏比较深的RelativeLayout,做动画的时候,奇葩的产品会有不同层次的设计。代码呢,请参考:http://blog.csdn.net/goodding/article/details/8562985

这里给最主要的一句,中间省略细节处理。

addFloatView((FrameLayout) getWindow().getDecorView());

代码语言:javascript
复制
private void addFloatView(FrameLayout parent) {
        if (mFloatView == null || (mFloatView.getParent() == null)) {
            if (!mIsAdded) {
                initFloatView();
                FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                parent.addView(mFloatView,lp);
                mIsAdded = true;
            }
        }

    }

很简单,就是拿到DecorView,然后在其上添加相应布局,于是这里就可以实现浮层引导页面,还有就是应用内悬浮窗口了,叨叨完。

3 正式进入反编译

再次重复使用我上篇提到的工具,http://www.jianshu.com/p/d57c542b5949

这里我也介绍下,还有个反编译工具---jadx,这个阅读反编译出来的代码后,显示得到源代码,比较清晰,不像android killer 反编译后,查看源代码的jd 工具,代码条理较乱。怎么导入,本文省略,不了解请参考上篇。我们来看下,整个工程使用android killer 查看运行图如下:

Paste_Image.png

看软件文件名就能猜到是哪家公司了,这里补一句,个人开发的小伙伴找不到图,就可以直接反编译下软件,在res资源下就是图片资源了,恩,注意这里仅仅是技术讨论。

1 这个软件用了哪些三方技术呢?

a 一看 alipay 你猜。

b baidu的

c google的是gson我这里不好截图,包太多了。

d multipletheme 这个就是切换主题的三方包,实现换肤功能。(感兴趣的小伙伴,可以详细阅读下这里)

e 还有就是侧滑的三方了,slidingmenu

f sina和qq的一看就是三方登录和分享了

Paste_Image.png

2. 自己的技术呢?

Paste_Image.png

恩,看文件,就知道ecom下面是广告,users下面是用户统计和crash分析等。reader就是该软件的工程主体代码部分。由于采用了混淆,故有些文件名称无法猜出。整体上看,软件的工程不是特别大,按照Android的一贯分层模式来划分包的。

4 去广告

终于来到我的目的地,去广告。这里吐血大放送,一个技巧。如何快速定位一个apk的界面。作为新人,我刚进公司要废很大劲找到对应的代码,最长达1个小时(我司工程项目较大,已经分包)。这里我提供两个简单的方法。

1 命令行形式

使用adb 命令行,需要简单配置下。 将adb调试下apk,进入想要查找的应用程序界面,然后cmd中输入adb shell。最后输入,以下的几个都可以:

a. 查看当前resume的是哪个activity: dumpsys activity | grep mResumedActivity

b.resume的Activity dumpsys activity | grep mFocusedActivity

c. 焦点view

adb shell dumpsys window windows | grep -E 'mCurrentFocus'

Paste_Image.png

2 快速查找法

找到对应的关键词,找能代表该界面的关键词,这个点是逆向去广告,去支付的很常用方法。本文软件界面,除去广告提示词外,还有就是点击小说的中间位置时的工具栏里面的关键字。一个直接在android studio中查找(eclipse类似),另外一个是上篇提到的反编译工具中查找。

Paste_Image.png

3正式进入去广告的activity---ActNovel

恩,这里顺便说一下,貌似开发人员命名很不规范,至少让我们这种不知道源码的阅读起来不方便,很严肃的事hao吗?

点击java源码的那个图标,进入jd 查看源码。

Paste_Image.png

这里叨叨下,使用jadx的查看源码,大家感受下。

Paste_Image.png

查找关键函数

看jadx上的截图,程序猿大哥这次写的很明白呀。恩,有人一定会问,那万一遇到不能猜出来的怎么办呢?很简单,使用本文提到的快速定位法,比如,本文想去掉这个页面广告,点击×,看弹出的窗口提示文字,快速反定位到函数。当然本文去广告的点很多,jadx上的是addAdsView()从整体上。还有其他地方可以去广告的点。看下源代码:

代码语言:javascript
复制
    private void addAdsView() {
        if (com.esbook.reader.a.a.E != 0 && !this.isClosed) {
            this.isAdShowing = true;
            this.adContainer.removeAllViews();
            if (this.easouAdUtils == null) {
                this.easouAdUtils = new bo(getApplicationContext(), this, this.adContainer, com.esbook.reader.a.a.L, com.esbook.reader.a.a.K, MSG_LOAD_NEXT_CHAPTER);
                this.easouAdUtils.a(new ca(this));
                this.easouAdUtils.a(new cb(this));
            } else {
                this.easouAdUtils.a(this.adContainer, this.easouAdUtils.b());
            }
            if (this.ad_coverview == null) {
                this.ad_coverview = new View(getApplicationContext());
                this.ad_coverview.setBackgroundColor(getResources().getColor(R.color.transparent_ad));
            }
            ViewGroup viewGroup = (ViewGroup) this.ad_coverview.getParent();
            if (viewGroup != null) {
                viewGroup.removeAllViews();
            }
            this.adContainer.addView(this.ad_coverview, new LayoutParams(-1, -1));
            if (com.esbook.reader.a.a.j == MSG_LOAD_PRE_CHAPTER || com.esbook.reader.a.a.j == MSG_CHANGE_SOURCE || com.esbook.reader.a.a.j == ERROR) {
                showAdCover(true);
            } else {
                showAdCover(false);
            }
        }
    }

想去广告点很多呀,

(1)从一开始就return,不添加。

(2)还有就是:

代码语言:javascript
复制
if (com.esbook.reader.a.a.j == MSG_LOAD_PRE_CHAPTER || com.esbook.reader.a.a.j == MSG_CHANGE_SOURCE || com.esbook.reader.a.a.j == ERROR) {
                showAdCover(true);
            } else {
                showAdCover(false);
            }

都showAdCover(false)

(3) showAdCover函数里面不显示广告也可以。

ok,来找到smali源代码。

Paste_Image.png

进入对应函数:

代码语言:javascript
复制
.method private addAdsView()V
    .locals 9

    const/4 v8, -0x1

    const/4 v7, 0x1

    sget v0, Lcom/esbook/reader/a/a;->E:I

    if-eqz v0, :cond_0

    iget-boolean v0, p0, Lcom/esbook/reader/activity/ActNovel;->isClosed:Z

    if-eqz v0, :cond_1

    :cond_0
    :goto_0
    return-void

    :cond_1
    iput-boolean v7, p0, Lcom/esbook/reader/activity/ActNovel;->isAdShowing:Z

    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->adContainer:Landroid/widget/RelativeLayout;

    invoke-virtual {v0}, Landroid/widget/RelativeLayout;->removeAllViews()V

    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    if-nez v0, :cond_5

    new-instance v0, Lcom/esbook/reader/util/bo;

    invoke-virtual {p0}, Lcom/esbook/reader/activity/ActNovel;->getApplicationContext()Landroid/content/Context;

    move-result-object v1

    iget-object v3, p0, Lcom/esbook/reader/activity/ActNovel;->adContainer:Landroid/widget/RelativeLayout;

    sget v4, Lcom/esbook/reader/a/a;->L:I

    sget v5, Lcom/esbook/reader/a/a;->K:I

    const/4 v6, 0x2

    move-object v2, p0

    invoke-direct/range {v0 .. v6}, Lcom/esbook/reader/util/bo;-><init>(Landroid/content/Context;Landroid/app/Activity;Landroid/widget/RelativeLayout;III)V

    iput-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    new-instance v1, Lcom/esbook/reader/activity/ca;

    invoke-direct {v1, p0}, Lcom/esbook/reader/activity/ca;-><init>(Lcom/esbook/reader/activity/ActNovel;)V

    invoke-virtual {v0, v1}, Lcom/esbook/reader/util/bo;->a(Lcom/esbook/reader/util/bq;)V

    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    new-instance v1, Lcom/esbook/reader/activity/cb;

    invoke-direct {v1, p0}, Lcom/esbook/reader/activity/cb;-><init>(Lcom/esbook/reader/activity/ActNovel;)V

    invoke-virtual {v0, v1}, Lcom/esbook/reader/util/bo;->a(Lcom/esbook/reader/util/bs;)V

    :goto_1
    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->ad_coverview:Landroid/view/View;

    if-nez v0, :cond_2

    new-instance v0, Landroid/view/View;

    invoke-virtual {p0}, Lcom/esbook/reader/activity/ActNovel;->getApplicationContext()Landroid/content/Context;

    move-result-object v1

    invoke-direct {v0, v1}, Landroid/view/View;-><init>(Landroid/content/Context;)V

    iput-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->ad_coverview:Landroid/view/View;

    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->ad_coverview:Landroid/view/View;

    invoke-virtual {p0}, Lcom/esbook/reader/activity/ActNovel;->getResources()Landroid/content/res/Resources;

    move-result-object v1

    const v2, 0x7f090013

    invoke-virtual {v1, v2}, Landroid/content/res/Resources;->getColor(I)I

    move-result v1

    invoke-virtual {v0, v1}, Landroid/view/View;->setBackgroundColor(I)V

    :cond_2
    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->ad_coverview:Landroid/view/View;

    invoke-virtual {v0}, Landroid/view/View;->getParent()Landroid/view/ViewParent;

    move-result-object v0

    check-cast v0, Landroid/view/ViewGroup;

    if-eqz v0, :cond_3

    invoke-virtual {v0}, Landroid/view/ViewGroup;->removeAllViews()V

    :cond_3
    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->adContainer:Landroid/widget/RelativeLayout;

    iget-object v1, p0, Lcom/esbook/reader/activity/ActNovel;->ad_coverview:Landroid/view/View;

    new-instance v2, Landroid/widget/RelativeLayout$LayoutParams;

    invoke-direct {v2, v8, v8}, Landroid/widget/RelativeLayout$LayoutParams;-><init>(II)V

    invoke-virtual {v0, v1, v2}, Landroid/widget/RelativeLayout;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V

    sget v0, Lcom/esbook/reader/a/a;->j:I

    if-eq v0, v7, :cond_4

    sget v0, Lcom/esbook/reader/a/a;->j:I

    const/4 v1, 0x4

    if-eq v0, v1, :cond_4

    sget v0, Lcom/esbook/reader/a/a;->j:I

    const/4 v1, 0x7

    if-ne v0, v1, :cond_6

    :cond_4   
    invoke-direct {p0, v7}, Lcom/esbook/reader/activity/ActNovel;->showAdCover(Z)V

    goto :goto_0

    :cond_5
    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    iget-object v1, p0, Lcom/esbook/reader/activity/ActNovel;->adContainer:Landroid/widget/RelativeLayout;

    iget-object v2, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    invoke-virtual {v2}, Lcom/esbook/reader/util/bo;->b()I

    move-result v2

    invoke-virtual {v0, v1, v2}, Lcom/esbook/reader/util/bo;->a(Landroid/widget/RelativeLayout;I)V

    goto :goto_1

    :cond_6
    const/4 v0, 0x0

    invoke-direct {p0, v0}, Lcom/esbook/reader/activity/ActNovel;->showAdCover(Z)V

    goto/16 :goto_0
.end method

关键点如下:

代码语言:javascript
复制
sget v0, Lcom/esbook/reader/a/a;->E:I

    if-eqz v0, :cond_0

    iget-boolean v0, p0, Lcom/esbook/reader/activity/ActNovel;->isClosed:Z

    if-eqz v0, :cond_1

    :cond_0
代码语言:javascript
复制
 if-eq v0, v1, :cond_4

    sget v0, Lcom/esbook/reader/a/a;->j:I

    const/4 v1, 0x7

    if-ne v0, v1, :cond_6

    :cond_4   
    invoke-direct {p0, v7}, Lcom/esbook/reader/activity/ActNovel;->showAdCover(Z)V

    goto :goto_0

    :cond_5
    iget-object v0, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    iget-object v1, p0, Lcom/esbook/reader/activity/ActNovel;->adContainer:Landroid/widget/RelativeLayout;

    iget-object v2, p0, Lcom/esbook/reader/activity/ActNovel;->easouAdUtils:Lcom/esbook/reader/util/bo;

    invoke-virtual {v2}, Lcom/esbook/reader/util/bo;->b()I

    move-result v2

    invoke-virtual {v0, v1, v2}, Lcom/esbook/reader/util/bo;->a(Landroid/widget/RelativeLayout;I)V

    goto :goto_1

    :cond_6
    const/4 v0, 0x0

    invoke-direct {p0, v0}, Lcom/esbook/reader/activity/ActNovel;->showAdCover(Z)V

    goto/16 :goto_0

对着源代码,还是很容易阅读。 怎么去,简单的nop掉呗,恩,这里挖了个坑等大家。整个过程结束了,码字挺辛苦的,各位看官有收获点个赞呗!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.05.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 背景
  • 2 banner广告实现
  • 3 正式进入反编译
    • 1 这个软件用了哪些三方技术呢?
      • 2. 自己的技术呢?
      • 4 去广告
        • 1 命令行形式
          • 2 快速查找法
            • 3正式进入去广告的activity---ActNovel
              • 查找关键函数
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档