Linux kernel 如何在不破坏linux内核模块的情况下,从linux内核模块中剥离本地符号?

Linux kernel 如何在不破坏linux内核模块的情况下,从linux内核模块中剥离本地符号?,linux-kernel,strip,kernel-module,Linux Kernel,Strip,Kernel Module,如果我执行--strip debug或--strip unneeded,我有.ko,它用nm列出所有函数名,如果我只执行strip foo.ko我有一个拒绝加载的内核模块 有人知道如何快速删除模块加载不需要的所有符号,从而使人们无法轻松地对API进行反向工程吗 PS:为了所有你们这些开源偏执狂传教士;这是一般公众在任何情况下都不会使用的东西,因此无需将此问题转化为GPL火焰战。我不确定我是否理解问题的实质: 在开发.ko时,如果我没有明确添加 ccflags-y += -ggdb -O0 -Wa

如果我执行
--strip debug
--strip unneeded
,我有
.ko
,它用
nm
列出所有函数名,如果我只执行
strip foo.ko
我有一个拒绝加载的内核模块

有人知道如何快速删除模块加载不需要的所有符号,从而使人们无法轻松地对API进行反向工程吗


PS:为了所有你们这些开源偏执狂传教士;这是一般公众在任何情况下都不会使用的东西,因此无需将此问题转化为GPL火焰战。

我不确定我是否理解问题的实质: 在开发.ko时,如果我没有明确添加

ccflags-y += -ggdb -O0 -Wall
在我的Makefile中,除了那些我自己发布或外部引用的符号,我没有得到任何符号。我确信我没有得到任何其他符号,原因有几个:

  • 生成的.ko文件要小得多
  • 转储文件并分析ELF显示表不存在
  • 我无法查看或访问kgdb中的符号
所以我对你的问题有点困惑,实际上?。。。您在.ko中看到了哪些符号(并且不想看到)? 如何在源文件中声明它们? 它们会在哪些ELF区域结束?
(抱歉,前面的问题很愚蠢):您是否定义了静态所有不需要在自己模块之外看到的东西?

对于我之前的问题没有答案,下面是一些猜测,也可能是一些线索,以及答案的一步:

据我所知,.ko只不过是源模块生成的所有.o文件合并后生成的一个.o文件,并添加了一个.modinfo部分。 在任何.ko构建Makefile的末尾,都有一个LD调用:据我所知,LD是用-r选项调用的,这就是创建Makefile调用的.o文件的原因。不要将此结果文件与存档或对象库(.a文件)混淆,后者只是将多个.o文件存档/打包为一个文件的格式:合并的对象是生成另一个.o模块的链接的结果:但在结果模块中,可以合并的所有部分都已,所有可以解析的公共/外部对都在这些部分中。 因此,我假设您的.ko文件包含所有“本地”外部定义:

  • 那些是外部的,因为他们 是用来打电话的 .ko中的模块(但不是 不再需要了,因为它们不是 应该是从外面打过来的 (www.ko),及

  • 那些.ko模块确实需要 与装载机正确通信 和内核

前者很可能已经在合并过程中由ld解决,但ld无法知道您是否打算从.ko外部调用它们

因此,您看到的无关符号是每个.o文件的外部符号,但不需要作为结果.ko的外部符号。 你要找的是一种只剥掉那些东西的方法

最后一段是否恰当地描述了您想要去除的符号


我想这正是我们的本来面目 在这里谈论

好的,那么看起来一个解决方案是“手动”删除多余的符号。“strip”实用程序似乎允许单独剥离(或保留)符号,因此您必须使用一个--strip all和一小束--keep symbol=。请注意,——通配符也可能会有所帮助。当然,你可以做相反的事情,根据最方便的方式,让所有的和单独的衣服都脱光

一个好的开始可能是删除模块中为交叉模块链接而明确定义的所有符号,并且不希望出现——只留下明显有用的符号,比如init和exit。并且不要接触那些由内核开发软件基础设施生成/属于内核开发软件基础设施的内容。然后反复尝试,直到找到正确的配方。。。事实上,我认为除了那些您明确定义自己为EXPORT_SYMBOL(当然还有init/exit)的符号之外,您自己的所有符号都可能是可移动的

祝你好运!:)

附言:


事实上,所有.ko项目中似乎都存在自动执行所需剥离的所需源信息:除非我遗漏了什么,否则在“ld-r”末尾,理论上可以默认剥离构建软件未导出或显式插入的任何内容结束.ko构建的时间。只是我认为工具链(编译器/链接器)没有规定/指令/选项来单独指定可重定位链接/合并的“剥离或保留”符号。否则,在EXPORT_SYMBOL宏和其他一些地方进行一些修改可能会达到您想要的结果,并从任何Linux系统中的大多数.ko文件中删除一些字节。

除了filofel的帖子:


剥离用户空间共享库使其保持正常运行的原因是,它们导出的符号位于从未剥离的
.dynsym
部分
.ko
文件不使用dynsym。

有人报告成功使用了

strip --strip-unneeded 

我只是构建了一个内核,没有意识到内核配置启用了调试符号,所以生成的模块的大小相当大。这对我很有用:

# du -sh /lib/modules/3.1.0/
1.9G    /lib/modules/3.1.0/
# find /lib/modules/3.1.0/ -iname "*.ko" -exec strip --strip-debug {} \;
# du -sh /lib/modules/3.1.0/
134M    /lib/modules/3.1.0/

/lib/modules/3.1.0
中找到名为
*.ko
的所有文件,并对每个文件执行
strip--strip debug

strip-g XXX.


我之前的问题,比如你所发生的事情,是通过在嵌入式设备上使用
Linux内核3.0.8

的这个命令解决的。如果你真的想避免一场火焰战争,我建议不要把人们概括为偏执狂:)说得好,蒂姆:)现在更好了吗?:DIf“大众”