Sarkozy 发表于 2015-1-30 20:04:00

【手记】秒杀当乐splash启动图

本帖最后由 Sarkozy 于 2015-1-31 13:13 编辑

demo-愤怒的小鸟当乐版下载地址:
http://pan.baidu.com/s/1ntDnlSt

首先反编译,回编译,然后将apk放到模拟器运行,得到如下画面:
是不是看着很不爽,作为游戏发烧友来说,任何延长游戏启动的画面都是在XX游戏!所以就有了本课的目的:去除splash启动图!
用AK神器反编译后,进入入口:

点开java代码查看:

找到oncreate这个函数,函数如下:
public void onCreate(Bundle paramBundle)
{
    super.onCreate(paramBundle);
    this.component = getClassText();
    RelativeLayout localRelativeLayout = new RelativeLayout(this);
    localRelativeLayout.setBackgroundColor(-1);
    ImageView localImageView = new ImageView(this);
    localImageView.setImageBitmap(getAdsImage());
    if ((imageMD5cmp == null) || (imageMD5cmp.length != imageMD5.length))
    {
      finish();
      return;
    }
    for (int i = 0;; i++)
    {
      if (i >= imageMD5.length)
      {
      localImageView.setId(1000);
      RelativeLayout.LayoutParams localLayoutParams = new RelativeLayout.LayoutParams(-2, -2);
      localLayoutParams.addRule(13, -1);
      localImageView.setLayoutParams(localLayoutParams);
      localRelativeLayout.addView(localImageView);
      setContentView(localRelativeLayout);
       start();
      return;
      }
      if (imageMD5cmp != imageMD5)
      {
       finish();
      return;
      }
    }
}

----------------------------------------------------
一般看到函数有判断的时候首先看看判断中的语句
我们可以在上述代码中看到判断中的语句是finish()而后return
而finish函数一般就是结束当前页面的意思,那猜测会不会是结束当前页面直接进入游戏呢?
我们可以从smali中找到相应的调用finish的语句:
invoke-virtual {p0}, Lcom/inject/InjectActivity;->finish()V
我们直接将他插入到定义imageview之前,看一下什么效果
结果模拟器非常不给我面子,闪退了。看来想的跟我不同啊。
那我们继续来看oncreate函数,顺着看,好像发现了什么
对,我们看到了start();函数。
那就可以大致的判断这个什么意思了。大概就是这个启动图专属activity,这个页面结束,那就跳到我们游戏中
大概的思路就是启动start函数,并且结束当前页面。
--------------------------那我们将启动新页面,以及结束当前页面结束这两句调用就好
smali方面的代码,将以下代码插入到定义图片之前(new-instance v2, Landroid/widget/ImageView;):
    invoke-direct {p0}, Lcom/inject/InjectActivity;->start()V

    invoke-virtual {p0}, Lcom/inject/InjectActivity;->finish()V
