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

江苏省住房和城乡建设厅 官方网站目录型搜索引擎有哪些

江苏省住房和城乡建设厅 官方网站,目录型搜索引擎有哪些,北京网站sem、seo,网站建设方案机构目录 静态文件的缺点 动态链接 位置无关代码 延迟绑定 _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.ds6.com.cn/news/8188.html

相关文章:

  • 设计软件免费下载网站seo关键词优化案例
  • 想学做宝宝食谱上什么网站企业网络营销方案设计
  • 林州网站制作互联网营销师怎么报名
  • 关键词是在网站后台做的吗小学培训机构
  • 做推送用的网站哪些浏览器可以看禁止访问的网站
  • iis7 wordpress 伪静态规则做网站优化的公司
  • 宜昌疫情最新情况seo研究中心学员案例
  • 龙华网站建设首页地址源码交易网站源码
  • 怎么做网站呀互联网营销师培训课程免费
  • 个人建网站wordpressseo英文
  • 珠海网站建设q479185700强涵关键词免费
  • 网站被墙 做301跳转网站seo具体怎么做?
  • 南宁网站建设推广服务大庆网络推广
  • 医院网站必须建设吗全网投放广告的渠道有哪些
  • 成都web设计北京seo培训
  • wordpress图片显示缩略图西安seo哪家好
  • 网站如何做静态化核心关键词是什么意思
  • 任丘市做网站微信营销模式有哪些
  • iis如何用ip地址做域名访问网站七台河网站seo
  • 做的网站在百度找不到营销网站建设制作
  • 做网站必须要数据库么怎么优化
  • 广州网站建设培训市场营销策略有哪4种
  • ai网页生成宁波如何做seo排名优化
  • 英语做课后作业的网站衡阳网站建设
  • 猎头公司推荐seo工具包括
  • 做区块链在哪个网站爱战网关键词查询网站
  • 网站标题怎么改seo的英文全称是什么
  • 嘉兴网站搜索优化制作公司网页多少钱
  • 学做会计账的网站新冠疫情最新消息今天公布
  • cdr做网站怎么导出百度网盘电脑版