ELF格式分析动态链接原理

深入解析ELF文件格式:从链接、加载到动态链接的完整指南 在计算机系统中,可执行文件是程序运行的载体,其内部结构决定了操作系统如何加载和执行代码。ELF(Executable and Linkable Format)作为Linux和类Unix系统的标准二进制文件格式,通过其精密的节(Section)与段(Segment)结构,定义了代码、数据、符号等信息的组织方式。这种结构化设计不仅解决了多文件编译时的符号解析与地址重定位问题,实现了高效的静态链接,还通过程序头表为操作系统加载器提供了清晰的“装载指南”,确保了程序能正确映射到内存。在工程实践中,动态链接技术进一步 阅读详情

1. 背景

语言:C

平台:arm32

编译工具:arm-gcc

2. 问题

  • 程序A引用动态B.so中的全局变量和函数,全局变量和函数地址在编译时不确定,只有B.so装载时确定,那么如何实现才能满足装载B.so的不动态修改A的代码段中的地址?
  • 地址无关代码是什么意思? 为什么动态库要生成位置无关代码?
  • 反汇编代码中经常看到类似bl  xxx@plt是什么意思?

3. 地址无关代码

  •  概念:程序主要由指令和数据组成,链接器会为每条指令和数据分配独立的地址,当指令要访问数据时,访问的数据的绝对地址。动态库在编译阶段,数据和函数的最终地址是无法确定,需要等到动态装载时方可确定,希望程序模块中的指令在装载时不需要因为装载地址的改变而改变,所以实现的基本思想就是:把指令中需要被修改的部分分离处理,跟数据部分放在一起。这样指令部分就可以保持不变。这样的方案称为地址无关代码技术(PIC, Position-independent code)。
  • 地址引用方式分类:

        共享模块中的地址引用按照是否跨模块分成两类:模块内引用和跨模块引用;按照不同的引用方式又可以分为:指令引用和数据访问,故可以分为四类
        Type1: 模块内数据访问。比如模块内定义的全局变量,静态变量。

        Type2: 模块内函数调用。

        Type3: 模块外部的数据访问:比如其他模块中定义的全局变量。

        Type4: 模块外部的函数调用。

示例代码:

module.so:

module.h
    void module_dump();

module.c
#include"module.h"                                                                                                                    

int global_module = 10;

void module_dump() {
    global_module += 1;
}
~  

elf.c:

int local_global_init = 10;
extern global_module;


void bar() {
    int a = 0;
    int b = 1;
}

void show() {
    //Type 1
    local_global_init +=1;
    //Type3
    global_module += 2;
    //Type2
    bar();
    //Type4
    module_dump();
}   

 编译:
 

arm-linux-androideabi-gcc -fPIC -shared module.c -o module.so
arm-linux-androideabi-gcc -o elf -fPIE -o elf elf.c ./module.so

show函数的反汇编代码:

