一气之下改造IPTV电视机顶盒

1)引言

在经历了通过windows计划任务和windows服务方式开机自启动frpc客户端都失败之后。
在不重装对方系统的情况下(因为我在本机和虚拟机测试是没问题的,对方系统应该是配置不妥,因而无法自启动),我在寻找一个更稳定且廉价的方案。

那就把frpc从这台电脑中分离出来吧,就算继续在那台电脑中折腾出什么方案,后期也不知道会出什么幺蛾子。

那我需要一个廉价的能运行Linux或Windows或Mac设备。

好吧,我首先想到(二手):工控机、树莓派、瘦客机、安卓手机

嗯,安卓系统也是Linux系统root好之后加个自启动就完美了,

但是二手安卓的稳定性让我堪忧(主要是供电,常年供电会不会废掉),

有没有更稳定的安卓设备呢?电信送的机顶盒子好像不错啊。

于是打开了某二手平台APP,寻找100元以下的以上设备

最后在价格、体积、外观、性能的综合考虑之后,我以50元入手了一个华为悦盒EC6108V9C

货到了之后就开工了。

2)启动虚拟机进行尝试

我比较担心的是不小心弄坏了盒子的系统开不了机,甚至变砖,带来不必要的麻烦
由于我的电脑中有运行着Docker,官方安卓虚拟机是开不了的了。

于是找了个微软使用Hyper-V技术实现的为Visual Studio准备的虚拟机,成功启动了模拟器
适用于 Android 的 Visual Studio 模拟器

成功跑起来模拟器之后,却发现adb连接不上去,WTF?

好在我发现了可以从Hyper-V管理器里面打开命令行。附图:

vs-emulator

avdshell

检查发现,虚拟机的命令行可以直接su拿到root权限,Perfect!!!我们准备一些文件放到SD卡挂载进去吧

先看看CPU是啥架构的,我再选择对应的frpc客户端

如果是在真机上,一般是arm架构,但是具体是v4还是v7就要执行cat /proc/cpuinfo来查看了
但是这里是模拟器,上面这个命令并没显示架构,我也懒得去查了,直接拿32位版本的frpc去用了。

再准备一个frpc.ini配置文件,一起放在桌面的sdcard文件夹,然后通过模拟器的附加工具把这个文件夹同步到模拟器里面。

push-to-sdcard

接下来就在命令行里面操作了,我执行了以下命令

# 提权操作
su

# 将/system分区挂载为可读可写
mount -o remount -o rw /system

# 拷贝frpc可执行程序,并且设置权限和所有者
cp /mnt/shell/emulated/frpc /system/bin/frpc
chown root:shell /system/bin/frpc
chmod 755 /system/bin/frpc

# 测试一下frpc能否正常执行,
# 如果正常显示版本,就没拿错文件,
# 否则请检查模拟器的系统架构与所选择的可执行文件是否对应
frpc -v

# 拷贝配置文件
cp /mnt/shell/emulated/frpc.ini /etc/frpc.ini
chmod 644 /etc/frpc.ini

# 运行一下检查配置文件是否有误
frpc -c /etc/frpc.ini

3)在虚拟机里尝试安排开机启动

一切顺利的话,我们就缺个开机启动了
在Linux系统里,要实现开机执行指定脚本,我想到了/etc/rc.d/rc.local文件
很遗憾,安卓里面没有
但是我发现安卓里面有一个/init.rc文件,似乎和开机启动有关系
于是查资料之后写出一段貌似能工作的配置,用echo命令添加到/init.rc文件末尾
Android开机执行shell脚本

/system/bin/runfrpc.sh文件内容,记得设置755的权限

#!/system/bin/sh
nohup /system/bin/frpc -c /system/etc/frpc.ini & 

/init.rc末尾添加的内容

service runfrpc /system/bin/runfrpc.sh
    class main
    user root
    group root
    oneshot
on property:sys.boot_completed=1
    start  runfrpc

然后满怀期待地执行reboot

结果重启之后,执行ps | grep frpc并没显示任何进程,WTF,出了什么问题
于是我检查frpc和frpc.ini文件存在否,然后再手动运行了一次
/system/bin/runfrpc.sh
没有发现异常

