反编译一款小说阅读软件 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());

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()从整体上。还有其他地方可以去广告的点。看下源代码:

    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)还有就是:

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

进入对应函数:

.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

关键点如下:

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
 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掉呗,恩,这里挖了个坑等大家。整个过程结束了,码字挺辛苦的,各位看官有收获点个赞呗!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容