undefined
最近和朋友聊天,发现一些灰色产业链通过批量反编译市场上的 apk,然后进行注入广告,再重新打包上渠道。
undefined
我想大家都不希望自己家的产品或者自己的 app 那么容易被 "占据",但是想要自身能够防御,首先要知道对方的手段。所以本篇博客的目的不是教大家如何破解别人的 app,而是让大家提升安全防御意识,对我们的应用做一些必要的防护,让自己的 app 不会那么容易被 "占领"。
undefined
因为是初探,也不需要掌握太多的技术,主要是各种工具的使用了~~
undefined
undefined
几个重要的工具,注意使用最新版本。
undefined
相信就是为了学习,大家或多或少都使用过上述几个工具了:
undefined
undefined
如果没有的话,自行下载,尽可能的下载最新版本。
undefined
题目是注入广告,那么我们选择一类广告注入,大多数 app 都有闪屏广告,那么我们就模拟:反编译一个 apk,加入我们的闪屏广告页,然后重新打包。
undefined
undefined
首先需要准备一个 apk,我们随便写一个简单的 demo。
undefined
- package com.zhy.decompile;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- public class MainActivity extends AppCompatActivity {@Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- }
undefined
undefined
app 的样子是这样的,凑合截个图,据说没图不利于阅读。
undefined
然后点击 run,拿 debug 的 apk 就可以,当然不嫌麻烦可以自己签名拿个混淆的 apk,也可以随便下载一个小众的 app。
undefined
undefined
- . / apktool d app.apk
undefined
undefined
其中 res 目录为资源目录,smali 目录下可以认为是源码目录,不过都是对应的 smali 文件。
undefined
如果你对 smali 的语法比较清晰,可以直接在代码中添加逻辑。
undefined
我们这里就算了,不过我们这里可以打开 res 目录,找到 activity_main 的布局文件,然后修改里面的字符串为:
,这里自己玩。
- This is hacked app!
undefined
对了,我们要注入闪屏广告。
undefined
思考下,闪屏广告我们可以用 Activity 来呈现,那么我有个思路是这样的步骤:
undefined
undefined
那就搞定了。
undefined
好像有什么不对的地方,我们这里的源码都是 smali 格式的,那么闪屏页的 Activity 我只会 java 呀,这怎么转化,有什么大力出奇迹的工具么?
undefined
恩,还真有。
undefined
工具就是 Android Studio,开个玩笑,虽然我们不会,但是我们知道 smali 文件可以反编译生成,那么我们可以查看反编译 apk 的包名,然后我们新建一个 app,在相同的包名下编写一个闪屏页 Activity,然后打包成 apk。把这个 apk 再反编译,提取出闪屏页对应的 Smali 文件,粘贴到被反编译 apk 的目录不就好了么。
undefined
undefined
内容如下:
undefined
- package com.zhy.decompile;
- public class HackAdActivity extends AppCompatActivity {
- private Handler mHandler = new Handler(Looper.getMainLooper());
- private Runnable mCallback = new Runnable() {@Override public void run() {
- Intent intent = new Intent();
- intent.setComponent(new ComponentName("com.zhy.decompile", "com.zhy.decompile.MainActivity"));
- startActivity(intent);
- }
- };@Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mHandler.postDelayed(mCallback, 3000);
- }@Override protected void onDestroy() {
- super.onDestroy();
- mHandler.removeCallbacks(mCallback);
- }
- }
undefined
注意包名一定要和原包名一致 & 先不要使用到布局文件,后面会说~~
undefined
然后提取出 apk,重新进行上面的操作,取到 Smali 文件。
undefined
undefined
注意我们的编写方式包含内部类,两个一起 copy 到反编译 app 的目录。
undefined
然后打开 AndroidManifest.xml 修改入口 Activity…
undefined
undefined
可以看到入口 Activity 改为我们新建的 Activity 了,原来的入口 Activity 切换为普通 Activity 了。
undefined
到这里,我们的文件就修改完毕了。
undefined
然后我们重新打包,与其打包之后的 apk,还可以安装,安装后启动首先是闪屏广告页,然后才是原来的页面。
undefined
那接下来就是打包了~~
undefined
undefined
- . / apktool b apk1127 - o app1127_new.apk
undefined
- . / apktool b apk1127 - o app1127_new.apk I: Using Apktool 2.2.0 I: Checking whether sources has changed...I: Smaling smali folder into classes.dex...W: Unknown file type,
- ignoring: apk1127 / smali / .DS_Store W: Unknown file type,
- ignoring: apk1127 / smali / com / .DS_Store W: Unknown file type,
- ignoring: apk1127 / smali / com / zhy / .DS_Store I: Checking whether resources has changed...I: Building resources...I: Building apk file...I: Copying unknown files / dir...
undefined
ok,打包成功后,可以看到一个新的 app1127_new.apk。
undefined
这个 apk 现在是无法安装的,安装后出现下图结果:
undefined
undefined
主要是因为没有签名。
undefined
那么接下来就开始签名吧~
undefined
undefined
签名的话,我们需要一个签名文件,我们一起来新生成下。
undefined
- keytool - genkey - alias zhy.keystore - keyalg RSA - validity 20000 - keystore zhy.keystore
undefined
然后按照提示往下输入即可。
undefined
当然如果你嫌命令太难记,你也可以利用 Android Studio 进行可视化生成一个:
undefined
点击 Build:
undefined
undefined
undefined
选择 create New,然后在弹出面板填写就行了,你肯定会填。
undefined
有了 keystore 之后呢,我们可以利用新生成的 keystore 来签名我们刚才 hack 的 apk。
undefined
- jarsigner - verbose - sigalg SHA1withRSA - digestalg SHA1 - keystore zhy.keystore - storepass 123456 app1127_new.apk zhy.keystore
undefined
记得上述代码弄成一行去执行:
undefined
上面的 options 其实并不多,文件路径,密码,别名呀什么的,应该可以看明白,有兴趣可以详细的搜索下相关文件。
undefined
签名完成之后一般就可以安装了,不过我们一般还会做一个对齐操作。
undefined
undefined
- zipalign 4 app1127_new.apk app1127_new_align.apk
undefined
此刻运行:
undefined
undefined
原本只有一个页面,可以看到现在被我们注入了一个
的页面。
- I am ad
undefined
当然了,如果你是一路模拟过来的,因为前面说了,先不要使用资源,所以你应该能看出页面的跳转,但是并 Ad 页面并没有布局文件。
undefined
下面我们来说使用布局文件。
undefined
undefined
HackAdActivity 中添加一行:
undefined
- setContentView(R.layout.ad);
undefined
还是刚才的活,重新反编译 copy Smali 文件,并且把 ad 这个 layout 复制到想要注入的 app 的反编译后的文件夹中。
undefined
然后是不是打包就好了呢?
undefined
当然不是,如果是,刚才就直接说好了。我们在写代码的时候,都知道会生成一个 R.layout.ad,那么这个值,在原本的 app 里面肯定是没有的(不考虑重名情况)。
undefined
所以,我们需要手动加入进去:
undefined
打开
文件:
- R$layout.smali
undefined
undefined
我们在最后添加一个 ad 的资源 id:
undefined
- .field public static final ad: I = 0x7f04002e
undefined
然后保存退出。
undefined
别急着打包…
undefined
这里定义完了,我们的 HackAdActivity.smali 中还需要修改呢。
undefined
你别说 smali 文件里面我看不懂怎么改?
undefined
改个 id 还是可以的。
undefined
undefined
找到 setContentView 前一行,是不是还蛮容易定位的。
undefined
改完之后,重新打包、签名、对齐就 ok 了~~
undefined
如果你使用了更多的资源,记得基本都要处理。
undefined
undefined
那么到这里就完成了反编译一个 apk,然后往里面注入一个新的 Activity 并且可以自定义这个布局文件,至于这个 Activity 能看什么事大家肯定都明白。
undefined
但是,但是,我们的目的并不是让大家去反编译人家的 apk,而是知道我们的 apk 能够被别人这么玩。
undefined
所以要思考的是:
undefined
- 如何预防这种行为呢?欢迎留言说说如何预防?
undefined
未完待续…
undefined
欢迎关注我的微博:
undefined
微信公众号:hongyangAndroid
(欢迎关注,不要错过每一篇干货,支持投稿)
来源: http://www.tuicool.com/articles/UjYV3ma