欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]ROP高级用法之ret2_dl_runtime_resolve

[原创]ROP高级用法之ret2_dl_runtime_resolve

简介

我们知道在Linux中如果程序想要调用其他动态链接库的函数,必须要在程序加载的时候动态链接;在一个程序运行过程中,可能很多函数在程序执行完时都不会用到,比如一些错误处理函数或者一些用户很少用到的功能模块;所以ELF采用一种叫做延迟绑定(Lazy Binding)的做法,基本思想就是当函数第一次被调用的时候才进行绑定(符号查找、重定位等);
而在Linux 中是利用_dl_runtime_resolve(link_map_obj, reloc_index)函数来对动态链接的函数进行重定位的;

_dl_runtime_resolve函数具体运行模式

首先总的来说一下_dl_runtime_resolve函数如何使程序第一次调用一个函数:

  1. 首先用link_map访问.dynamic,分别取出.dynstr、 .dynsym、 .rel.plt的地址;
  2. .rel.plt + 参数reloc_index,求出当前函数的重定位表项Elf32_Rel的指针,记作rel;
  3. rel->r_info >> 8作为.dynsym的下标,求出当前函数的符号表项Elf32_Sym的指针,记作sym;
  4. .dynstr + sym->st_name得出符号名字符串指针;
  5. 在动态链接库查找这个函数的地址,并且把地址赋值给*rel->r_offset,即GOT表;
  6. 最后调用这个函数;

现在我们通过一个实例来解释上面的过程:
任意打开一个ELF程序,这里我用XDCTF2015的pwn200中的strlen函数为例来看Linux中程序如何第一次调用一个函数;
在0x8048588下断点;

0x8048579 <main+90>     call   setbuf@plt <0x8048390>

   0x804857e <main+95>     add    esp, 0x10

   0x8048581 <main+98>     sub    esp, 0xc

   0x8048584 <main+101>    lea    eax, [ebp - 0x6c]

   0x8048587 <main+104>    push   eax

 ? 0x8048588 <main+105>    call   strlen@plt <0x80483b0>

        s: 0xffffbd8c ?— 'Welcome to XDCTF2015~!\n'

   0x804858d <main+110>    add    esp, 0x10

   0x8048590 <main+113>    sub    esp, 4

   0x8048593 <main+116>    push   eax

   0x8048594 <main+117>    lea    eax, [ebp - 0x6c]

   0x8048597 <main+120>    push   eax

然后si进入call strlen@plt;

0x80483b0  <strlen@plt>                jmp    dword ptr [_GLOBAL_OFFSET_TABLE_+20] <0x804a014>

   0x80483b6  <strlen@plt+6>              push   0x10 //参数n

   0x80483bb  <strlen@plt+11>             jmp    0x8048380

    ↓

   0x8048380                              push   dword ptr [_GLOBAL_OFFSET_TABLE_+4] <0x804a004>

   0x8048386                              jmp    dword ptr [0x804a008] <0xf7fead80>

       ↓   

   0xf7fead80 <_dl_runtime_resolve>       push   eax

   0xf7fead81 <_dl_runtime_resolve+1>     push   ecx

   0xf7fead82 <_dl_runtime_resolve+2>     push   edx

我们看到程序没有直接转到strlen函数,而是跳转到了_dl_runtime_resolve函数;并且push了两个参数:

push   0x10 //参数n

push   dword ptr [_GLOBAL_OFFSET_TABLE_+4]<0x804a004>

刚好是_dl_runtime_resolve(link_map_obj, reloc_index)需要的参数;其中0x804a004就是link_map指针,然后0x10就是reloc_index;

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功