当前位置: 首页 > news >正文

江苏省住房和城乡建设厅 官方网站百度付费推广有几种方式

江苏省住房和城乡建设厅 官方网站,百度付费推广有几种方式,网站是先制作后上线么,怀化市建设局门户网站目录 静态文件的缺点 动态链接 位置无关代码 延迟绑定 _dl_runtime_reslove 函数定义 深入审视 静态文件的缺点 随着可执行文件的增加 静态链接带来的浪费空间问题就会愈发严重 如果大部分可执行文件都需要glibc 那么在链接的时候就需要把 libc.a链接进去 如果一个libc…

目录

静态文件的缺点

动态链接

位置无关代码

延迟绑定

_dl_runtime_reslove 函数定义

深入审视


静态文件的缺点

随着可执行文件的增加  静态链接带来的浪费空间问题就会愈发严重

 如果大部分可执行文件都需要glibc 那么在链接的时候就需要把 libc.a链接进去

如果一个libc.a为5M 那么100就是 5G  例如下面的左边

静态链接的一个很明显的缺点 对标准函数进行一点点 的修改 都需要重新编译整个源文件

动态链接

如果不把系统库和自己编写的代码链接到一个可执行文件 而是分割到两个独立的模块 等到程序进行运行了 再进行链接 这样就可以节省硬盘空间 并且在内存中一个系统库可以被多个程序使用 这样还会节省物理空间

在这种 运行和加载的时候 在内存中完成链接的过程叫做动态链接这些用于动态链接的系统库 我们叫做共享库 或者 共享对象这个过程我们通过 动态链接器完成

  例如上图的右边

func1.elf func2.elf 不再包含单独的testLib.o 
当程序运行func1.ELF的时候 系统将func1.o和依赖的testLib.o载入内存中
进行动态链接
完成后 系统将控制器交给程序入口点 程序开始执行后面func2.ELF开始执行 因为内存中已经有testLib.o 不需要重复加载 所以直接链接即可

继续使用之前静态链接的例子

这里我们把func.c编译为共享库

gcc -shared -fpic -o func.so func.c-shared 生成共享库
-fpic 生成和位置无关的代码
gcc -fno-stack-protector -o func.ELF2 main.c  ./func.somain.c 和func.so进行动态链接
生成 func.ELF2

我们查看 func.ELF2的链接格式

 

查看 汇编格式
objdump -d -M intel --section=.text func.ELF2 |grep -A 11 "<main>"

这里我们就能发现 call 后面跟上了偏移量 地址等

位置无关代码

可以加载而无需重定位的代码就是位置无关代码PIC

通过gcc -fpic就可以生成位置无关代码

一个程序的代码段和数据段的相对位置都是保持不变的   所以指令和变量之间的距离是一个运行时常量 与绝对内存地址无关  

于是就有了全局偏移量表 GOT

GOT表位于 数据段的开头
用于保存全局变量和库函数的引用每个条目占8字节 在加载时会重定位并且填入符号的绝对地址
为了RELRO保护 
GOT 被拆分为 .got 和.got.plt.got 用于保存全局变量引用 写入内存为只读  不需要延迟绑定.got.plt 用于保存函数引用 具有读写权限  需要延迟绑定

我们可以看看func.o的情况

objdump -h func.so

readelf -r func.so| grep tmp

R_X86_64_GLOB_DAT 表示 动态链接器找到 tmp的值 存入0x3fd8

我们使用汇编可以看看代码

objdump -d -M intel --section=.text func.so |grep -A 20 "<func>"

 

 这里我们能发现 调用函数 rip+0x2ead的地方    rip为下一条指令的地址 这里是 112b

112b + 2ead =3fd8

所以汇编我们能发现调用函数就是指向 实际地址 3fd8

延迟绑定

如果动态链接是要通过动态链接器加载进行 如果要重定位的符号(库函数)多了之后 肯定会影响性能

延迟绑定就是为了解决这个问题

延迟绑定的思想就是如果函数是第一次被调用 动态链接器才进行符号查找 重定位的操作
如果没有调用就不进行绑定

ELF文件通过 PLT和GOT的配合来实现延迟绑定

每一个被调用的库函数都有一组 GOT 和PLT

位于代码段.got.plt节 是一个PLT数组 每一个条目占16字节 
PLT[0] 跳转到动态链接器
PLT[1] 调用系统启动函数 _libc_start_main()函数
main函数就是从里面进行调用PLT[2] 开始就被调用的各个函数条目
位于数据段.got.plt节的GOT也是一个数组  每条占8字节
GOT[0]和GOT[1]
包含着动态链接库解析函数地址所需要的两个地址 (dynamic和relor条目)GOT[2] 是动态链接器 ld-linux.so的入口点 GOT[3] 开始就是各个条目这些条目默认指向对应PLT条目的第二条指令
绑定后才会修改函数的实际地址

我们使用例子说明

#include<stdio.h>
void print_bananer(){printf("Welcome got and plt");
}
int main(void){print_bananer();return 0;
}

进行编译

gcc -Wall -g -o test.o -c test.c -m32gcc -o test test.o -m32 -no-pie

我们直接通过反汇编进行查看

objdump -d test 

 

 我们先看到main函数

看到call

 11d8:	e8 c0 ff ff ff       	call   119d <print_bananer>
这里地址送11d8
e8为call的机器码c0ffffff为printf_bananer的地址 这里第一次调用 不知道地址 所以用这个代替119d是去的地址 指向 print_bananer函数

我们去看119d的地址

 发现119d是print_bananer的地址

然后我们看到里面的关键调用

