作者归档:zhiwei

国美Fenmmy Note解锁bootloader

型号: 2018X38A
芯片: P23 (MT6763)

首先,在设置里打开允许oem解锁

进入bootloader模式

adb reboot bootloader

运行解锁命令

fastboot oem unlock

按照屏幕提示, 按一下 音量加

然后查一下解锁状态

$ fastboot getvar all
(bootloader) 	max-download-size: 0x8000000
(bootloader) 	partition-size:flashinfo: 1000000
(bootloader) 	partition-type:flashinfo: raw data
(bootloader) 	partition-size:userdata: 32000000
(bootloader) 	partition-type:userdata: ext4
(bootloader) 	partition-size:cache: 1b000000
(bootloader) 	partition-type:cache: ext4
(bootloader) 	partition-size:system: c0000000
(bootloader) 	partition-type:system: ext4
(bootloader) 	partition-size:vendor: 7d000000
(bootloader) 	partition-type:vendor: raw data
(bootloader) 	partition-size:tee2: 900000
(bootloader) 	partition-type:tee2: raw data
(bootloader) 	partition-size:tee1: 500000
(bootloader) 	partition-type:tee1: raw data
(bootloader) 	partition-size:odmdtbo: 1000000
(bootloader) 	partition-type:odmdtbo: raw data
(bootloader) 	partition-size:logo: 800000
(bootloader) 	partition-type:logo: raw data
(bootloader) 	partition-size:boot: 2000000
(bootloader) 	partition-type:boot: raw data
(bootloader) 	partition-size:lk2: 100000
(bootloader) 	partition-type:lk2: raw data
(bootloader) 	partition-size:lk: 100000
(bootloader) 	partition-type:lk: raw data
(bootloader) 	partition-size:nvram: 4000000
(bootloader) 	partition-type:nvram: raw data
(bootloader) 	partition-size:gz2: 1000000
(bootloader) 	partition-type:gz2: raw data
(bootloader) 	partition-size:gz1: 1000000
(bootloader) 	partition-type:gz1: raw data
(bootloader) 	partition-size:sspm_2: 100000
(bootloader) 	partition-type:sspm_2: raw data
(bootloader) 	partition-size:sspm_1: 100000
(bootloader) 	partition-type:sspm_1: raw data
(bootloader) 	partition-size:spmfw: 100000
(bootloader) 	partition-type:spmfw: raw data
(bootloader) 	partition-size:md1dsp: 1000000
(bootloader) 	partition-type:md1dsp: raw data
(bootloader) 	partition-size:md1img: 4000000
(bootloader) 	partition-type:md1img: raw data
(bootloader) 	partition-size:proinfo: 300000
(bootloader) 	partition-type:proinfo: raw data
(bootloader) 	partition-size:sec1: 200000
(bootloader) 	partition-type:sec1: raw data
(bootloader) 	partition-size:seccfg: 800000
(bootloader) 	partition-type:seccfg: raw data
(bootloader) 	partition-size:protect2: 978000
(bootloader) 	partition-type:protect2: ext4
(bootloader) 	partition-size:protect1: 800000
(bootloader) 	partition-type:protect1: ext4
(bootloader) 	partition-size:metadata: 2000000
(bootloader) 	partition-type:metadata: raw data
(bootloader) 	partition-size:nvdata: 4000000
(bootloader) 	partition-type:nvdata: ext4
(bootloader) 	partition-size:nvcfg: 2000000
(bootloader) 	partition-type:nvcfg: ext4
(bootloader) 	partition-size:frp: 100000
(bootloader) 	partition-type:frp: raw data
(bootloader) 	partition-size:expdb: 1400000
(bootloader) 	partition-type:expdb: raw data
(bootloader) 	partition-size:para: 80000
(bootloader) 	partition-type:para: raw data
(bootloader) 	partition-size:recovery: 2000000
(bootloader) 	partition-type:recovery: raw data
(bootloader) 	partition-size:boot_para: 100000
(bootloader) 	partition-type:boot_para: raw data
(bootloader) 	partition-size:preloader: 40000
(bootloader) 	partition-type:preloader: raw data
(bootloader) 	off-mode-charge: 1
(bootloader) 	warranty: no
(bootloader) 	unlocked: yes
(bootloader) 	secure: no
(bootloader) 	kernel: lk
(bootloader) 	product: GM18A
(bootloader) 	version-preloader: 
(bootloader) 	version: 0.5

brotli压缩的卡刷包提取

用Google的brotli解压缩

brotli -d system.new.dat.br -o system.new.dat

