qintangtao 发表于 2017-12-15 16:36

MIUI9绕开联网和插卡打开未知来源

本帖最后由 qintangtao 于 2017-12-16 09:51 编辑

严重声明
本文的意图只有一个就是通过分析学习更多的逆向技术,如果有人利用本文知识和技术进行非法操作进行牟利,带来的任何法律责任都将由操作者本人承担,和本文作者无任何关系,最终还是希望大家能够秉着学习的心态阅读此文。

MIUI9绕开联网和插卡打开未知来源
最新MIUI9的设备通过PC手机助手安装APK,需要在设备上打开未知来源。
发现最新的MIUI9打开未知来源需要联网和插入SIM卡后才能打开。

* 用命令打开“未知来源”
         
         在MIUI9中加了权限,打开失败。因此需要手动打开

* 设置->更多设置->系统安全->未知来源
         
   提示需要联网,联网后再次打开,又提示需要插入SIM卡
         看来是进行了网络检测和SIM卡检测
         看来只有老老实实的联网和插卡后才能打开未知来源了
         会不会有其它方式可以绕开呢?不能把,本地检测了网络和插卡,绕不过吧

*pull“com.android.settings”
         

*jadx查看下   
         拖进去居然没有反应,看来反编译失败了   
   解开apk后发现没有classes.dex   
   经过一番搜索,dex被提取并转换成oat了

*pull oat
         
         虽然是.odex结尾的,但其实是oat格式的文件

* oat转dex
         oat是elf格式的文件并且包含了一个完整的dex
         用ExtractDexFromOat把oat转换成dex
         

*jadx 打开 .dex
         居然还是打开失败
         经过一番折腾,是因为dex头中的035改成了037导致反编译失败
         
         把037改成035即可用jadx打开了
         我是把jadx解析dex用到的lib包dx-1.10.jar反编译后去掉了对035的校验

* apktool 反编译资源文件
         

* 搜索“未知来源”
         
         “install_applications”可疑

* 继续搜索“install_applications”看在那个布局文件中出现
         
         出现在security_settings_misc.xml
         <com.android.settings.MiuiRestrictedSwitchPreference android:persistent="false" android:title="@string/install_applications" android:key="toggle_install_applications"          android:summaryOn="@string/install_unknown_applications" android:summaryOff="@string/install_unknown_applications" style="?android:attr/preferenceScreenStyle" />
         可以看出com.android.settings.MiuiRestrictedSwitchPreference是小米自定义的没有android:id,可以看到有android:key有可能是根据这个key在程序中操作的

* jadx搜索“toggle_install_applications”
         
         
         
         在com.android.settings.SecuritySettings找到2处
         this.bGg = (MiuiRestrictedSwitchPreference) findPreference("toggle_install_applications");
         正如上面的猜想是通过key来获取MiuiRestrictedSwitchPreference对象
       public boolean onPreferenceChange(Preference preference, Object obj) {      String key = preference.getKey();                     if ("toggle_install_applications".equals(key)) {            if (((Boolean) obj).booleanValue()) {                this.bGg.setChecked(false);                bsN();                z = false;            } else {                bsI(false);            }      }      return z;}
         在onPreferenceChange中响应事件
                  打开时调用bsN();
                  关闭时调用bsI(false);

* 跟踪bsN()
            
         弹出确认框 可以看到上面关闭时也是调用的bsI
         

* 跟踪bsI()
            
         关闭:
                  Global.putInt(blI(), "install_non_market_apps", z ? 1 : 0);
         打开:
                Intent intent = new Intent("com.miui.securitycenter.action.UNKNOWN_SOURCE_VERIFY");
intent.setPackage("com.miui.securitycenter");
startActivityForResult(intent, 1004);   

         startActivityForResult的第二个参数是请求码1044
         应该是在onActivityResul中根据"com.miui.securitycenter"中设置的返回码来确定是否打开“未知来源”

* 跟踪onActivityResul()
         
         第一个参数是请求码,第二个参数是返回码
         可以看出当请求码=1004时,返回码=-1时打开“未知来源”
         看看“com.miui.securitycenter”中做了什么

*pull“com.miui.securitycenter”包才能继续跟踪了
         

* pull “com.miui.securitycenter”的oat文件
         

* 同样把oat转dex
         

* apktool 反编译资源文件
         

* 在AndroidManifest.xml搜索com.miui.securitycenter.action.UNKNOWN_SOURCE_VERIFY
         
         找到相关activity “com.miui.permcenter.install.UnknownSourceVerifyActivity”