然后检查/init.rc发现,我刚刚再末尾添加的内容消失了...

我怀疑是被重置了,那没办法只能去网上找找看怎样持久化。
Android修改init.rc
Android修改init.rc和init.xx.rc文件
Android如何配置init.rc中的开机启动进程(service)
Android系统启动——3init.rc解析
android 系统启动时执行自己的脚本

得到的答案就是,修改boot.img镜像,重新烧录!不是吧,我没想要这么大动干戈

我不想刷机,更不想去编译内核(并不是懒,是觉得没必要这么折腾,价值不大,这样折腾我得花一个星期业余时间吧,我不如加点RMB买个预装Linux电脑棒),我觉得应该有其它方案,毕竟已经root了

好吧,继续查询之后发现一种新的方案:安装一个inid.d机制。

http://blog.sina.com.cn/s/blog_4ae16c850101cbp6.html

这个方案有两个关键的文件:busyboxterm-init.sh
我浏览的帖子附带的某盘下载地址全被和谐了。没办法我只能自己分开找了。

发现了busybox的官网https://busybox.net/ 于是从官网的下载地址里面下载两种CPU架构的二进制文件,注意使用右键另存为来下载
i686 https://busybox.net/downloads/binaries/1.21.1/busybox-i686
armv7 https://busybox.net/downloads/binaries/1.21.1/busybox-armv7l
其它平台 https://busybox.net/downloads/binaries/1.21.1/

Google搜索几遍没找到,那就去Github上找找吧,一找一个准
Term-init
作者的帖子

好了,接下来将这两个文件同步到模拟器的SD卡中。

然后先安装busybox

# 拷贝程序文件
cp /mnt/shell/emulated/busybox /system/bin/busybox
chown root:shell /system/bin/busybox
chmod 755 /system/bin/busybox

# 测试一下没有用错文件,如果正常显示帮助信息就没错
# 否则就去官网重新下载对应平台的可执行文件吧
busybox --help

# 安装
busybox --install -s /system/xbin/

# 检查此目录下是否存在着大量指向`/system/bin/busybox`的软链,有的话就是安装成功了
ls -l /system/xbin

接下来执行term-init.sh脚本以安装init.d机制

sh /mnt/shell/emulated/term-init.sh

安装过程中会检查环境是否满足,然后还需要回车确认

装好之后重启虚拟机,ps | grep frpc如果看到进程,那就是OK了

4)刷机准备工作

在虚拟机这个小白鼠上折腾了半天之后,信息满满地在线等快递,
于是,我先找了一些机顶盒的刷机帖子看了看
华为悦盒EC6108V9C安装教程

盒子到了之后,现实往往没有那么顺利。
STBManage工具总是提示:命令非法,操作失败

qFsrgPQ_jpg

又只能继续寻求解决方案,有的说要恢复出厂设置,
还有的说要升级STB工具(已测试,然并软)
有的说要路由器断网,有的说要降级才行
我决定都试试吧
于是我又找到了进入REC的方案,开机的同时不停地按左右键
华为悦盒怎么进入REC模式升级双清恢复出厂设置最全方法

然后找到一个固件包

华为悦盒EC6108V9C-桌面固件-广东电信华为盒子破解

固件下载地址
链接: https://pan.baidu.com/s/1ovrYsAilHkIvUJp7WRehVA 密码: impd

接下来把固件包放在U盘的根目录和upgrade目录各一份,因为不想重试
然后目录结构如下了:

----update.zip
----upgrade
       |___update.zip

重新进入REC模式之后,选择Apply update from backup,然后就进入了升级过程

升级完成之后,盒子的欢迎页换了。我再次打开STBManage工具,很好,连接成功!

于是我修改了允许远程管理,接下来就是ADB的事情了

接着运行通用破解及V8_V9A_V9E.bat脚本开始安装当贝桌面和一些工具到盒子中

后来发现,也许并不需要这个脚本,我事后查看这个bat时发现,
也由于时测试用的东西,才会这么不关心脚本里具体的内容,
若是项目生产环境,从网上下载的东西,不搞懂整个脚本哪里敢运行