11ba:	e8 91 fe ff ff       	call   1050 <printf@plt>
11ba地址   
e8 ->call
91 fe ff ff  为函数地址

我们去看看1050地址

我们发现是

printf.plt地址 就是

然后我们进行代码审计

这里我们可以通过另一个编译 让pie停止


gcc -o test test.o -m32 -no-pie

然后重新进行查看

objdump -d test 

发现一个地址 我们使用gdb进行查看这个地址

gdb test
b mianr
x/x 0x804c010

这里是printf的got表

 这里得到另一个地址 我们回去反汇编看看

 发现就是下一条 push 0x8这个地址 所以第一个代码是返回 printf@plt的push

然后执行完push

又进行跳转

这里有一个地址 我们去看看

 

发现是main的共享库文件-0x10偏移量 的地址

然后进行push 0x804c004

又跳到0x804c008

gdb test 
x/x 0x804c008

我们发现 这里是0

因为第一次执行 还没有找到printf函数

我们让他执行起来

b main
r
x/x 0x804c008

发现得到了地址 这个地址就是 printf的地址

0x804c008这个的地址 其实就是指向 _dl_runtime_resolve函数

这个函数在动态链接里有着很重要的作用

计算出地址 更新got表等

我们现在来梳理一下

printf.plt ->printf.got.plt -> printf.plt->公共plt->_dl_runtime_reslove函数

这就是printf函数调用过程

这里我们还需要知道

_dl_runtime_reslove 怎么找到printf函数地址

这个是因为在之前我们执行printf@plt的时候 push了0x8

 这个就类似于 printf的id 让 _dl_runtime_reslove去找这个id的函数

_dl_runtime_reslove 函数定义

_dl_runtime_resolve(link_map_obj, reloc_index)

reloc_index 这个参数是来寻找 .rel.plt表的 这个表是ELF rel结构体

这个结构体为

typedef struct
{ELF64_Addr r_offset  ELF64_Xword r_info
}ELF64_Rel

r_offset是用于保存 需要进行重定位和重定位写入内存的位置

r_info的高三位是保存 符号在.dynsym里的下标

通过上面的图像 我们可以发现 r_info又指向 .dynsym中的ELF_sym结构体

这个结构体的内容为

typedef struct
{ELF64_Word st_name;   符号名称在字符串表中的偏移量unsigned char st_info;  包含符号类型和捆绑信息unsigned char st_other; 保留位ELF64_Half st_shndx; 指向和该符号关联的段/节索引值ELF64_Addr st_value; 该符号的值 就是地址ELF64_Xword st_size; 符号所占的字节
}ELF64_Sym

st_value和st_name为重要成员

st_value是符号导出时存放的虚拟地址 不能导出为null
st_name 是相对.dynstr的偏移

然后就是去.dynstr找函数

这个表中存放着 函数地址

所以我们从函数开始导入开始看

程序导入函数 .dynstr中增加一个函数名字符串
在.dynsym中增加一个ELF Sym的结构体 其中 S_name指向 .dynstr
然后又在.rel.plt中增加一个 ELF Rel结构体 其中 r_info指向 .dynsym的 ELF Sym结构体
最后 r_offset 构成 GOT表  存储在 .plt.got段的地址上

这样 我们函数就可以在程序的.plt.got中了

在我们明白这个了 我们重新对test进行审视

深入审视

这里第一个跳转 是无条件跳转到 GOT[0]处

但是GOT[0]在初始化的时候 默认指向 plt的第二条 就是PLT[1]->push 0x8

然后进行跳转到公共的PLT 然后去找_dl_runtime_reslove函数

这里的执行就是

无条件跳转到 xxx.got 把link_map_obj压入栈内
然后开始调回 plt 然后压入 函数id push 0x8
然后进行跳转去找_dl_runtime_reslove函数 并且执行

这样就实现了 函数通过动态链接寻找

http://www.dinnco.com/news/33950.html

相关文章:

  • 郑州网站建设 个人工作室结构优化
  • php项目开发案例源码seo在线网站推广
  • 免费音效素材网站沈阳专业seo排名优化公司
  • 专门做礼物的网站关键词推广
  • dns 国外网站谷歌优化是什么意思
  • 成都的网站建设开发公司磁力屋torrentkitty
  • 少儿编程网站seo网站关键词排名快速
  • 网站建设阶段垂直搜索引擎
  • 用visual做的网站百度网址收录提交入口
  • 网站建设哪里优化大师有必要花钱吗
  • 教程建设网站2022年seo还值得做吗
  • 做企业评价的有哪些网站高端网站建设的公司
  • 网站公司排行榜前十名网络营销是网上销售吗
  • 青岛公司做网站免费广告投放平台
  • 做二手钢结构网站免费培训机构管理系统
  • 检察院内部网站升级建设网站营销网站营销推广
  • 学校学院网站建设目标网络营销活动推广方式
  • 广州开发网站技术支持广告商对接平台
  • 只做网站的人员工资站长工具查询域名
  • 网站公司怎么做运营seo指什么
  • 微网站开发系统百度竞价广告怎么收费
  • 北仑做网站品牌推广方案包括哪些
  • 京东客网站怎么做如何优化网页加载速度
  • 上海资本公司排名seo搜索引擎优化就业指导
  • 微信公众号小程序是什么济南网站优化排名
  • 日本专门做恋足的网站seo搜索优化工程师招聘
  • 专门做正品的网站免费的行情网站app软件
  • 号号网站开发关键词优化排名软件流量词
  • 潍坊专业人员继续教育seo sem
  • 建网站外贸如何做网站推广