本帖最后由 Mycool 于 2014-10-26 17:24 编辑
前面写过一篇去广告的帖子,里面提到了去除软件启动界面的方法。
但是当时是怎么去除的,原理是什么,我自己也不清楚。
这几天正在学习基础知识,忍不住又重新反编译看了下,找到了一种可以解释清楚的方法。
app是球探的手机比分客户端
软件在启动的时候会加载启动界面,但是这个是广告,如果点击的话就启动本机的彩客软件,本机没有的话就会启动下载。很流氓。
见图:
我们打开改之理反编译,首先打开配置文件AndroidManifest.xml
看程序第一个启动的activity。
然后我们打开这个activity对应的smali文件SplashScreenActivity.smali
点击工具栏的咖啡杯图标,启动JD_GUI阅读逆向出来的java源码
如图:
启动后如图:
我们可以看到,这个启动界面SplashScreenActivity继承了activity类,启动初始代码如下:
- public void onCreate(Bundle paramBundle)
- {
- super.onCreate(paramBundle);
- getApplication();
- requestWindowFeature(1);
- if (an.a())
- {
- a locala = b();
- if (locala != null)
- {
- setContentView(2130903365);
- this.a = ((Button)findViewById(2131166268));
- this.b = ((ImageView)findViewById(2131165223));
- a(locala);
- }
- }
- this.e.sendEmptyMessageDelayed(1401201108, this.c);
- an.f("Splash onCreate ");
- }
复制代码 活动启动时,有个嵌套的条件语句if,条件成立后,就用setContentView把启动界面的内容显示出来,有朋友问了,你怎么知道这个setContentView设置的是启动的广告界面呢?好的,我们可以用setContentView(2130903365);中的数字,转换成十六进制,去public.xml文件中找到对应的布局文件,打开一看,果然是启动时的广告界面。
显示过广告界面以后,会延时一段时间,然后启动真正的程序主界面。这里要用到StartActivity方法。
我们搜索StartActivity,发现代码如下:
- private void a()
- {
- Intent localIntent = new Intent();
- localIntent.setFlags(67108864);
- localIntent.setClass(this, Score_MainActivity.class);
- startActivity(localIntent);
- finish();
- }
复制代码 这里定义了一个a()方法,他的作用就是发送一个启动Activity的意图,并结束掉自身。这里启动的Activity就是主界面的Activity即Score_MainActivity。
那么我们在上面的if条件执行前,先调用这个a()方法,不就可以跳过启动界面显示了么?
是的,就这么简单。如何修改代码来实现呢?这里需要修改smali代码。
调用a()方法的smali代码应该是怎么样的呢?我也不知道,因为不懂这个语法啊。我们继续在反编译的java源码中阅读:
- protected void onResume()
- {
- super.onResume();
- if (this.d)
- a();
- }
复制代码
可以看到,这个onResume方法调用了a()方法,Ok,我们去找这个调用方法对应的smali代码,拷贝出来。
经过对比分析,可以确定这样的一句smali代码可以实现调用方法的过程:
- invoke-direct {p0}, Lcom/bet007/mobile/score/activity/main/SplashScreenActivity;->a()V
复制代码 OK,我们将其粘贴到上面onCreate启动代码之中,放在if语句之前:
那么好了。程序还没来得及判断是不是满足条件来显示启动界面的广告,我们就结束掉这个activity并启动主界面activity了。
编译运行。去除启动界面的目的完美达到。
|