5)使用ADB改造盒子

首先把各个文件准备好放到U盘,包括:

  • busybox
  • frpc
  • frpc.ini
  • runfrpc.sh
  • term-init.sh
    其中busybox和frpc都是对应armv7架构的
    然后我再写了一个一键安装的脚本,一起放进去了U盘
    install.sh文件
#!/system/bin/sh
# install frpc and start at system power on.

# 如果你的U盘路径不是这个,可以在这修改
sdpath=/sdcard

mount -o remount -o rw /system;

# install frpc
cp $sdpath/frpc /system/bin/frpc;
chown root:shell /system/bin/frpc;
chmod 755 /system/bin/frpc;

# create frpc config file
cp $sdpath/frpc.ini /system/etc/frpc.ini;
chmod 750 /system/etc/frpc.ini;

# copy busybox to evn path
cp $sdpath/busybox /system/bin/busybox;
chown root:shell /system/bin/busybox;
chmod 755 /system/bin/busybox;

# install busybox
/system/bin/busybox --install -s /system/xbin/

# enable init.d
sh $sdpath/term-init.sh

mount -o remount -o rw /system;

# create start script for frpc
cp $sdpath/runfrpc.sh /system/etc/init.d/runfrpc
chown root:root /system/etc/init.d/runfrpc;
chmod 755 /system/etc/init.d/runfrpc;

echo "=======================FINISH========================="
echo "you can exec reboot command to verify."
echo "if the frpc proc has benn in ps | grep frpc result,"
echo -e "than, you are succeeded.\n"

把U盘插入机顶盒之后,执行adb连接命令:

adb connect 机顶盒IP:5555
adb shell
su
sh /sdcard/install.sh
reboot

如果开机之后没有frpc进程,
并且/data/Test.log文件夹不存在,那有可能你盒子的内核没法支持init.d,
换个盒子或者自己编译打包镜像烧进去吧

反正我就是搞成了~~

然后我将盒子修改为WIFI连接方式,并且安装对方的WIFI名称和密码添加到提前添加进wifi列表,

实在是太帅了,我只需要把盒子给对方,对方只需要上电,我的frpc就能工作了,

对方的电脑也不再需要开着黑窗口了

搞定!收工~~~

6)附件:

权限计算网页

term-init.sh脚本的内容

#!/system/bin/sh
#Script to enable init.d by Ryuinferno @ XDA

error_msg(){
echo "You do not need this mod..."
sleep 1
echo "If you are reapplying, please delete these files if present:"
echo "/system/bin/sysinit"
sleep 1
echo "/system/etc/install-recovery.sh"
sleep 1
echo "/system/etc/install-recovery-2.sh"
sleep 1
echo "And run again..."
sleep 1
echo "If init.d is still not working, read the FAQ part in my thread..."
sleep 1
echo "Aborting..."
mount -o remount,ro -t auto /system
echo ""
echo "Ryuinferno @ XDA"
exit 1
}

echo "Init.d Enabler by Ryuinferno @ XDA"
echo ""
sleep 1

id=`id`; 
id=`echo ${id#*=}`; 
id=`echo ${id%%\(*}`; 
id=`echo ${id%% *}`
if [ "$id" != "0" ] && [ "$id" != "root" ]; then
	echo "Script NOT running as root!"
	sleep 1
	echo "Superuser access not granted!"
	sleep 1
	echo "Please type 'su' first before running this script..."
	exit 1
else
	echo "Hello Supaa User! :P"
	echo ""
	sleep 1
fi

if [ ! "'which busybox'" ]; then
	echo "busybox NOT INSTALLED!"
	sleep 1
	echo "Please install busybox first!"
	exit 1
else
	echo "busybox found!"
	sleep 1
fi

bbb=0

if [ ! "`which grep`" ]; then 
	bbb=1
	echo "grep applet NOT FOUND!"
	sleep 1
	else 
	echo "Awesome! grep found! :D"
	sleep 1
fi