sda2img转化

sdat2img.py system.transfer.list system.new.dat system.ext4.img

然后mount

mount -t ext4 system.ext4.img /mnt/system

进 /mnt/system 就可以看到文件了

用ubus读取网口IP对比用uqmi读取modem的IP

#!/bin/sh

. /usr/share/libubox/jshn.sh

#### ifstatus lte_4  ####
json_load "$(ubus call network.interface.lte_4 status)"
json_select ipv4-address
json_select "1"
json_get_var lte_address address
json_select ".."
json_select ".."
json_select route
json_select "1"
json_get_var lte_gateway nexthop



json_load "$(uqmi -s -d /dev/cdc-wdm0 --get-current-settings)"
json_select ipv4
json_get_var modem_ip ip
json_get_var modem_gateway gateway


echo $lte_address
echo $lte_gateway

echo $modem_ip
echo $modem_gateway

做比较, 如果 ip 不同
就执行

ifdown lte
sleep 1
ifup lte

重启网口

openwrt中etc config下的配置文件是如何动态生成的

目录 package/base-files/files/lib/functions 下有如下文件



leds.sh
network.sh
preinit.sh
service.sh
system.sh
uci-defaults.sh

uci-defaults.sh会生成默认的/etc/config下的文件

target/linux/ramips/base-files/etc/board.d

   01_leds
   02_network
   03_gpio_switches

targetlinux/ramips/base-files/etc/uci-defaults

package/base-files/files/etc/init.d/boot 这个启动脚本里有
uci_apply_defaults
这个函数

———————————————————–

package/base-files/files/etc/board.d
99-default_network

/package/network/services/odhcpd/files/odhcpd.defaults json_load “$(cat /etc/board.json)”
package/base-files/files/lib/functions/uci-defaults.sh json_dump -i > /tmp/.board.json
mv /tmp/.board.json ${CFG}

package/base-files/files/bin/board_detect [ -n “$CFG” ] || CFG=/etc/board.json

package/base-files/files/bin/config_generate CFG=/etc/board.json

openwrt uqmi可用的命令

# uqmi -d  /dev/cdc-wdm0   --get-data-status
"Incompatible state"



# uqmi -d  /dev/cdc-wdm0   --get-serving-system 
{
	"registration": "registered",
	"plmn_mcc": 460,
	"plmn_mnc": 1,
	"plmn_description": "UNICOM",
	"roaming": false
}



# uqmi -d  /dev/cdc-wdm0   --get-signal-info
{
	"type": "lte",
	"rssi": -53,
	"rsrq": -10,
	"rsrp": -84,
	"snr": 30
}


uqmi -d  /dev/cdc-wdm0   --wda-get-data-format
"raw-ip"



# uqmi -d  /dev/cdc-wdm0   --get-current-settings
{
	"pdp-type": "ipv4-or-ipv6",
	"ip-family": "ipv4",
	"mtu": 1500,
	"ipv4": {
		"ip": "10.24.30.23",
		"dns1": "116.116.116.116",
		"dns2": "221.5.88.88",
		"gateway": "10.24.30.24",
		"subnet": "255.255.255.240"
	},
	"ipv6": {
		
	},
	"domain-names": {
		
	}
}


# uqmi -d  /dev/cdc-wdm0  --get-capabilities
{
	"max_tx_channel_rate": 50000000,
	"max_rx_channel_rate": 100000000,
	"data_service": "non_simultaneous_cs_ps",
	"sim": "supported",
	"networks": [
		"cdma1x",
		"cdma1xevdo",
		"gsm",
		"umts",
		"lte",
		"unknown"
	]
}


# uqmi -d  /dev/cdc-wdm0   --reset-dms


# uqmi -d  /dev/cdc-wdm0   --start-network


# uqmi -d  /dev/cdc-wdm0   --stop-network

联想Z5创建多于5个微信分身

用Frida

setImmediate(function() { //prevent timeout
    Java.perform(function(){
        console.log("start hook....");

        var MultipleSpaceManager = Java.use("com.android.settings.feature.multiplespace.manager.MultipleSpaceManager");
        console.log("MultipleSpaceManager Found.");        

        var createAppMultiple = MultipleSpaceManager.createAppMultiple.overload("java.lang.String", "com.android.settings.feature.multiplespace.manager.MultipleSpaceManager$CreateAppMultipleListener");

        createAppMultiple.implementation = function (pkgname, objX) {
            console.log("pkgname: " + pkgname);
            this.createAppMultiple("com.tencent.mm", objX);
        };

        console.log("hook ok");
    });
});

