标签: elf

将运行Linux进程中的内存地址范围转换为目标文件中的符号?

这是文件/ proc/self/smaps的片段:

00af8000-00b14000 r-xp 00000000 fd:00 16417      /lib/ld-2.8.so
Size:                112 kB
Rss:                  88 kB
Pss:                   1 kB
Shared_Clean:         88 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:           88 kB
Swap:                  0 kB
00b14000-00b15000 r--p 0001c000 fd:00 16417      /lib/ld-2.8.so
Size:                  4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Swap:                  0 kB
Run Code Online (Sandbox Code Playgroud)

它表明这个进程(self)链接到/lib/ld-2.8.so和两个(中的很多)字节范围映射到内存中.

第一个88kb(22个4kb页面)的范围是共享干净的,这是它没有被写入.这可能是代码. …

linux memory debugging symbols elf

4
推荐指数
1
解决办法
3315
查看次数

链接器如何在没有SONAME的情况下找到共享库

如果我创建一个没有像这样的SONAME的共享库

gcc -shared libfoo.o -o libfoo.so
Run Code Online (Sandbox Code Playgroud)

并链接它,链接器如何找到我的共享库?

libfoo.so链接器将文件名视为默认SONAME吗?

gcc shared-libraries elf

4
推荐指数
1
解决办法
6426
查看次数

CPU依赖代码:如何避免函数指针?

我有为多个CPU编写的性能关键代码.我在运行时检测CPU,并根据检测到的CPU使用适当的函数.所以,现在我必须使用函数指针并使用这些函数指针调用函数:

void do_something_neon(void);
void do_something_armv6(void);

void (*do_something)(void);

if(cpu == NEON) {
    do_something = do_something_neon;
}else{
    do_something = do_something_armv6;
}

//Use function pointer:
do_something(); 
...
Run Code Online (Sandbox Code Playgroud)

这并不重要,但我会提到我已经针对不同的cpu优化了功能:armv6和armv7以及NEON支持.问题是通过在许多地方使用函数指针,代码变得更慢,我想避免这个问题.

基本上,在加载时,链接器使用函数地址解析relocs和patch代码.有没有办法更好地控制这种行为?

就个人而言,我提出了两种避免函数指针的方法:为cpu依赖函数创建两个独立的.so(或.dll),将它们放在不同的文件夹中,并根据检测到的CPU将这些文件夹中的一个添加到搜索路径中(或者LD_LIB_PATH).加载主代码和动态链接器将从搜索路径中获取所需的dll.另一种方法是编译两个独立的库副本:)第一种方法的缺点是它迫使我至少有3个共享对象(dll):两个用于cpu依赖函数,一个用于使用它们的主代码.我需要3,因为在加载使用这些cpu相关函数的代码之前,我必须能够进行CPU检测.关于第一种方法的好处是应用程序不需要为多个CPU加载相同代码的多个副本,它将仅加载将使用的副本.第二种方法的缺点是非常明显的,不需要谈论它.

我想知道是否有办法在不使用共享对象的情况下执行此操作并在运行时手动加载它们.其中一种方法是涉及在运行时修补代码的一些hackery,它可能太复杂而无法正确完成它).有没有更好的方法来控制加载时的重定位?也许将cpu依赖函数放在不同的部分,然后以某种方式指定哪个部分具有优先级?我认为MAC的男子气概有类似的东西.

