没有android手机确切内核头文件,绕过模块的版本检查,构建一个内核模块

有一次不小心把我的乐1pro(x800+)掉地上了,屏幕碎的很惨。现在乐视都倒了,这机器的配置也跟不上了,不值得换屏,但电容屏碎了也能操作,就像废物利用,做个下载器。但下载到手机再转存到nas上太麻烦了,就想到cifs挂载nas。下载了一个带root的rom刷机后,adb shell进入系统shell,执行cat  /proc/filesystems查看支持的文件系统,没有发现cifs,说明内核没有支持cifs.查看内核支持模块,决定自己编译一个cifs模块增加这个功能.从此开始了以下的踩坑之旅.

1.通过uname -a 查内核版本,尽量保证内核版本接近,这样出问题的可能性会比较小.

查出的内核版本是Linux localhost 3.10.84-perf-g9fc36aa #1 SMP PREEMPT Wed Oct 19 18:52:46 CST 2016 aarch64

访问https://github.com/ 搜索android kernel le msm8994    (msm8994是高通骁龙810的编号) 会找到几个项目

https://github.com/Silentlys/android_kernel_letv_msm8994的内核版本和我使用的相同,所以就使用这个了。

git clone https://github.com/Silentlys/android_kernel_letv_msm8994.git

下载编译器

git clone https://aosp.tuna.tsinghua.edu.cn/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/

这里使用了清华的开源镜像站代替google的,因为众所周知的原因,使用https://android.googlesource.com不能下载。

export PATH=$PATH:/root/Android/aarch64-linux-android-4.9/bin
export ARCH=arm64
export SUBARCH=arm64
export ANDROID_AARCH64=/root/Android/aarch64-linux-android-4.9/bin
export CROSS_COMPILE=aarch64-linux-android-

cd android_kernel_letv_msm8994

mkdir output

make O=output msm8994_defconfig

make O=output menuconfig

选上cifs相关模块 nls_utf8模块

cd output/
LANG=c make O=output DTC_EXT=dtc -j6

取手机中的./adb pull /proc/config.gz

编译时出现error, 提示complit7.h 没有

参考https://blog.csdn.net/u014418171/article/details/82659887

下载https://bitbucket.org/jonascardoso/toolchain_aarch64_travis/downloads/

https://bitbucket.org/jonascardoso/toolchain_aarch64_travis/get/517026371d60.zip

gcc编译器

https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/

都出现问题

查看编译linux内核所用的gcc版本

手机上 cat /proc/version

Linux version 3.10.84-perf-g9fc36aa (letv@pcnbj-cp033) (gcc version 4.9.x-google 20140827 (prerelease) (GCC) ) #1 SMP PREEMPT Wed Oct 19 18:52:46 CST 2016

翻墙google查gcc version 4.9.x-google 20140827 (prerelease) (GCC) 找到android.googlesource.com下git日志

更新git

git log|grep 4b341df71296

git branch
git checkout master
git branch
git log|grep 4b341df71296
git branch lex800gcc 4b341df712969ca2ac0c3cf6294260d406b9d9be
gic checkout lex800gcc
git branch
bin/aarch64-linux-android-gcc --version
LANG=c make O=aoutput DTC_EXT=dtc -j6
编译成功

下载模块到手机

./adb push cifs.ko /sdcard/cifs.ko
./adb push nls_utf8.ko /sdcard/nls_utf8.ko
./adb shell
su

dmesg -c

insmod cifs.ko

insmod: failed to load cifs.ko: Exec format error

dmesg -c

disagrees about version of symbol module_layout

linux内核模块验证错误问题。

经过多天的查找,找到https://blog.csdn.net/mr_pang_1991/article/details/50014211,参考此大神的博客

终于编译成功。

记录如下

创建一个模块firststep.c

内容

#include <linux/module.h>
#include <linux/init.h>


const struct kernel_symbol *(*find_symbol1)(const char *name, struct module **owner, const unsigned long **crc, bool gplok, bool warn) = (const struct kernel_symbol *(*)(const char *name, struct module **owner, const unsigned long **crc, bool gplok, bool warn))0xffffffc000281554; //0xffffffc00027cab4; 通过手机/proc/kallsyms导出的绝对地址,如果 地址全是0,可以echo 0 > /proc/sys/kernel/kptr_restrict  使用绝对地址是为了不进行crc的版本验证