frida.get_usb_device().attach(‘com.android.settings’)

远离: 将创建其他分身的 pacakgeName 换成 ”com.tencent.mm”

避免超过3个分身后, 添加按钮不可用

如何启动

https://developer.android.com/work/managed-profiles
https://stackoverflow.com/questions/43344576/appium-how-to-launch-app-from-android-for-work-work-profile


am start --user 910  -n "com.tencent.mm/.ui.LauncherUI " -a android.intent.action.MAIN -c android.intent.category.LAUNCHER




am start --user 915  -n "com.tencent.mm/.ui.LauncherUI"                                                                                                          

Starting: Intent { cmp=com.tencent.mm/.ui.LauncherUI }
Error type 3
Error: Activity class {com.tencent.mm/com.tencent.mm.ui.LauncherUI} does not exist.



停止用户
am stop-user 900

pm list users 看到用user状态就变了

am profile start –user 915
am profile stop 

am start-user
am unlock-user
am switch-user
am stop-user

am get-current-user

pm list packages –user 910

先开启用户
am start-user 915
再开启应用
am start --user 915  -n "com.tencent.mm/.ui.LauncherUI"

qmi配置ipv6

uqmi -d /dev/cdc-wdm0 --get-current-settings
{
	"pdp-type": "ipv4-or-ipv6",
	"ip-family": "ipv4",
	"mtu": 1500,
	"ipv4": {
		"ip": "10.130.36.153",
		"dns1": "221.12.1.227",
		"dns2": "221.12.33.227",
		"gateway": "10.130.36.154",
		"subnet": "255.255.255.252"
	},
	"ipv6": {
		
	},
	"domain-names": {
		
	}
}

然而,AT+CGPADDR=1是有IPV6的

at+cgpaddr=1

+CGPADDR: 1,"10.130.36.153,36.8.132.237.0.0.185.43.0.1.0.2.80.64.233.245"

说明 没有配置pdp, 做如下配置

/etc/config/network

config interface 'lte'
	option proto 'qmi'
	option device '/dev/cdc-wdm0'
	option pdptype 'ipv4v6'
	option dhcpv6 '1'

/etc/config/firewall

config zone
	option name		wan
	list   network		'lte'

/lib/netifd/proto/qmi.sh  (因为移远EC20 R2.0的问题, 数据格式几个命令不能用,并且默认的数据格式只能是raw-ip)

        # Set IP format                                                                                                                                             
        #uqmi -s -d "$device" --set-data-format 802.3 > /dev/null 2>&1  
        #uqmi -s -d "$device" --wda-set-data-format 802.3 > /dev/null 2>&1
        #dataformat="$(uqmi -s -d "$device" --wda-get-data-format)"
                                                                   
        #if [ "$dataformat" = '"raw-ip"' ]; then  
           ...
        #fi  

所以,把数据格式相关的几条命令注视掉, 就可以了

wwan0     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.130.36.153  P-t-P:10.130.36.153  Mask:255.255.255.252
          inet6 addr: 2408:84ed:0:b92b:e18a:c1bc:773d:d885/64 Scope:Global
          inet6 addr: fe80::e18a:c1bc:773d:d885/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:502 errors:0 dropped:0 overruns:0 frame:0
          TX packets:693 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:168062 (164.1 KiB)  TX bytes:87403 (85.3 KiB)

br-lan    Link encap:Ethernet  HWaddr 78:A3:51:42:9F:BA  
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: 2408:84ed:0:b92b::1/64 Scope:Global
          inet6 addr: fd5c:55d0:5ea0::1/60 Scope:Global
          inet6 addr: fe80::7aa3:51ff:fe42:9fba/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1736 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1180 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:187710 (183.3 KiB)  TX bytes:330901 (323.1 KiB)

PC也能分配到v6地址


2: enp109s0f1:  mtu 1400 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 80:fa:5b:34:e4:e9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.119/24 brd 192.168.1.255 scope global dynamic noprefixroute enp109s0f1
       valid_lft 43195sec preferred_lft 43195sec
    inet6 fd5c:55d0:5ea0::bdd/128 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 2408:84ed:0:b92b::bdd/128 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fd5c:55d0:5ea0:0:c925:bf86:3482:7e80/64 scope global temporary dynamic 
       valid_lft 604796sec preferred_lft 86350sec
    inet6 fd5c:55d0:5ea0:0:82fa:5bff:fe34:e4e9/64 scope global mngtmpaddr noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 2408:84ed:0:b92b:c925:bf86:3482:7e80/64 scope global temporary dynamic 
       valid_lft 604796sec preferred_lft 86350sec
    inet6 2408:84ed:0:b92b:82fa:5bff:fe34:e4e9/64 scope global mngtmpaddr noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fe80::82fa:5bff:fe34:e4e9/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