if [ ! "`which run-parts`" ]; then 
	bbb=1
	echo "run-parts applet NOT FOUND!"
	sleep 1
	else
	echo "Good! run-parts found! :)"
	echo ""
	sleep 1
fi

if [ $bbb -eq 1 ] ; then
	echo ""
	echo "Required applets are NOT FOUND!"
	echo ""
	sleep 1
	echo "Please reinstall busybox!"
	exit 1
fi

echo "Great! Let's proceed..."
echo ""
sleep 1
echo "Press enter to continue..."
read enterKey

clear
sleep 1
echo "Mounting system as rewritable..."
mount -o remount,rw -t auto /system

sleep 1
echo ""
echo "Checking for the presence of sysinit in /system/bin..."
sleep 1
if [ -e /system/bin/sysinit ]; then
	echo "sysinit found..."
	if [ -z "`cat /system/bin/sysinit | grep "init.d"`" ]; then
		echo "Adding lines to sysinit..."
		echo "" >> /system/bin/sysinit
		echo "# init.d support" >> /system/bin/sysinit
		echo "" >> /system/bin/sysinit
		echo "export PATH=/sbin:/system/sbin:/system/bin:/system/xbin" >> /system/bin/sysinit
		echo "run-parts /system/etc/init.d" >> /system/bin/sysinit 
		echo "" >> /system/bin/sysinit
	else
		echo ""
		echo "Your sysinit should already be running the scripts in init.d folder at boot..."
		error_msg
	fi
else
	echo "sysinit not found, creating file..."
	echo "#!/system/bin/sh" > /system/bin/sysinit
	echo "# init.d support" >> /system/bin/sysinit
	echo "" >> /system/bin/sysinit
	echo "export PATH=/sbin:/system/sbin:/system/bin:/system/xbin" >> /system/bin/sysinit
	echo "run-parts /system/etc/init.d" >> /system/bin/sysinit 
	echo "" >> /system/bin/sysinit
fi

sleep 1
echo "Setting correct permissions and ownership for sysinit..."
chmod 755 /system/bin/sysinit
chown 0.2000 /system/bin/sysinit

sleep 1
echo ""
echo "Checking for the presence of install-recovery.sh..."
sleep 1
if [ -f /system/etc/install-recovery.sh ] && [ -z "`cat /system/etc/install-recovery.sh | grep "daemon"`" ]; then
	if [ ! -z "`cat /system/etc/install-recovery.sh | grep "init.d"`" ];then
		echo "Your install-recovery.sh seems to be already modified for init.d..."
		error_msg
	fi
	echo "install-recovery.sh found, renaming it as install-recovery-2.sh..."
	mv /system/etc/install-recovery.sh /system/etc/install-recovery-2.sh
	echo "Recreating install-recovery.sh..."
	echo "#!/system/bin/sh" > /system/etc/install-recovery.sh
	echo "# init.d support" >> /system/etc/install-recovery.sh
	echo "" >> /system/etc/install-recovery.sh
	echo "/system/bin/sysinit" >> /system/etc/install-recovery.sh
	echo "" >> /system/etc/install-recovery.sh
	echo "# excecuting extra commands" >> /system/etc/install-recovery.sh
	echo "/system/etc/install-recovery-2.sh" >> /system/etc/install-recovery.sh
	echo "" >> /system/etc/install-recovery.sh
elif [ -f /system/etc/install-recovery.sh ] && [ ! -z "`cat /system/etc/install-recovery.sh | grep "daemon"`" ]; then
	if [ -f /system/etc/install-recovery-2.sh ] && [ ! -z "`cat /system/etc/install-recovery-2.sh | grep "init.d"`" ];then
		echo "Your install-recovery-2.sh seems to be already modified for init.d..."
		error_msg
	fi
	echo "install-recovery.sh is used for superuser, using install-recovery-2.sh instead..."
	if [ -f /system/etc/install-recovery-2.sh ]; then
		echo "" >> /system/etc/install-recovery-2.sh
		echo "# init.d support" >> /system/etc/install-recovery-2.sh
		echo "/system/bin/sysinit" >> /system/etc/install-recovery-2.sh
		echo "" >> /system/etc/install-recovery-2.sh
	else
		echo "#!/system/bin/sh" > /system/etc/install-recovery-2.sh
		echo "# init.d support" >> /system/etc/install-recovery-2.sh
		echo "" >> /system/etc/install-recovery-2.sh
		echo "/system/bin/sysinit" >> /system/etc/install-recovery-2.sh
		echo "" >> /system/etc/install-recovery-2.sh
	fi
	if [ -z "`cat /system/etc/install-recovery.sh | grep "install-recovery-2.sh"`" ]; then
		echo "" >> /system/etc/install-recovery.sh
		echo "# extra commands" >> /system/etc/install-recovery.sh
		echo "/system/etc/install-recovery-2.sh" >> /system/etc/install-recovery.sh
		echo "" >> /system/etc/install-recovery.sh
	fi