ELF-only(针对手臂目标)解决方案对我来说已经足够了,我并不真正关心PE(dll's).

谢谢

c cpu arm elf ld

4
推荐指数
1
解决办法
1216
查看次数

如何防止用户读取存储在二进制文件中的字符串?

这是一个最小的测试用例:

#include <stdio.h>
#include <stdlib.h>

int main ( int argc , char **argv )
{
        const char abc [15] = "abcdefg\0";
        printf ("%s\n" , abc);
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

和你做strings test,你应该看到abcdefg,因为它存储在只读区域.

那么,使用"strings"命令阻止用户读取此字符串的最佳方法是什么,例如我不希望用户知道我的SQL短语

c c++ linux string elf

4
推荐指数
2
解决办法
1234
查看次数

如何查看ELF文件中包含的函数名称和参数?

如果查看文件的字节,我肯定会在其中看到一些函数名称。有什么工具可以帮我列出它们吗?甚至他们的参数呢?

linux cygwin elf

4
推荐指数
1
解决办法
3270
查看次数

如何构建elf解释器(ld-linux.so.2/ld-2.17.so)作为静态库?

如果我的问题不准确,我很抱歉,因为我没有很多与Linux相关的经验.我目前正在从头开始构建一个Linux(主要是遵循linuxfromscratch.org 7.3版的指南).我遇到了以下问题:当我构建一个可执行文件时,它会获得一个名为ELF解释器的硬编码路径.

readelf -l program
Run Code Online (Sandbox Code Playgroud)

显示类似的东西

[Requesting program interpreter: /lib/ld-linux.so.2]
Run Code Online (Sandbox Code Playgroud)

我跟踪这个库ld-linux-so.2是glibc的一部分.我对这种行为不是很满意,因为它使二进制文件非常不可移植 - 如果我改变/lib/ld-linux.so.2的位置,可执行文件不再有效,我找到的唯一"修复"是使用patchelf来自NixOS的实用程序将硬编码路径更改为另一个硬编码路径.出于这个原因,我想链接到l​​d库的静态版本,但不会生成.所以这是我的问题,请你解释一下如何构建glibc以便生成ld-linux.so.2的静态版本,以后我可以链接到我的可执行文件.我不完全理解这个ld库的作用,但我认为这是加载其他动态库(或者至少是glibc.so)的部分.我想动态链接我的可执行文件,但我希望动态链接器本身静态内置到它们中,因此它们不依赖于硬编码路径.或者我希望能够使用类似于LD_LIBRARY_PATH的环境变量设置解释器的路径,也许是LD_INTERPRETER_PATH.目标是能够生成可移植的二进制文件,无论目录结构如何,它都可以在具有相同ABI的任何平台上运行.

一些可能相关的背景:我正在使用Slackware 14 x86来构建i686编译工具链,所以整体来说它都是x86主机和目标.我正在使用glibc 2.17和gcc 4.7.x.

linux gcc glibc elf linux-from-scratch

4
推荐指数
1
解决办法
6956
查看次数

如何使用自定义elf解释器调试程序?

我可以像这样调试一些程序(比如/ bin/ls):

[ks@localhost ~]$ gdb -q --args /bin/ls
Reading symbols from /bin/ls...Reading symbols from /bin/ls...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Missing separate debuginfos, use: debuginfo-install coreutils-8.22-19.fc21.x86_64
(gdb) start 
Temporary breakpoint 1 at 0x402990
Starting program: /usr/bin/ls 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Temporary breakpoint 1, 0x0000000000402990 in main ()
(gdb) 
Run Code Online (Sandbox Code Playgroud)

在这里,我可以设置临时断点main并停止它.

但我必须使用这样的自定义精灵解释器运行程序:

[ks@localhost ~]$ gdb -q --args /lib64/ld-linux-x86-64.so.2 /bin/ls
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/usr/lib64/ld-2.20.so.debug...done.
done.
(gdb) start 
Function "main" not …
Run Code Online (Sandbox Code Playgroud)

debugging gdb elf ld

4
推荐指数
1
解决办法
1431
查看次数

以编程方式访问核心文件内存映像

从相应的ELF核心转储文件访问进程的内存映像的(正确)方法是什么?在某种程度上,我将能够检查特定的地址,比如0x12345678.

请记住,没有gdb可以使用,只是纯粹的C方法.libelf不鼓励图书馆使用,但不包括在内.

c core elf

4
推荐指数
1
解决办法
136
查看次数

我的C代码如何在运行时找到与地址对应的符号(在Linux中)?

给定函数或变量运行时地址,我的代码需要找出名称,如果是变量,则键入符号的信息.或至少提供足够的信息,以便以后离线提取名称(和类型信息).

这是Linux代码,假设调试信息可用.

我试着研究ELF文件格式,binutils以及除了主题之外的所有内容都是巨大的,所以我希望有人可以帮我缩小范围.

我可以看到以下类型的解决方案:

  • 找到当前加载到内存中的模块的代码/数据段的范围 - 怎么做?将地址的模块和段名称和偏移量保存在其段中.离线然后使用binutils在模块的调试信息中找到符号 - 再次,如何做?

  • 使用一些我不知道的API /系统服务在运行时找到符号和信息 - 如何?

先感谢您.

c linux elf debug-symbols binutils

4
推荐指数
2
解决办法
2234
查看次数

使用$ ORIGIN指定ELF二进制文件中的解释器不起作用

我正在使用patchelf修改已经编译的二进制文件的rpath和解释器.对patchelf的调用看起来像这样:

patchelf --set-interpreter "\$ORIGIN/lib/ld-linux-x86-64.so.2" --set-rpath "\$ORIGIN/lib" ./grep
Run Code Online (Sandbox Code Playgroud)

通过运行验证正确设置了readelf -l ./grep | grep interpreter这些输出,输出:

[Requesting program interpreter: $ORIGIN/lib/ld-linux-x86-64.so.2]
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试运行可执行文件时,出现以下错误:

-bash: ./grep: No such file or directory
Run Code Online (Sandbox Code Playgroud)

这似乎表明链接器存在问题.如果我指定一个绝对路径而不是使用$ORIGIN那么它似乎工作正常.

我想知道我在$ORIGIN这里使用的方式是否有些不正确,或者这可能是在系统级别上被禁用的东西?

linux linker elf

4
推荐指数
1
解决办法
883
查看次数