* 用修改过的jadx打开SecurityCenter.dex(不校验dex头的035)
         找到UnknownSourceVerifyActivity
            
         可以看到V()把返回码设置成了-1
                  1、VERSION.SDK_INT == 24 && !"mido".equals(str)
                  2、VERSION.SDK_INT == 25 && new ArrayList().contains(str)
                  3、T()
                  
                  Build.DEVICE=tiffany,VERSION.SDK_INT=25
                  前面两个条件满足就可以,但是在我测试的设备上不满足前面两个条件
                  继续看T()

* 跟踪T(), 父类AdbInstallVerifyActivity的方法
         

*跟踪W()
         
         此处判断了是否联网,没有联网则提示并finish掉

* 跟踪m
         

* 跟踪 a.a(this.R.getApplicationContext(), hashMap));
         

* 跟踪 com.miui.securityscan.utils.a.Jr(arg3);
         
         获取android_id

* 跟踪 ((Map)v4).put("sim", a.b(arg3));
         
         可以看到没有插卡返回“off”

* 跟踪 new i().al(jSONObject2.toString())
         
         请求数据加密

* 跟踪 a.c()
         
         post请求
         Url是this.R.s
         在子类UnknownSourceVerifyActivity中s赋值为“http://srv.sec.miui.com/data/unknownSources”

* 用Fiddler看一下
         HTTP/1.1 200 OK
         Server: Server/2.1.1
         Date: Fri, 08 Dec 2017 06:41:22 GMT
         Content-Length: 29
         Connection: keep-alive
         x-host-name: c00.bj
         x-sec-s: qXjqQ8Kf7TcFT2R9C6E3CxcbkG5L7a1H1jAH9co1OPbJ3Ciy5P68qznvRwOnr/AL5qVW6BddwZV6fG1zE0sxJT20EKWH+6B/vdzTXVBLFX3zic+CJvwOwQCGNHyGQmZ6Gd41xq1Mt3Izthve+0HQM/3TkFDkmUbLqrELpOGtut0=

         {"status":"0","message":"ok"}

         向"http://srv.sec.miui.com/data/unknownSources"请求数据
         当没有插入SIM卡的时候,则请求数据中sim=off时返回的status!=0并且message提示需要插卡


* 根据返回的数据
         return jSONObject.optInt("status", -1) == 0 ? null : jSONObject.optString("message");
         Status=0时返回null,否则返回message

* 跟踪au(String str)
         
         可以看到当str=null时调用了V() 将返回码设置成-1后并finish掉

* 根据上面的跟踪,看来并不是在本地校验sim卡是否存在而是在服务器端校验的
         既然如此我们是否可以拦截求情返回status=0的数据呢?
         当然是可以的
         我们可以开启一个热点,并开启一个webserver,让手机连接这个热点,把相关请求转到webserver上并返回自定义的数据即可

* 开启热点并把“srv.sec.miui.com”添加到host
         

* 使用QtWebServer 开发一个小的webserver
         

* 断开热点机器上的外网   
         设备就不会联网激活

* 连接该热点
         就可以把srv.sec.miui.com的请求转到QtWebServer 上
         请求路径是“/data/unknownSources”则返回{"status":"0","message":"ok"}

大蛇拉龟 发表于 2017-12-15 18:28

这个有什么用?

lan0mkdy 发表于 2017-12-26 08:14

airwenlee 发表于 2017-12-15 19:09
怎么屏蔽MIUI9恶心的广告?切换程序经常会弹出京东或是苏宁广告

你这是软件自带的吧。。。不是系统广告。而且小米的广告都可以关的

15005560818 发表于 2017-12-15 17:15

感谢分享

兔子我是胡萝卜 发表于 2017-12-15 17:19

咦,帖子重复了?

hunanxiaom 发表于 2017-12-15 17:26

谢谢分享

朕很寂寞 发表于 2017-12-15 17:27

感谢分享,不过好像现在miui9现在开机不需要联网

不是呵呵 发表于 2017-12-15 18:34

确实666

airwenlee 发表于 2017-12-15 19:09

怎么屏蔽MIUI9恶心的广告?切换程序经常会弹出京东或是苏宁广告

随风飘落 发表于 2017-12-15 20:27

大神分析的就是到位

linclon 发表于 2017-12-15 20:44

厉害厉害,感谢楼主分享
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: MIUI9绕开联网和插卡打开未知来源