arm64取字符串

#include 
#include 

int main() {
    int ret = __system_property_set("persist.radio.uim.remote.slot", "-2");
    printf("%d\n", ret);
    ret =  __system_property_set("persist.radio.uim.remote.slot", "-3");
    return 0;
}

用 https://zhiwei.li/text/2016/02/25/%E7%BC%96%E8%AF%91android-c%E4%BB%A3%E7%A0%81/ 这里的方法编译

然后,用root成功执行

MOV指令编码也是看不懂

   E8 03 00 32 --->  MOV W8, #1
   E8 03 1F 32 --->  MOV W8, #2
   
   E8 07 00 32 --->  MOV W8, #3
   E8 03 1E 32 --->  MOV W8, #4

jtrace

http://newandroidbook.com/tools/jtrace.html

带插件架构的增强的Linux/Android strace

jstrace相对于strace 的改进如下:
1. Android意识(Android-awareness)
不仅dump系统调用, 也解释一些基于I/O的socket操作, 比如
   a) 系统属性设置( /init) , 看下面的例子
   b) 输入事件(比如 InputReader)
c) Binder消息分析(自动检测), 对某些进程(ActivityManager), 它实际也解密parcel

2.带颜色的输出

3. 线程名称能力: 
  Android使用 prctl 来命名线程(特别是在 system_server里)
你能直接通过名字来附加的目标线程

4. 插件化

5.错误注入
   允许你 监视和阻止某些系统调用
   或者修改他们的参数 和 返回值

JCOLOR=1 /data/local/tmp/jtrace64 -p 1

JCOLOR=1 /data/local/tmp/jtrace64 -p 1 | grep setprop

监视init 进程, 可以跟踪 属性 写入

recvfrom (8, { setprop request for ist.radio.uim.remote.slo = }…) = 29
recvfrom (8, { setprop request for ist.radio.uim.remote.gpi = }…) = 29

/dev/socket/property_service

persist.radio u:object_r:radio_prop:s0

libc.so

frameworks/base/core/jni/android_os_SystemProperties.cpp
system/core/init/property_service.c
bionic/libc/include/sys/_system_properties.h
bionic/libc/bionic/system_properties.c

可以通过SystemProperties.set()/SystemProperties.get()来操作属性值,但是android.os.SystemProperties这个类是{@ hide}的,我们可以通过反射的方法调用

properties.c的__system_property_set()
通过socket向property_service发送消息  err = send_prop_msg(&msg);

用frida hook 到 android\os\SystemProperties

搜索  find /vendor -type f | xargs fgrep ‘uim.remote.slot’
发现 /vendor/lib/libril-qc-hal-qmi.so 里有用到

persist.radio.uim.remote.slot

persist.radio.uim.remote.slot

ZuiDialer.apk
ZuiCallSettings.apk
ZuiFindMyPhone.apk
LSF-User-Phone.apk
ZuiMessage.apk
SimSettings.apk
ZuiSettings.apk
ZuiTelecom.apk

boot-telephony-common.vdex

禁止修改  persist.radio.uim.remote.slot 这个属性为 非-1 的值

由于手机找回功能已经激活,手机校验到  关机/拔卡 动作后会触发手机 找回功能 应用,
内置在手机底层的“找回功能”应用会内部调用红茶的境外上网资源服务,强制联网,上报手机位置到服务器,这样失主就可以看到自己的手机状态和位置。

与红茶移动的eConnect落地,可提供免费30分钟的流量给用户。这只需把eConnect的组件直接植入到手机里就可做到

https://zhao.zui.com
https://zhao.lenovomm.com/

在  com.zui.simsettings.fragment.DualCardPrefsFragment 有


   mCardCall.setEnabled(isVirtualCardInsert() ^ 1);  // 虚拟卡不能选择打电话
   mCardSms.setEnabled(isVirtualCardInsert() ^ 1);
   mCardData.setEnabled(isVirtualCardInsert() ^ 1);


    private boolean isVirtualCardInsert() {
        boolean ret = true;
        int vsim_slot = Integer.valueOf(SystemProperties.get("persist.radio.uim.remote.slot", "-1")).intValue();
        if(vsim_slot != 1 && vsim_slot != 0) {
            ret = false;
        }

        return ret;
    }