1. PIC/PIE
  • RELRO
  • master of orw 复现
    1. pic 的实现
  • 有点混乱

    PIC/PIE

    PIC ( position independent code ) 一开始是用于动态库的加载的,这么多动态库肯定得服从任意的地址分配,而二进制文件的位置是固定的。后来发现 ASLR 的效果很好,希望引入 PIE ( position independent execute )让二进制的地址也随机化。

    在 gcc manual 13.2 中有关选项的解释如下

    RELRO

    可以向 dynamic loader 指定在什么时候解析 GOT。在 man ld 里可以看见

    lazy
        When generating an executable or shared library, mark it to tell the dynamic linker to defer function call resolution to the point when the function is called (lazy binding), rather than at load time.Lazy binding is the default.
    

    lazy binding 是默认的

    now 
        When generating an executable or shared library, mark it to tell the dynamic linker to resolve all symbols when the program is started, or when the shared library is loaded by dlopen, instead of deferring function call resolution to the point when the function is first called.
    

    但是我们用 gcc 不加 -z 选项编译的文件是 FULL RELRO。gcc 是默认会传递 -z now 参数 默认是 full relro

    后面的东西是随手贴上去的

    master of orw 复现

    用 syscall 接收远程文件跳转执行

    gcc -o test -static -fno-stack-protector -no-pie -O3 ./lib_uring_test.c -luring
    
    -static 
    

    REL 和 EXEC 的区别

    可重定位文件中,符号的地址还没有填写上去(还是 0)

    pic 的实现

    在 x64 中,开了 PIC 之后,数据和函数的地址是通过 RIP 的偏移计算的。测试一下。

    int d = 3;
    
    int add(int a, int b){
        return a+b;
    }
    
    int main(){
        int x = add(d, 3);
    }
    

    汇编如下:

    pwndbg> disass /r main
    Dump of assembler code for function main:
       0x0000000000001141 <+0>:     f3 0f 1e fa             endbr64
       0x0000000000001145 <+4>:     55                      push   rbp
       0x0000000000001146 <+5>:     48 89 e5                mov    rbp,rsp
       0x0000000000001149 <+8>:     48 83 ec 10             sub    rsp,0x10
       0x000000000000114d <+12>:    48 8d 05 bc 2e 00 00    lea    rax,[rip+0x2ebc]        # 0x4010 <d>
       0x0000000000001154 <+19>:    8b 00                   mov    eax,DWORD PTR [rax]
       0x0000000000001156 <+21>:    be 03 00 00 00          mov    esi,0x3
       0x000000000000115b <+26>:    89 c7                   mov    edi,eax
       0x000000000000115d <+28>:    e8 c7 ff ff ff          call   0x1129 <add>
       0x0000000000001162 <+33>:    89 45 fc                mov    DWORD PTR [rbp-0x4],eax
       0x0000000000001165 <+36>:    b8 00 00 00 00          mov    eax,0x0
       0x000000000000116a <+41>:    c9                      leave
       0x000000000000116b <+42>:    c3                      ret
    End of assembler dump.
    

    0x115d 处的 call add 的语句是 e8 cd ff ff ff 即跳转到(当前地址 - 0x2e)的地方。

    0x114d 是通过 rip 来相对寻址的

    emmm 下面是不开 -fPIC 的我怎么觉得没什么差别

    pwndbg> disass /r main
    Dump of assembler code for function main:
       0x0000000000001141 <+0>:     f3 0f 1e fa             endbr64
       0x0000000000001145 <+4>:     55                      push   rbp
       0x0000000000001146 <+5>:     48 89 e5                mov    rbp,rsp
       0x0000000000001149 <+8>:     48 83 ec 10             sub    rsp,0x10
       0x000000000000114d <+12>:    8b 05 bd 2e 00 00       mov    eax,DWORD PTR [rip+0x2ebd]        # 0x4010 <d>
       0x0000000000001153 <+18>:    be 03 00 00 00          mov    esi,0x3
       0x0000000000001158 <+23>:    89 c7                   mov    edi,eax
       0x000000000000115a <+25>:    e8 ca ff ff ff          call   0x1129 <add>
       0x000000000000115f <+30>:    89 45 fc                mov    DWORD PTR [rbp-0x4],eax
       0x0000000000001162 <+33>:    b8 00 00 00 00          mov    eax,0x0
       0x0000000000001167 <+38>:    c9                      leave
       0x0000000000001168 <+39>:    c3                      ret
    End of assembler dump.
    

    还有一些问题待解决: