我在Linux环境中,我需要创建一个程序来检索放置在其可执行文件的一个部分中的一些数据.那么,如何从内部获取指向程序某一部分(通过其名称)的指针?
我知道可以使用elf_getdata()段的索引作为参数传递给get和Elf_Datastruct,并且这个结构的一个字段是d_buf,它是指向实际数据的指针.但是,似乎该elf_getdata()函数将部分数据从文件复制到内存,这不是我想要的.我想要一个指向加载时加载到内存中的数据的指针.
伙计们,任何想法?
GDB采用什么方法来确定函数的长度?我注意到在从main()中删除了两个字节后,GDB认为该函数仍然是原始长度,所以我假设它使用了一些调试信息?
特别是,main()的结尾最初是:
0x00000000004005a1 <+133>: mov edi,0x4006ac
0x00000000004005a6 <+138>: call 0x4003a0 <puts@plt>
0x00000000004005ab <+143>: mov eax,0x0
0x00000000004005b0 <+148>: leave
0x00000000004005b1 <+149>: ret
Run Code Online (Sandbox Code Playgroud)
然后我删除了两个字节(在程序清单的早期):
0x000000000040059f <+131>: mov edi,0x4006ac
0x00000000004005a4 <+136>: call 0x40039e
0x00000000004005a9 <+141>: mov eax,0x0
0x00000000004005ae <+146>: leave
0x00000000004005af <+147>: ret
0x00000000004005b0 <+148>: nop
0x00000000004005b1 <+149>: nop
Run Code Online (Sandbox Code Playgroud)
即GDB认为整体长度仍然相同.我想知道GDB是如何做到这一点的.
该文件是以下类型:a.out:ELF 64位LSB可执行文件,x86-64,版本1(SYSV),动态链接(使用共享库),未剥离仅使用"gcc"创建,没有参数.
我正在处理一个大型可执行文件,我没有源代码(长篇故事).
我想从中提取几个函数的二进制代码 - 并尝试从我自己的程序中调用它们.我正在寻找的函数都是从相同的源文件(在Linux上使用gcc)编译的,如果重要的话.
我可以使用objdump看到函数的二进制代码.有没有什么方法可以说服工具转储函数的二进制代码 - 没有别的东西,没有拆解?
基本上,如果定义函数的C文件被称为foo.c,我想得到foo.o(我实际上更喜欢foo.So,但这不会存在于可执行文件中).可以用objdump,readelf或其他一些方法完成吗?
如果重要的话,这些功能是独立的.
谢谢!
我试图弄清楚 DWARF 2 debug_line 部分是如何编码的。标准论文(http://www.dwarfstd.org/doc/dwarf-2.0.0.pdf)对我没有多大帮助,我真的不明白像下面这样的事情:
.4byte .debug_line
.4byte 0x736e7502, 0x656e6769, 0x6e692064, 0x04070074
Run Code Online (Sandbox Code Playgroud)
代表某物。那里编码了“无符号整数”字符串,但前面的 0x02 值..这代表什么?我什至找不到带有 DWARF 2 常量的标准 enum/define 标头..有人可以解释一下如何解析 DWARF 2 中的 debug_line 吗?
我正在使用 GCC 在 ARM 上为 bada 构建一个 ELF SO。编译器选项包括 -fpic。然而,在构建的文件中,当我这样做时readelf -r,有很多重定位记录,类型如下:
我在这里误解了什么?
编辑:据我所知,编译器中的 PIC 实现不使用 GOT。相反,它们使用 PC 相对寻址,其中存储的常量是从使用点到符号地址的偏移量;这是由链接器解决的。像这样,读取一个全局变量:
ldr r12, OffsetToVar
PointOfUse:
ldr r0, [r12, pc]
# r0 now has the value of MyVar
#...
# At function's end...
OffsetToVar:
.long MyVar-PointOfUse-8
# Compiler can't resolve this, since it doesn't know
# the address of MyVar, but linker can
Run Code Online (Sandbox Code Playgroud)
跨模块函数调用的类似想法。但是,当项目混合使用 ARM 和 Thumb 代码时,后者可能会失火。但我已经解决了这个问题。
所以我的struct值在gdb中的"next"命令之后变为0,这应该没有效果.
166 RawElfSymbol *currSymb = symbolTabSec;
(gdb) p *currSymb
$8 = {name = 623313010, addr = 540682099, size = 1931505518, type_and_bind = 117 'u', ignored = 99 'c', section_tag = 8296}
(gdb) next
167 int sizeOfSymb = currSymb->size;
(gdb) p *currSymb
$9 = {name = 0, addr = 0, size = 0, type_and_bind = 0 '\000', ignored = 0 '\000', section_tag = 0}
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况的任何可能的解释?我无法弄清楚:/
如果这有帮助,这是RawElfSymbol结构:
typedef struct {
unsigned int name; // offset in bytes from start of string table …Run Code Online (Sandbox Code Playgroud) 我已经使用Android ndk建立了一个静态库。
我现在尝试在另一个Android项目中使用此库
//in mainActivity
static
{
System.loadLibrary("MILlib");
}
Run Code Online (Sandbox Code Playgroud)
构建测试项目时出现以下错误
02 17:07:24.890 2785-2785 / com.MIL.testlib E / AndroidRuntime:致命异常:主进程:com.MIL.testlib,PID:2785 java.lang.UnsatisfiedLinkError:dlopen失败:“ / data / app / com “ .MIL.testlib-1 / lib / arm / libMILlib.so”在java.lang.System.loadLibrary(System.java:989)处的java.lang.Runtime.loadLibrary(Runtime.java:371)处具有不良的ELF魔术com.MIL.testlib.MainActivity。(MainActivity.java:112),位于java.lang.reflect.Constructor。android.app.Instrumentation.newActivity(Instrumentation.java:1079)的java.lang.Class.newInstance(Class.java:1650)的newInstance(本机方法)android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2640)的java.lang.Class.newInstance(Class.java:1650)在android.app.ActivityThread $ H.handleMessage(ActivityThread.java :)在android.app.ActivityThread.access $ 900(ActivityThread.java:181)在android.app.ActivityThread.access $ 900(ActivityThread.java:181)1482)在android.os.Handler.dispatchMessage(Handler.java:102)在android.os.Looper.loop(Looper.java:145)在android.app.ActivityThread.main(ActivityThread.java:6145)在java。 com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1399)处java.lang.reflect.Method.invoke(Method.java:372)处的lang.reflect.Method.invoke(本机方法) com.android.internal。os.ZygoteInit.main(ZygoteInit.java:1194)
什么是不良的ELF魔术数,如何解决?
是否有可能有一个 ELF 文件包含来自两个 ISA 的可执行指令。也就是说,有一个 ELF 文件可以在两种架构上运行,例如 x86 和 PowerPC。
我想到的一个例子是几年前使用的 Apple 通用二进制文件。有什么方法可以在 Linux 发行版中实现类似的功能吗?我遇到过旨在做到这一点的 FatELF 项目,但它似乎已经死了
根据此ELF 规范:ELF 目标文件包含各种部分,其中之一是符号表部分 .symtab,其中包含所有符号(文件、函数、对象等)的信息。
ELF 包含符号表中每个符号的名称、属性标志、类型、值和绑定等信息。
文件、函数或对象(数组、变量、字符串)等的对象名称实际上暴露了代码的内部信息。这样,任何人都可以分析ELF(使用strings,objdump或readelf工具),看到此信息,并获得对事物的内部,其应当保密的代码的想法。
为了可读性和可维护性,我们编写了开发人员可以理解的代码。所以,我们需要继续使用正确的文件名和变量名等。我们不能使用代码混淆来掩盖它们,因为它会导致难以维护。
问题(已编辑):有什么方法可以在可执行 ELF 的符号表中隐藏或删除符号“名称”,以便没有人可以了解代码并且可执行文件仍然可以运行?
所以可执行文件包含不同的部分和标题.
在ELF Header我们可以看到一些关于它们的元数据,如不同标题的大小,起点等.
可执行文件的不同部分是否一次性加载到内存中?
如果是,如何/何时定义以及我们可以在哪里看到有关该信息的信息,因为ELF Header在该问题上似乎没有任何参数.
提前致谢.