int (*printk1)(const char *fmt, ...) = (int (*)(const char *fmt, ...))0xffffffc000bfeaac; //  0xffffffc000be3e94;

static const char *sym_array[] = {
"module_layout",
"request_key",
.....此处是cifs.mod.c和nls_utf8.mod.c中的____versions[]数组中的名列表
"register_nls",
"utf32_to_utf8",
"utf8_to_utf32",
};


int __init
find_symbol_init (void)
{
  const char *name;
  int index;
  const struct kernel_symbol *ksymbol;
  struct module *owner;
  const unsigned long *crc;
  bool gplok = true;
  bool warn = true;
  for (index = 0; index < ARRAY_SIZE (sym_array); index++)
    {
      name = sym_array[index];
      ksymbol = find_symbol1 (name, &owner, &crc, gplok, warn);
      if (ksymbol != NULL)
    printk1 (" %s", ksymbol->name);
      else
    printk1 ("<0>Failed to find symbol %s\n", name);
      if (crc != NULL)
    printk1 ("*crc : 0x%lx\n", *crc);
      else
    printk1 ("\n");
    }
  return 0;
}

void __exit
find_symbol_exit (void)
{
}

module_init (find_symbol_init);
module_exit (find_symbol_exit);

MODULE_LICENSE ("GPL");
MODULE_AUTHOR("SongTao");

创建Makefile文件

ifneq ($(KERNELRELEASE),)

    MODULE_NAME = firststep
#    $(MODULE_NAME)-objs := firststep.o
    obj-m := $(MODULE_NAME).o

else

    KERNELDIR ?= /root/Android/le3_10_84/android_kernel_letv_msm8994/aoutput  //内核编译输出路径
    PWD ?= $(shell pwd)
 

.PHONY: modules clean

modules:
    $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules
clean:
    rm -f *.o *.mod.c .*.*.cmd *.ko *.order *.symvers
    rm -rf .tmp_versions

endif

 

修改内核目录下scripts/Makefile.modpost文件,在$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE规则下的$(call if_changed_dep,cc_o_c)上面和下面都增加$(shell sleep 30),为了有足够的时间修改编译时生成的mod.c文件的内容

从手机中取一个ko文件,使用modprobe --show-modversions ufsd.ko查出手机正在使用的module_layout的crc值

0x2e7c00e9      module_layout 记录下来

LANG=c make

当生成firststep.mod.c时,立刻打开文件,修改文件中的module_layout对应的值为记录的。

编译完成后,下载到手机,加载模块后

执行dmesg可以看到需要的模块crc值。复制出来备用。

将这些值整理完成,重新编译cifs等模块前,删除对应的.mod.c文件,执行编译,.mod.c生成后,立刻修改文件中的值,编译完成下载到手机就可以insmod成功了。

insmod /sdcard/cifs.ko

ps #cifsiod
mount -t cifs -o username=guest,password=,iocharset=utf8 //IP地址/public /mnt/cifs

/mnt/cifs是手动创建的
mount -o bind /system/test/ /storage/sdcad0/111
chgrp sdcard_rw /storage/sdcad0/111
 

insmod /sdcard/cifs.ko
insmod /sdcard/nls_utf8.ko

ls -l /proc/1/ns

lrwxrwxrwx root     root              2019-12-18 23:38 mnt -> mnt:[4026531840]
lrwxrwxrwx root     root              2019-12-18 23:38 net -> net:[4026535318]

Usage: nsenter [OPTIONS] [PROG [ARGS]]

        -t PID          Target process to get namespaces from
        -m[FILE]        Enter mount namespace
        -u[FILE]        Enter UTS namespace (hostname etc)
        -i[FILE]        Enter System V IPC namespace
        -n[FILE]        Enter network namespace
        -p[FILE]        Enter pid namespace
        -U[FILE]        Enter user namespace
        -S UID          Set uid in entered namespace
        -G GID          Set gid in entered namespace
        --preserve-credentials  Don't touch uids or gids
        -r[DIR]         Set root directory
        -w[DIR]         Set working directory
        -F              Don't fork before exec'ing PROG
 

//nsenter -t 1 -m 4026531840 -n 4026535318

nsenter -t 1

mount -t cifs -o username=guest,password=,iocharset=utf8 //IP地址/public /sdcard/BdNetdisk

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值