00000534 <show>:
 534:   e92d4800    push    {fp, lr}
 538:   e28db004    add fp, sp, #4
 53c:   e59f3044    ldr r3, [pc, #68]   ; 588 <show+0x54>
 540:   e08f3003    add r3, pc, r3
 544:   e59f2040    ldr r2, [pc, #64]   ; 58c <show+0x58>
 548:   e08f2002    add r2, pc, r2
 54c:   e5922000    ldr r2, [r2]
 550:   e2821001    add r1, r2, #1
 554:   e59f2034    ldr r2, [pc, #52]   ; 590 <show+0x5c>
 558:   e08f2002    add r2, pc, r2
 55c:   e5821000    str r1, [r2]
 560:   e59f202c    ldr r2, [pc, #44]   ; 594 <show+0x60>
 564:   e7932002    ldr r2, [r3, r2]
 568:   e5922000    ldr r2, [r2]
 56c:   e2822002    add r2, r2, #2
 570:   e59f101c    ldr r1, [pc, #28]   ; 594 <show+0x60>
 574:   e7933001    ldr r3, [r3, r1]
 578:   e5832000    str r2, [r3]
 57c:   ebffffe2    bl  50c <bar>
 580:   ebffff9f    bl  404 <module_dump@plt>
 584:   e8bd8800    pop {fp, pc}
 588:   00001a98    muleq   r0, r8, sl
 58c:   00001ab8            ; <UNDEFINED> instruction: 0x00001ab8
 590:   00001aa8    andeq   r1, r0, r8, lsr #21
 594:   fffffffc            ; <UNDEFINED> instruction: 0xfffffffc


Disassembly of section .data:                                                                                                                              

00002008 <local_global_init>:
    2008:   0000000a    andeq   r0, r0, sl

类型一:模块内部数据访问

        local_global_init +=1;对应的反汇编代码

//r2是地址58c处的值即:00001ab8 
544:   e59f2040    ldr r2, [pc, #64]   ; 58c <show+0x58>
//r2 = pc + r2 = 550 + 1ab8 = 2008
548:   e08f2002    add r2, pc, r2
//r2 = 地址2008处的值:0x0a ,即r2 = 10
 54c:   e5922000    ldr r2, [r2]
//r1 = r2 + 1 = 10 + 1 = 11
 550:   e2821001    add r1, r2, #1


00002008 <local_global_init>:                                                                                                                              
    2008:   0000000a    andeq   r0, r0, sl

根据上面汇编代码看,为何跳转到 local_global_init地址处,show代码段计算出来当前pc值和.data代码段中local_global_init相对偏移offset(1ab8),pc + offset即可访问到local_global_init变量,这是相对跳转。

类型二:模块内函数调用

        四种情况中最简单的情况,因为被调用的函数与调用者之间处于同一个模块,它们之间的相对位置是固定的,所以这种情况比较简单。

      57c:   ebffffe2    bl  50c <bar> //bl即相对跳转指令

bl指令可以参考:arm push/pop/b/bl汇编指令_nginux的博客-优快云博客

类型三:模块外部变量访问

        模块间数据访问比模块内稍微复杂一点,因为模块间的数据访问目标地址需要等到装载时才能确定,比如上面例子中global_module变量,他被定义在外部模块,即动态库module.so中,并且该地址要动态库装载时才确定。前面提到地址无关代码,基本思想就是将地址相关的部分放到数据段,ELF的做法是在数据段里面建立一个指向这些变量的数据 ,也被称为全局偏移表(Global Offset Table, GOT)。当代码需要引用该全局变量时,可以通过GOT中相对应的项间接引用。

 //先计算.got表的函数表(_GLOBAL_OFFSET_TABLE_)的相对偏移
 //r3 = 588地址处的值,即 1a98
 53c:   e59f3044    ldr r3, [pc, #68]   ; 588 <show+0x54>

 //r3 = pc + r3 = 548 + 1a98 = 1FE0                                                                                                 
 540:   e08f3003    add r3, pc, r3
 ....

 //r2 = 地址594处的值,即ffffffc,这是-4的补码。
 560:   e59f202c    ldr r2, [pc, #44]   ; 594 <show+0x60>

 //r2 = r3 + r2地址处的值,即1FE0 - 4 = 1FDC,这个地址存储的是global_module变量的地址
 564:   e7932002    ldr r2, [r3, r2]

 //获取global_module数值,放到r2寄存器
 568:   e5922000    ldr r2, [r2]
 56c:   e2822002    add r2, r2, #2
 570:   e59f101c    ldr r1, [pc, #28]   ; 594 <show+0x60>
 574:   e7933001    ldr r3, [r3, r1]
 578:   e5832000    str r2, [r3]
 57c:   ebffffe2    bl  50c <bar>
 580:   ebffff9f    bl  404 <module_dump@plt>
 584:   e8bd8800    pop {fp, pc}
 588:   00001a98    muleq   r0, r8, sl
 58c:   00001ab8            ; <UNDEFINED> instruction: 0x00001ab8
 590:   00001aa8    andeq   r1, r0, r8, lsr #21
 594:   fffffffc            ; <UNDEFINED> instruction: 0xfffffffc

Disassembly of section .got:                                                                                                                               

//变量对应的GOT表
00001fc8 <_GLOBAL_OFFSET_TABLE_-0x18>:
    1fc8:   00001eb0            ; <UNDEFINED> instruction: 0x00001eb0
    1fcc:   00001ea0    andeq   r1, r0, r0, lsr #29
    1fd0:   00001e98    muleq   r0, r8, lr
    1fd4:   00001ea8    andeq   r1, r0, r8, lsr #29
    1fd8:   000005e4    andeq   r0, r0, r4, ror #11
    1fdc:   00000000    andeq   r0, r0, r0

//函数对应的GOT表
00001fe0 <_GLOBAL_OFFSET_TABLE_>:
    ...
    1fec:   000003cc    andeq   r0, r0, ip, asr #7
    1ff0:   000003cc    andeq   r0, r0, ip, asr #7
    1ff4:   000003cc    andeq   r0, r0, ip, asr #7
    1ff8:   000003cc    andeq   r0, r0, ip, asr #7
    1ffc:   000003cc    andeq   r0, r0, ip, asr #7

注意:arm elf平台变量和函数的got表都在.got section,而x86平台是分为了两个section。

图解上述流程:

流程描述:

        当要访问global_module外部变量时,程序先找到GOT,然后根据GOT中变量对应的表项找到global_module虚拟地址。arm32每个变量都对应一个4字节的地址,链接器装载模块的时候会查找变量的地址,然后填充GOT表中的各个项。由于GOT没有放在.text代码段,所以模块装载时可以动态修改,并且每个进程都可以有独立的副本,相互不受影响。

        GOT是如何做到跟指令的地址无关的?通过汇编代码我们可以看到,GOT表的和当前指令的offset偏移是可以确定的,通过offset相对偏移可解决使用绝对地址的问题。再根据外部变量在GOT中的偏移就可以确定变量的地址。当然GOT每个表项对应哪个变量的地址是由编译器自行决定的,通过objdump工具可以看到每个表项分别对应哪个变量。

        objdump -r elf(readelf -r也可以)可以读取rel.dyn变量重定位段,获取需要重定位的变量的相关信息,其中offset字段就是该变量的重定位地址对应的.got(GOT)的表项,比如global_module的offset = 1fdc(正如上面汇编计算的结果),对应的是.got(GOT)表中global_module的表项地址。

objdump -R elf

offset:global_module从elf头开始的offset,对应到某个.got表项
00001fdc UNKNOWN           global_module

readelf -S elf

...
17] .got              PROGBITS        00001fc8 000fc8 000038 00  WA  0   0  4
...

.got section的地址是1fc8,global_module对应的的.got表项地址:1fdc。

类型四:模块外部函数调用

延迟绑定(PLT)

        通过上面类型三外部变量通过GOT表跳转,很自然的想到外部函数调用也可以使用相同的方式来实现,不过现实中编译器并没有这么简单的实现,其中主要涉及一个性能问题:动态链接下,程序模块包含了大量的函数引用(全局变量相对较少,不然程序模块间耦合很大),程序的运行过程中,很多函数在程序结束前都不会被调用到(比如一些错误处理或者很少用到的功能模块),如果程序装载时就把所有的函数都链接好,解析出来实际的地址将是一种浪费。所以EFL采用了一种延迟绑定(Lazy Binding)的做法,基本思想:函数第一次调用时绑定(符号查找,重定位等),如果没有调用,则不进行绑定。所以程序开始时,模块间的函数调用都没有进行绑定,而是需要用到时才由动态链接器来负责绑定。这样的做法可以大大加速程序的启动速度。

PLT基本原理和实现

        外部函数引用时不直接跳转到GOT表,而是先间接跳转到叫做PLT项的结构。每个外部函数在PLT中都有一个相应的项,比如module_dump函数在PLT中的地址称为module_dump@plt。

module_dump@plt会跳转到对应的GOT表项,函数未执行前,该表项指向了plt section首地址,该首地址会跳转到符号解析函数,解析出来module_dump实际的地址,填入GOT对应的表项,GOT表项填充以后就可以跳转到module_dump函数。


00000404 <module_dump@plt>: 
 //ip = pc + 0 = 40c                                                                                                                               
 404:   e28fc600    add ip, pc, #0, 12

 //ip = ip + 0x1000 = 40c + 0x1000 = 0x140c
 408:   e28cca01    add ip, ip, #4096   ; 0x1000

 //pc = [0x140c + 0xbec] = [1ff8]
 //1ff8地址指向了GOT表
 40c:   e5bcfbec    ldr pc, [ip, #3052]!    ; 0xbec

readelf -r elf指令可以读取plt具体的内容,比如:
Relocation section '.rel.plt' at offset 0x458 contains 8 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00001fe0  00000316 R_ARM_JUMP_SLOT   00000000   __libc_init@LIBC
00001fe4  00000216 R_ARM_JUMP_SLOT   00000000   __cxa_atexit@LIBC
00001fe8  00000416 R_ARM_JUMP_SLOT   00000000   __register_atfork@LIBC
00001fec  00000116 R_ARM_JUMP_SLOT   00000000   printf@LIBC
00001ff0  00000716 R_ARM_JUMP_SLOT   00000000   malloc@LIBC
00001ff4  00000a16 R_ARM_JUMP_SLOT   00000000   xhook_register
00001ff8  00000916 R_ARM_JUMP_SLOT   00000000   xhook_refresh
00001ffc  00000816 R_ARM_JUMP_SLOT   00000000   say_hello

malloc@LIBC代表,在ELF的1ff0地址处理,存放的是libc库malloc地址。

Disassembly of section .got:

00001fc8 <_GLOBAL_OFFSET_TABLE_-0x18>:
    1fc8:   00001eb0            ; <UNDEFINED> instruction: 0x00001eb0
    1fcc:   00001ea0    andeq   r1, r0, r0, lsr #29
    1fd0:   00001e98    muleq   r0, r8, lr
    1fd4:   00001ea8    andeq   r1, r0, r8, lsr #29
    1fd8:   000005e4    andeq   r0, r0, r4, ror #11
    1fdc:   00000000    andeq   r0, r0, r0

//可以看到3cc指向了plt section首地址
00001fe0 <_GLOBAL_OFFSET_TABLE_>:
    ...
    1fec:   000003cc    andeq   r0, r0, ip, asr #7
    1ff0:   000003cc    andeq   r0, r0, ip, asr #7
    1ff4:   000003cc    andeq   r0, r0, ip, asr #7
    1ff8:   000003cc    andeq   r0, r0, ip, asr #7                                                                                                         
    1ffc:   000003cc    andeq   r0, r0, ip, asr #7



Disassembly of section .plt:

//这段汇编实现跳转到符号解析函数,函数地址解析完比填入1ff8地址中
//最终跳转到GOT表+8偏移处,即链接器符号解析函数,编译阶段无法确定,加载时填充,初始化0.
000003cc <__libc_init@plt-0x14>:                                                                                                                           
 3cc:   e52de004    push    {lr}        ; (str lr, [sp, #-4]!)
 3d0:   e59fe004    ldr lr, [pc, #4]    ; 3dc <note_end+0x1fc>
 3d4:   e08fe00e    add lr, pc, lr
 3d8:   e5bef008    ldr pc, [lr, #8]!
 3dc:   00001c04    andeq   r1, r0, r4, lsl #24

000003e0 <__libc_init@plt>:
 3e0:   e28fc600    add ip, pc, #0, 12
 3e4:   e28cca01    add ip, ip, #4096   ; 0x1000
 3e8:   e5bcfc04    ldr pc, [ip, #3076]!    ; 0xc04

图解流程:

 跳转到外部函数module_dump函数流程:

1. bl module_dump@plt

        先跳转到module_dump@plt汇编代码处,即PLT机制的间接跳转

2. module_dump@plt代码

        module_dump@plt会跳转到GOT表中module_dump的表项,如果时非首次调用。0x3cc处已经填充了实际的函数地址,直接跳转到函数地址执行即可。如果是首次调用module_dump函数,GOT表项中默认填充的是.plt的首地址(比如示例代码代码.plt section首地址0x3cc),跳转到3cc处执行

3. .plt section

        跳转到.plt section首地址处执行代码,该处代码会会跳转到GOT表项的第三项,存储的是链接器的符号解析函数(装载时才能确定该地址,初始化时为0)

4. 跳转到符号解析函数

        .plt section首地址处代码执行会跳转到链接器符号解析函数,函数解析到module_dump地址后填充到GOT module_dump的表项,即3cc值被替换成实际的函数地址。

Linux内核分析:实验七--Linux内核如何装载和启动一个可执行程序 刘畅 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000写在前面本次实验着力分析Linux内核装载和启动一个可执行程序的过程,其中包括可执行文件格式的分析、可执行文件的装载和链接的过程,并通过GDB跟踪execve系统调用来梳理Linux系统加载可执行程序的过程。可执行文件的格式分析相对于其它文件 阅读详情

相关推荐

深入解析ELF文件格式:从链接加载到进程创建的全链路剖析

可执行文件格式是操作系统加载和运行程序的基础,它定义了二进制代码、数据及元数据的组织方式。ELF(Executable and Linkable Format)作为Linux和类Unix系统的标准格式,其核心原理在于通过文件头、程序头表和节头表等结构,将静态的二进制文件映射为动态的进程内存空间。理解ELF的技术价值在于,它不仅是程序执行的载体,更是链接、加载、动态库绑定等系统机制的关键实现基础。在应用场景上,ELF广泛应用于系统编程、安全分析、性能优化和嵌入式开发等领域,帮助开发者解决符号解析、内存布局和动

weixin_34268310的博客 395

动态链接(ELF文件)

动态链接(ELF文件)

weixin_51758733的博客 323

FPGA新手避坑指南:手把手教你搞定RTL8211千兆网PHY的时序配置(附Verilog代码)

本文详细解析了FPGA与RTL8211千兆网PHY芯片的时序配置问题,重点介绍了TXDLY/RXDLY引脚设置、FPGA发送端和接收端的Verilog实现,以及调试与验证的完整流程。通过硬件电路设计和代码示例,帮助开发者解决网络连接不稳定、丢包等常见问题,提升千兆网通信的稳定性。

weixin_28732953的博客 539

Linux eBPF内核源码sample/bpf全网最细解析(一)

本文重点讲解samples/bpf/sockex1_kern.c和samples/bpf/sockex1_user.c这两个文件,并剖析了它们调用的其他外部函数。

尧fighting的博客 4358

DDR核心机制解析:从Burst到Prefetch的性能跃迁

本文深入解析了DDR内存性能跃迁的核心机制,重点阐述了Burst(突发传输)与Prefetch(预取)技术的协同工作原理。Burst机制通过连续传输数据减少访问延迟,而Prefetch则通过内部预取数据提升吞吐量,两者结合完美匹配现代CPU缓存行需求,是DDR3等内存实现高效带宽的关键。

weixin_29232121的博客 135

Vue+ECharts-GL 3D地图实战:5层叠加打造炫酷中国地图(附完整代码)

本文详细介绍了如何利用Vue和ECharts-GL构建具有强烈立体感的3D中国地图。通过5层图层的巧妙叠加与样式调校,实现了从背景阴影到交互高光的完整视觉层次,并整合了动态飞线与散点标记。文章提供了完整的代码实现、核心配置解析以及性能优化与视觉调优的实战技巧,帮助开发者快速打造专业级的交互式地图可视化应用。

d6e7f8g9h的博客 649

C温故补缺(十七):动态链接(ELF,PIC,GOT,PLT)

在数据段中,编译器创建为了GOT表,GOT表包括多个表项,每个表项里存储一个地址,GOT[0]~GOT[3]是内置的表项,从GOT[4]开始,每个函数一个表项,例如GOT[4]是第一个函数引用的表项,GOT[5]为第二个函数引用的表项,编译器生成可执行文件时,GOT[4]中存储的地址总是指向了PLT[2]表项的第二条指令,GOT[5]中存储的地址总是指向了PLT[3]表项的第二条指令,因此类推。0x4005c0为PLT[2]表项的地址,这个地址是个相对地址,与内存无关的,生成可执行文件时,就已经确定了。

Chocolate的博客 267

【人工智能】《Deep Dive into LLMs like ChatGPT 》—— Andrej Karpathy 第三阶段:强化学习(Reinforcement Learning, RL)

摘要:强化学习(RL)阶段通过让模型自主生成并验证答案,突破SFT阶段的模仿局限,使其在数学、代码等领域形成独特的推理路径。RL流程包括批量生成解答、自动批改筛选正确路径,并采用PPO/GRPO算法优化模型。模型会自发涌现自我检查、回滚等策略,显著提升正确率(如AIME竞赛准确率从15%升至56%)。与SFT模型相比,RL模型具备主动链式思维、验算能力,响应时间更长但效果更优,形成真正的“思考模型”。三阶段对比显示,RL通过可验证题的对错奖励机制,赋予模型超越人类范式的推理能力。

奶爸的编程之路,也就一周冷个三天 149

计算机财务管理第五版第四章课后答案,计算机财务管理习题精简版

计算机财务管理习题第一、二章 EXCEL的基本理论一、单选题1.下列符号中不属于比较运算符的是( )A <= B >= C <> D ><2.EXCEL存储单位是工作本,作为一个文件,其扩展名为 ( )A XLS B DBT C ...

weixin_30784365的博客 3218

大数据分析利器:Tableau实战教程从入门到精通

你有3家分店,每月收集1000条销售数据(日期、分店、口味、销售额、订单数);想用Excel分析“哪家分店最赚钱”,但要做透视表→改格式→画柱状图,耗时30分钟,还经常因为公式错误返工;想看看“草莓味奶茶的月度销量趋势”,得手动筛选数据、调整折线图轴范围,稍不注意就漏看关键节点;想把分析结果分享给合伙人,Excel表格太抽象,对方盯着数字问“你到底想告诉我什么?

AI架构师小马 1491

【目标检测】基于yolov5的安全帽佩戴检测系统(附代码和数据集)

【目标检测】基于yolov5的安全帽佩戴检测系统(附代码和数据集)

学无止境、积少成多、厚积薄发 3105

bin和elf文件(ARM) 五

原文地址:http://www.iteye.com/topic/1121480 近段时间在研究Erlang核心特性的实现,也许过段时间会有个系列的总结,期待...   今天看到有人写一个深入Hello World的文章,想起来读研的时候做的一个关于程序加载和链接的课程设计,也是以Hello World为例说明的,随发出来共享。文后有下载链接。   ==================

yazhouren的专栏 1831

Xilinx FPGA平台DDR3设计保姆式教程(1)DDR3基础简介

xilinx平台DDR3设计(1)DDR3简介 如果我们只是拿来用ddr搬砖,那么它就简单,知道IP怎么使用就好,但是要想知其所以然,理论知识是必备的,这也是我们初学者所欠缺的东西,慢慢修炼吧! 目录 一、DDR3简介 二、地址的概念及容量计算 三、重要给概念理解 3.2 列地址脉冲选通潜伏期 3.4 掩码 四、参考资料 一、DDR3简介 DDR3全称double-data-rate 3 synchronous dynamic RAM,即第三代双倍速率同步动态随机存储器。...

数字IC/FPGA杂货铺,找一找,或许有你想要的~ 1万+

ELF文件的加载和动态链接过程

近段时间在研究Erlang核心特性的实现,也许过段时间会有个系列的总结,期待... 今天看到有人写一个深入Hello World的文章,想起来读研的时候做的一个关于程序加载和链接的课程设计,也是以Hello World为例说明的,随发出来共享。文后有下载链接。 ====================================================== 本文...

一墨的博客 1356

2023年GESP12月认证C++五级真题解析

例如,如果a=4,那么4是最⼩的幸运数,而1不是,但我们可以连续对1做3次+1操作,使其变为4,所以我们可以说,1幸运化后的结果是 4。【题目大意】给一个完全平方数的标准,推导出哪些是超级幸运数,然后判断N个数字中,哪些是超级幸运数,是的输出“lucky”,不是的输出离该数字最近的比它大的数字。前一个数字,下标是j的数字是偶数,后面的数字下标是j+1的是奇数,按照要求,偶数在奇数的后面,要交换。A函数时间复杂度是O(n/2),B函数算法是O(sqrt(n)),大部分情况后者是优的,值更小。

lan_in的博客 1006

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

i386 Linux下 ELF 动态链接分析 (一)

导读: Aug 29i386 Linux下 ELF 动态链接分析 (一)work Add commentsIan Lance Taylor正在写连载文章介绍linkers。一直想了解dynamic linking的过程,于是正好就学习了一下。program loader、program linker和dynamic linker的具体工作过程暂不在讨论范围。首先,随便写个小程

xu的blog 2702

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ELF文件与链接

什么是ELF文件 ELF文件头部格式 ELF在计算机科学中,是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。 ELF文件种类 ELF文件组织格式 ELF文件由4部分组成...

TSZ0000的博客 2245

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Linux ELF 详解:从定义到底层原理

ELF 是 Linux 系统底层的「二进制文件标准」,其核心价值在于统一链接和加载的接口对开发者:编译(gcc)生成.o目标文件,链接(ld)生成可执行文件 / 共享库,无需关注底层格式细节。对系统:加载器(内核)和动态链接器()通过 ELF 头部和表结构,标准化地完成程序加载和运行。理解 ELF 的结构和流程,是深入掌握 Linux 程序运行原理、动态链接、调试崩溃问题的关键基础。建议结合readelfobjdump工具实际分析一个简单的 C 程序(如hello.c编译后的a.out。

我的博客主要是用来给我自己复习的,主要是上传一些知识点,小型的项目和功能模块,如果有什么问题或错误麻烦联系我! 1087

ELF文件及android hook原理

可执行和可链接格式(Executable and Linkable Format,缩写为ELF),常被称为ELF格式,在计算机科学中,是一种用于执行档、目的档、共享库和核心转储的标准文件格式。

A blog 6809

plt、.plt.got, ELF entry point和装载地址

ELF entry point和装载地址 https://blog.youkuaiyun.com/ayu_ag/article/details/50737209 GOT表和PLT表知识详解 https://blog.youkuaiyun.com/qq_18661257/article/details/54694748?locationNum=1&fps=1 深入了解GOT,PLT和动态链接 https://www.cnblogs.com/pannengzhi/p/2018-04-09-about-got-plt.h

happylzs2008的专栏 375

程序员的自我修养--链接、装载与库笔记:Windows下的动态链接

Windows下的PE的动态链接与Linux下的ELF动态链接相比,有很多类似的地方,但也有很多不同的地方。 1. DLL简介 DLL即动态链接库(Dynamic-Link Library)的缩写,它相当于Linux下的共享对象。Windows系统中大量采用了这种DLL机制,甚至包括Windows的内核的结构都很大程度依赖于DLL机制。Windows下的DLL文件和EXE文件实际上是一个概念,...

网络资源是无限的 1419

ELF文件格式

本文介绍了Linux可执行文件的ELF格式结构。主要内容包括:ELF文件由Header、Program Headers(段表)和Section Headers(节表)组成;详细解析了ELF Header结构体;列举了readelf和objdump等常用分析工具;解释了段(Segment)与节(Section)的区别及常见节的功能;说明了动态链接通过.plt和.got实现的机制。文章最后总结了ELF的关键组成部分,并预告下篇将介绍ARM汇编基础。

yydszycheng 429

plt文件格式c++读取_ELF文件格式解析

原创: S3cana 合天智汇原创投稿活动:https://mp.weixin.qq.com/s/Nw2VDyvCpPt_GG5YKTQuUQELF文件格式的相关知识是Linux下进行pwn以及reverse的基础,是二进制可执行文件的一种形式,下面我们通过一个ELF文件的生成,并结合其ELF文件结构分析一下一个二进制文件在系统中执行时与权限相关的一些ELF结构知识点。文章内容较为浅显,大佬可略过...

weixin_33404792的博客 1748

《Linux 内核原理与分析》第 8 周作业

execve()

m0_53304143的博客 984

elf文件查找函数的过程

要反编译的程序:hello.c#includeint main(){   printf("Hello World!/n");   return 0;} 1.对hello进行反汇编,并查找包含"printf"的行;可以看到它调用了地址0x80482b0的函数;[root@localhost src]# objdump -d hello | grep printf080482b0 : 804838c:

贾亮的专栏 2530

2021-2022-1 20212813《Linux内核原理与分析》第八周作业

Linux 内核如何装载和启动一个可执行程一、基础知识1、编译链接的过程2、ELF 可执行文件格式3、静态链接和动态链接静态链接动态链接二、实验过程1、跟踪分析execve 系统调用内核处理函数sys_execve三、遇到的问题 一、基础知识 1、编译链接的过程 程序从源代码到可执行文件需要经过以下步骤: 预处理、编译、汇编、链接,如下图所示,每一步产生不同的文件。 各步骤的任务如下: 预处理:删除所有注释;删除所有的“#define”,展开所有的宏定义;处理所有的条件预编译指令;添加行号和文件名标识等

zzx751775692的博客 1279
上一篇: 汇编视角分析C++虚函数实现原理
下一篇: arm/arm64函数栈帧(stackframe)结构和传参规则
OS技术解密
博客等级 码龄16年 3760粉丝 189原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值