打包后我们看到的效果是,启动以下,闪退了···诶,不对,又进去了
那么酱紫可以确定一个事情
invoke-direct {p0}, Lcom/inject/InjectActivity;->start()V
是从启动页到游戏的关键,剩下都是渣渣
那么,我们将oncreate函数修改为这样(已经知道思路的那就可以精简代码了)
.method public onCreate(Landroid/os/Bundle;)V
    .locals 8
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;

    .prologue
    const/4 v7, -0x1

    #v7=(Byte);
    const/4 v6, -0x2

    .line 152
    #v6=(Byte);
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    .line 153
    invoke-direct {p0}, Lcom/inject/InjectActivity;->getClassText()[Ljava/lang/String;

    move-result-object v4

    #v4=(Reference,[Ljava/lang/String;);
    iput-object v4, p0, Lcom/inject/InjectActivity;->component:[Ljava/lang/String;

    .line 155
    new-instance v3, Landroid/widget/RelativeLayout;

    #v3=(UninitRef,Landroid/widget/RelativeLayout;);
    invoke-direct {v3, p0}, Landroid/widget/RelativeLayout;-><init>(Landroid/content/Context;)V

    .line 156
    .local v3, "rl":Landroid/widget/RelativeLayout;
    #v3=(Reference,Landroid/widget/RelativeLayout;);
    invoke-virtual {v3, v7}, Landroid/widget/RelativeLayout;->setBackgroundColor(I)V

    invoke-direct {p0}, Lcom/inject/InjectActivity;->start()V

    invoke-virtual {p0}, Lcom/inject/InjectActivity;->finish()V

    return-void   
.end method
----------------------------------------
代码精简过后,我们继续朝着start函数进发,得到如下结果:
private void start()
{
    if (!copyDir()) {
      new Timer().schedule(new MyTask(this.component), 2500L);
    }
}

这里我们明显看到了一个比较显眼的2500L,据我所知,smali中以L为单位的一直都是显示的时间的,没有看到其他的用途


看到时间那就好办了,时间改为一毫秒就好,即将2500L改为1L,那我们定位到smali函数块,修改为如下:


.method private start()V
    .locals 5

    .prologue
    .line 328
    invoke-direct {p0}, Lcom/inject/InjectActivity;->copyDir()Z

    move-result v0

    .line 329
    .local v0, "flag":Z
    #v0=(Boolean);

    .line 330
    new-instance v1, Ljava/util/Timer;

    #v1=(UninitRef,Ljava/util/Timer;);
    invoke-direct {v1}, Ljava/util/Timer;-><init>()V

    .line 331
    .local v1, "timer":Ljava/util/Timer;
    #v1=(Reference,Ljava/util/Timer;);
    new-instance v2, Lcom/inject/InjectActivity$MyTask;

    #v2=(UninitRef,Lcom/inject/InjectActivity$MyTask;);
    iget-object v3, p0, Lcom/inject/InjectActivity;->component:[Ljava/lang/String;

    #v3=(Reference,[Ljava/lang/String;);
    invoke-direct {v2, p0, v3}, Lcom/inject/InjectActivity$MyTask;-><init>(Lcom/inject/InjectActivity;[Ljava/lang/String;)V

    #v2=(Reference,Lcom/inject/InjectActivity$MyTask;);
    const-wide/16 v3, 0x1

    #v3=(LongLo);v4=(LongHi);
    invoke-virtual {v1, v2, v3, v4}, Ljava/util/Timer;->schedule(Ljava/util/TimerTask;J)V

    .line 333
    .end local v1    # "timer":Ljava/util/Timer;

    return-void
.end method
--------------------------------------
修改完了以后,打包,安装,进入游戏,发现没有当乐启动图了呀,好开森!
最后总结一下思路:查看oncreate函数,查找关键调用函数,修改时间长度,[处女座的可以精简一下代码],保存







转载注明出处:pd521.com
逆向未来技术社区,期待您的加入!

海鸥 发表于 2015-1-30 20:40:44

帖子没写完就跑了,支持

sndncel 发表于 2015-1-30 21:06:13

谢谢分享,,,希望抽空写完呀。。。哈哈。

单翅的天使ylj 发表于 2015-1-30 21:11:33

支持了,学习一下{:4_87:}

Promise 发表于 2015-1-30 21:43:56

等更新,楼主LOL加油。

水波摇曳 发表于 2015-1-31 09:45:17

哇槽 发总还没回来,坑人一晚上..

zpdiy08 发表于 2015-1-31 14:06:34

谢谢分享,膜拜学习了!

Sarkozy 发表于 2015-1-31 15:06:40

海鸥 发表于 2015-1-30 20:40
帖子没写完就跑了,支持

写完啦

lies2014 发表于 2015-1-31 15:47:49

谢谢教程,获益良多啊!~

孤久则惯 发表于 2015-8-2 12:01:26

页: [1] 2
查看完整版本: 【手记】秒杀当乐splash启动图