else
	echo "install-recovery.sh not found, creating it..."
	echo "#!/system/bin/sh" > /system/etc/install-recovery.sh
	echo "# init.d support" >> /system/etc/install-recovery.sh
	echo "" >> /system/etc/install-recovery.sh
	echo "/system/bin/sysinit" >> /system/etc/install-recovery.sh
	echo "" >> /system/etc/install-recovery.sh
fi

sleep 1
echo "Setting the correct permissions and ownership for install-recovery.sh..."
echo "Also for install-recovery-2.sh if it exists..."
chmod 755 /system/etc/install-recovery.sh
chown 0.0 /system/etc/install-recovery.sh
if [ -f /system/etc/install-recovery-2.sh ]; then
	chmod 755 /system/etc/install-recovery-2.sh
	chown 0.0 /system/etc/install-recovery-2.sh
fi

sleep 1
echo ""
echo "Checking for the presence of the init.d folder..."
sleep 1
if [ -d /system/etc/init.d ]; then
	echo "init.d folder found..."
else 
	echo "init.d folder not found, creating the folder..."
	mkdir /system/etc/init.d
fi

sleep 1
echo ""
echo "Creating basic init.d scripts..."
echo "#!/system/bin/sh" > /system/etc/init.d/08setperm
echo "#set correct permissions to /system/etc/init.d folder" >> /system/etc/init.d/08setperm
echo "" >> /system/etc/init.d/08setperm
echo "mount -o remount,rw -t auto /system" >> /system/etc/init.d/08setperm
echo "chmod -R 777 /system/etc/init.d" >> /system/etc/init.d/08setperm
echo "mount -o remount,ro -t auto /system" >> /system/etc/init.d/08setperm
echo "" >> /system/etc/init.d/08setperm

echo "#!/system/bin/sh" > /system/etc/init.d/00test
echo "#init.d test" >> /system/etc/init.d/00test
echo "" >> /system/etc/init.d/00test
echo "if [ -f /data/Test.log ]; then" >> /system/etc/init.d/00test
echo "rm /data/Test.log" >> /system/etc/init.d/00test
echo "fi" >> /system/etc/init.d/00test
echo "" >> /system/etc/init.d/00test
echo 'echo "Init.d is working !!!" >> /data/Test.log' >> /system/etc/init.d/00test
echo 'echo "excecuted on $(date +"%d-%m-%Y %r" )" >> /data/Test.log' >> /system/etc/init.d/00test
echo "" >> /system/etc/init.d/00test

sleep 1
echo "Setting correct permissions and ownership for init.d folder and scipts..."
chmod 777 /system/etc/init.d
chmod 777 /system/etc/init.d/08setperm
chmod 777 /system/etc/init.d/00test
chown 0.0 /system/etc/init.d
chown 0.0 /system/etc/init.d/08setperm
chown 0.0 /system/etc/init.d/00test

sleep 1
echo ""
echo "Mounting system as read-only..."
mount -o remount,ro -t auto /system
sleep 1
echo ""
echo "Done!!!"
sleep 1
echo "Please reboot at least twice before checking /data..."
sleep 1
echo "If init.d is working, you will see a Test.log in /data..."
sleep 1
echo ""
echo "Enjoy!!! =)"
echo "Ryuinferno @ XDA 2013"
exit

评论