中兴光猫开机启动脚本
本帖最后由 asfsagsdfdsfsfd 于 2025-7-1 20:01 编辑在光猫等嵌入式设备上,系统的 rootfs(根文件系统)通常位于只读分区。如果直接修改该分区内容,极有可能导致 U-Boot 启动失败,或触发 CRC 校验错误,造成设备无法正常启动。那么,如果我们希望在设备开机后自动执行自定义脚本或程序,应该如何实现呢?主要有两种思路:
[*]修改固件镜像
这是最底层的方法,通过解包、修改、重新打包固件,可以从启动流程根本上植入脚本。然而,这种方式难度较大,需要深入理解固件的文件结构、校验机制和启动逻辑。
[*]利用已有可写分区进行 Hook
在系统中查找可写分区上的可执行程序,通过替换或包装(Hook)该程序,实现自定义脚本注入。这种方式相对简单,不必修改固件本身,也能保持较高的兼容性和安全性。
本文主要介绍第二种方式。具体的分析过程此处略去,我们直接看实现步骤。
1. 确定目标进程首先,查看系统中正在运行的 Java 进程:~ # ps | grep java
1757 java 13:21 java -noverify -Dfile.encoding=UTF-8 -Xcompactalways -Djava.net.preferIPv4Stack=false -Dsun.zip.disableMemoryMapping=true -Duser.timezone=GMT+8 -XX:ErrorFile=/usr/data/java_excp_log/java_error_2078.log -Djava.security.policy=/usr/local/osgi/local/j2re/lib/security/private.policy -Dorg.osgi.framework.security=osgi -Xms48M -Xmx128M -Xss256K -jar /usr/local/osgi/local/osgi/felix/bin/felix.jar
3251 root 0:52 cpulimit -l 80 -e java
11465 root 0:00 grep java
可以看到,系统的主 Java 服务由以下 JAR 包启动:/usr/local/osgi/local/osgi/felix/bin/felix.jar
2. 确认分区是否可写接下来,进入该目录并检查分区挂载属性:~ # cd /usr/local/osgi/local/osgi/felix/bin
/usr/local/osgi/local/osgi/felix/bin # df -h .
Filesystem Size Used Available Use% Mounted on
/dev/mtdblock10 30.0M 28.0M 2.0M93% /usr/local/osgi
确认分区是否可写:/usr/local/osgi/local/osgi/felix/bin # mount | grep /usr/local/osgi
/dev/mtdblock10 on /usr/local/osgi type jffs2 (rw,relatime)
由此可得:
[*]分区设备:/dev/mtdblock10
[*]文件系统:jffs2
[*]挂载方式:读写(rw)
说明此分区允许写入,可供我们进行Hook操作。
3. Hook 实现原理有了可写分区,我们可以通过封装启动逻辑的方式来 Hook:
[*]编写一个新的 Java 程序,先执行自定义 Shell 脚本(即我们需要在开机时运行的逻辑)。
[*]脚本执行完毕后,再调用原始的 felix.jar 启动系统服务。
[*]如果没有找到java进程,那么可以寻找一个二进制进程(在可写分区),流程一致。
这样一来:
[*]启动流程对原系统无任何功能影响。
[*]无需修改只读分区。
[*]脚本具备开机自动运行能力。
4. 具体操作我自己写了一个jar包,还有两个二进制Hook程序(arm/arm64)。下载地址:https://github.com/zooyer/devpai程序运行逻辑:
[*]备份Hook程序到 devpai 目录下(为了防止系统更新把我们Hook程序覆盖了)。
[*]启动一个线程/进程,一直判断Hook程序是否被覆盖,如果被覆盖,则我们再覆盖回去。
[*]执行 devpai 目录下的 hook.sh ,这个就是我们的启动脚本了。
[*]执行原始程序,不破坏原始流程。
部署Hook程序:1.下载Hook程序到临时目录并解压,可以看到3个Hook程序。cd /tmp
# 下载Hook程序
curl -k -L -o hookd.tgz https://github.com/zooyer/devpai/archive/refs/tags/v1.0.0.tar.gz
# 解压Hook程序
tar -zvxf hookd.tgz
# 查看Hook程序
cd devpai-1.0.0/
ls
#hookd.jar hookd_arm hookd_arm642.通过上述方式找到Hook点,如:/usr/local/osgi/local/osgi/felix/bin/felix.jar3.切换到Hook目录,复制对应Hook程序到该目录。# 切换到Hook目录
cd /usr/local/osgi/local/osgi/felix/bin
# 拷贝Hook程序,添加执行权限
cp /var/tmp/devpai-1.0.0/hookd.jar .
chmod a+x hookd.jar
ls
#felix.jarhookd.jar
# 创建Hook程序运行时目录
mkdir devpai
# 把原始程序,放入运行时目录
mv felix.jar devpai
# 把Hook程序,替换成原始程序
mv hookd.jar felix.jar
/usr/local/osgi/local/osgi/felix/bin #ls
devpai felix.jar
4.创建Hook脚本:vi devpai/hook.sh#!/bin/sh
user="$(/usr/bin/whoami)"
init="/usr/data/devpai/init.sh"
# 以root用户运行
if [ "$user" != "root" -a "$user" != "" ]; then
echo "aDm8H%MdA" | su -c "$init"
exit
fi
$init
这里我有调用了另一个目录中的初始化脚本,因为一般Hook目录的存储空间很小,不适合存放数据。后续启动脚本就都在/usr/data/devpai/init.sh这个里面了。5.杀掉java进程,让守护进程自动重新拉起。ps | grep java
1757 java 2h26 java -noverify -Dfile.encoding=UTF-8 -Xcompactalways -Djava.net.preferIPv4Stack=false -Dsun.zip.disableMemoryMapping=true -Duser.timezone=GMT+8 -XX:ErrorFile=/usr/data/java_excp_log/java_error_2078.log -Djava.security.policy=/usr/local/osgi/local/j2re/lib/security/private.policy -Dorg.osgi.framework.security=osgi -Xms48M -Xmx128M -Xss256K -jar /usr/local/osgi/local/osgi/felix/bin/felix.jar
3251 root 14:13 cpulimit -l 80 -e java
7982 root 0:00 grep java
# 这一步很重要,很多情况下如果没有这个步骤的话,那么下次重启则不会执行Hook程序
kill -9 1757
原文链接:https://blog.devpai.com/archives/modem-hook
感谢大佬分享666 uin 发表于 2025-7-1 22:06
感谢大佬分享666
感谢支持!感谢支持! 感谢大师分享! 感谢大师分享 池州老_阮 发表于 2025-7-2 03:34
感谢大师分享!
感谢支持!感谢支持! totomman 发表于 2025-7-2 08:21
感谢大师分享
感谢支持!感谢支持! 感谢大师分享 技术流!造福我等小白!感谢楼主!
页:
[1]