启动与分析
(base) ➜ cwe_binary r2 d5db980dfc204a0f8df04dd1a2ec09fa
[0x08048760]> aaa
加载一个文件的命令为r2 文件名
分析的命令为aaa,这玩意有好几个等级,具体分析啥咱也忘了a越多分析的东西越多,最多是三个a。
使用python处理的话,json可以加载获取到的字符串
import r2pipe
r2 = r2pipe.open(filename, flags=['-2'])
r2.cmd('aaa')
json.loads(r2.cmd('aflj'))
函数和符号信息
afl
和
is
afl打印所有函数信息,is打印符号信息
如图加上j表示输出为json,~{}
可以输出为这种可读的形式
[0x08048760]> aflj~{}
Do you want to print 4077 lines? (y/N) y
[
{
"offset": 134514528,
"name": "entry0",
"size": 33,
"is-pure": "false",
"realsz": 33,
"noreturn": false,
"stackframe": 28,
"calltype": "cdecl",
"cost": 15,
"cc": 1,
"bits": 32,
"type": "fcn",
"nbbs": 1,
"edges": 0,
"ebbs": 1,
"signature": "entry0 ();",
"minbound": 134514528,
"maxbound": 134514561,
"callrefs": [
{
"addr": 134514320,
"type": "CALL",
"at": 134514556
}
],
"datarefs": [
134516736,
134516640,
134516548
],
"indegree": 0,
"outdegree": 1,
"nlocals": 0,
"nargs": 0,
"bpvars": [
],
"spvars": [
],
"regvars": [
],
"difftype": "new"
},
offset为偏移量。
字段介绍:name
name为函数的名字
entry
在ida里面是_start
是ida的入口地址
main
也是没有前缀的"name": "sym.imp.puts",
对应ida的plt表puts的地址无论是用户定义的函数还是调用的其他库函数都会有sym前缀,所以通过name区分用户自定义函数和系统函数是不行的
一些编译器生成的必要函数name可能跟ida的有一些不同
radare的name
ida的name
注意:调用的库函数在这里只会显示对应plt表项的信息。(通过imp前缀可以区分),通过去除掉一些编译器生成的函数可以得到所有的自定义的函数
其他字段
"size": 43
表示整个函数从开始到结束的大小。
注意 offset+size不是retn指令的地址,如图第一个箭头指向offset,第二个指向offset+size(或许是到下一个函数开始)
对比了几个
"is-pure": "true"
为ture的案例,都是不存在的函数,其中包含下标为imp标志的函数,loc标志的函数size和realsz没什么区别。
"stackframe": 40
是函数整个栈帧的大小 合起来刚好是0x28(十进制40)“bits”: 64, 应该是64位
“edges”: 4 表示cfg图边的数量
“signature”: “sym.tttt (int64_t arg1);”, 会包含函数和函数的参数,以及参数的数据类型。
“minbound”: 1706,为函数的开始 “maxbound”: 1786 为下一个函数的开始
“callrefs” 一个列表,包含在什么地方(at)调用(CALL)了哪个(addr)函数,在什么地方跳转(CODE)到什么地方。
"callrefs": [
{
"addr": 1408,
"type": "CALL",
"at": 1734
},
{
"addr": 1752,
"type": "CODE",
"at": 1743
},
“datarefs” 存放里面用到的一些数据的地址。
"datarefs": [ 1956, 1959 ],
codexrefs
"codexrefs": [ { "addr": 1812, 这个函数的首地址 "type": "CALL", 调用 "at": 1706 某个函数在这个位置 }, { "addr": 1743, 本函数在什么地方跳转 "type": "CODE", "at": 1752 跳转到 }, { "addr": 1750, "type": "CODE", "at": 1784 } ],
- “dataxrefs” 变量,参数,返回值,用到数据的信息,临时变量有一点不够准确
"dataxrefs": [
],
"indegree": 3, 引入多少数据(包含参数,用到的数据)
"outdegree": 2, 返回的数量
"nlocals": 2, 局部变量数量(不够准确)
"nargs": 1, 参数数量
"bpvars": [
{
"name": "var_14h", 14h表示距离ebp的偏移(实际上这是一个全局变量)
"kind": "var", 变量
"type": "int64_t",
"ref": {
"base": "rbp", 基地址
"offset": -20 偏移
}
},
{
"name": "var_4h",
"kind": "var",
"type": "uint32_t",
"ref": {
"base": "rbp",
"offset": -4
}
}
],
“spvars” 参数的
"spvars": [ ], "regvars": [ { "name": "arg1", "kind": "reg", "type": "int64_t", "ref": "rdi" } ],
## 获取符号信息
`isj~{}`
在不删除符号表的时候会展示很多东西,删除符号表(strip filename)之后就没有什么符号了,优点是分析速度很快
{
“name”: “crtstuff.c”,
“flagname”: “sym.crtstuff.c”,
“realname”: “crtstuff.c”,
“ordinal”: 35,
“bind”: “LOCAL”,
“size”: 0,
“type”: “FILE”,
“vaddr”: 0,
“paddr”: 0,
“is_imported”: false
},
## 跳转
跳转到分析的位置
`s addr`
## 查看汇编代码
先用s跳转到一个函数的开始
- `agf`查看cfg图
![cfg](https://raw.githubusercontent.com/tower111/picture/main/小书匠/1615697326304.png)
- `pdf` 查看汇编指令,调用关系。
![调用关系](https://raw.githubusercontent.com/tower111/picture/main/小书匠/1615697391784.png)
- `agfj~{}`展示每个块详细信息,方便获取一些字段
```bash
[
{
"name": "sym.tttt",
"offset": 1674, 地址
"ninstr": 31,
"nargs": 3, 参数数量
"nlocals": 4, 局部变量数(汇编里面存放过都会计数,有些源代码没定义,只是编译器生成的临时存放数据的)
"size": 102, 函数大小
"stack": 40, 栈帧大小
"type": "sym",
"blocks": [ 每个块的信息
{
"offset": 1674,
"size": 51,
"jump": 1732, 见后面的分析(如果跳转)
"fail": 1725, 如果不跳转
"trace": { 待补充
"count": 55,
"times": 1
},
"colorize": 0,
"ops": [
{
"offset": 1674,
"esil": "rbp,8,rsp,-,=[8],8,rsp,-=", 中间语言 见后面的分析
"refptr": false,
"fcn_addr": 1674,
"fcn_last": 1811,
"size": 1,
"opcode": "push rbp",
"disasm": "push rbp", 汇编指令
"bytes": "55", 字节码
"family": "cpu",
"type": "rpush",
"reloc": false,
"type_num": 268435468,
"type2_num": 0,
"flags": [
"sym.tttt"
],
"xrefs": [
{
"addr": 1858,
"type": "CALL"
}
]
},
跳转
如下指令,在jnz跳转的时候会跳转到"jump": 1732
不跳的时候(汇编代码紧邻的)是"fail": 1725
cmp [rbp+var_4], 1
jnz short loc_6C4
中间语言
"esil": "rbp,8,rsp,-,=[8],8,rsp,-="
esil:Evaluable Strings Intermediate Language 可计算字符串中间语言。
目的是能够表示CPU执行的大多数常见操作,例如二进制算术运算,内存加载和存储,处理系统调用。这样,如果我们可以将指令转换为ESIL,就可以看到程序在运行时的功能,即使对于大多数隐秘的体系结构,您也绝对没有要调试的设备。
指令详细信息
用s addr
跳转到一个块的开始(块地址的列表可以从agf获取到)
aoj 指令数
可以通过len(block['ops'])
来确定
[0x0000068a]> aoj 2~{}
[
{
"opcode": "push rbp",
"disasm": "push rbp",
"pseudo": "push rbp",
"description": "push word, doubleword or quadword onto the stack",
"mnemonic": "push", 助记符
"mask": "ff",
"esil": "rbp,8,rsp,-,=[8],8,rsp,-=",
"sign": false,
"prefix": 0,
"id": 588,
"opex": {
"operands": [
{
"size": 8,
"rw": 1,
"type": "reg", 分为imm(调用函数也在这),reg,mem
"value": "rbp" 立即数为数值,寄存器为寄存器名
}
]
},
"addr": 1674,
"bytes": "55",
"size": 1,
"type": "rpush",
"scale": 0,
"refptr": 0,
"cycles": 1,
"failcycles": 0,
"delay": 0,
"stack": "inc",
"stackptr": 8,
"family": "cpu"
},
一个稍微复杂的指令opex更多一点
"opcode": "lea rdi, [rip + 0x110]",
"disasm": "lea rdi, str.dddd", disasm相比opcode会多一些分析,可读性更好
"opex": {
"operands": [
{
"size": 8,
"rw": 2,
"type": "reg",
"value": "rdi"
},
{
"size": 8,
"rw": 1,
"type": "mem",
"base": "rip", 详细展开指令
"scale": 1,
"disp": 272 真实地址=[base*scale+disp] base为基地址寄存器,scale为规模,disp为偏移量(十进制) (如果是rax+rbx+0x10会变为rax*2+16) 如果是负数里面存放补码
}
],
"rex": true,
"modrm": true,
"disp": 272
},
base为0的情况有
'lea rdx, [rax*4]'(处理第二个操作数)
'mov rax, qword fs:[0x28]'(段加偏移)
字符串处理
对字符串的处理"disasm": "lea rdi, str.dddd",
会在这里添加str.
也有可能没有被识别,被识别为了imm类型,可以判断改地址是否在字符串列表地址中,获取字符串列表的方式如下
izzj~{}
指令可以获得指令的信息
{
"vaddr": 481, 如果不是.strtab段两个地址是相等的,指向函数的地址
"paddr": 6201,
"ordinal": 56,
"size": 26, 空间大小
"length": 25, 长度
"section": ".strtab", strtab段在ida里是不显示的
"type": "ascii",
"string": "_ITM_registerTMCloneTable"
},
函数调用指令
列出三种架构用到的函数调用
x86_mnemonics = ['call', 'int']#包含函数调用和syscall
arm_mnemonics = ['bl', 'blx']
mips_mnemonics = ['jal', 'jalr', 'syscall']
转移指令的确定
列出了三种架构的转移指令
x86_mnemonics = ['BNDLDX', 'BNDMK', 'BNDMOV', 'BNDSTX'
, 'CMOVA', 'CMOVZ', 'CMOVPO', 'CMOVPE', 'CMOVP', 'CMOVO', 'CMOVNZ', 'CMOVNP', 'CMOVNO', 'CMOVNG', 'CMOVL'
, 'FIST', 'FISTP', 'FISTTP', 'FSAVE', 'KMOVB', 'KMOVD', 'KMOVQ', 'KMOVW'
, 'LDDQU', 'LDS', 'LEA', 'LODS', 'LODSB', 'LODSD', 'LODSQ', 'LODSW'
, 'LSS', 'LSL', 'MOV', 'MOVAPD', 'MOVAPS', 'MOVBE', 'MOVD', 'MOVDDUP', 'MOVDQ2Q', 'MOVDQA', 'MOVDQU'
, 'MOVHLPS', 'MOVHPD', 'MOVHPS', 'MOVLHPS', 'MOVLPD', 'MOVLPS', 'MOVQ', 'MOVS', 'MOVSB', 'MOVSD', 'MOVNTQ'
, 'MOVNTDQ', 'MOVMSKPS', 'MOVSQ', 'MOVSS', 'MOVSW', 'MOVSX', 'MOVSXD', 'MOVUPD', 'MOVUPS', 'MOVZX',
'PMOVMSKB'
, 'PMOVSX', 'PMOVZX', 'PUSH', 'PUSHA', 'PUSHAD', 'PUSHF', 'STOS', 'STOSB', 'STOSD', 'STOSQ', 'STOSW'
, 'VBROADCAST', 'VEXPANDPD', 'VEXPANDPS', 'VMOVDQA32', 'VMOVDQA64', 'VMOVDQU16', 'VMOVDQU32', 'VMOVDQU64',
'VMOVDQU8'
, 'VPBROADCAST', 'VPBROADCASTB', 'VPEXPANDD', 'VPEXPANDQ', 'movb', 'movq']
arm_mnemonics = ['MOV', 'MVN', 'MOVT', 'MRA', 'MAR', 'LDR', 'STR', 'PLD', 'PLI', 'PLDW', 'LDM', 'LDREX',
'LDREXD', 'STM', 'STREX', 'STREXD']
mips_mnemonics = ['LB', 'LBE', 'LBU', 'LBUE', 'LD', 'LDE', 'LDU', 'LDUE', 'LDC1', 'LDC2'
, 'LDL', 'LDPC', 'LDR', 'LDXC1', 'LH', 'LHE', 'LHU', 'LHUE', 'LL'
, 'LLD', 'LLE', 'LLDP', 'LLWP', 'LLWPE', 'LSA', 'LUXC1', 'LW'
, 'LWC1', 'LWC2', 'LWL', 'LWLE', 'LWPC'
, 'LWR', 'LWRE', 'LWU', 'MOV', 'SB', 'SBE', 'SC'
, 'SCD', 'SCDP', 'SCE', 'SCWP', 'SCWPE'
, 'SD', 'SDBBP', 'SDC1', 'SDC2', 'SDL', 'SDR', 'SDXC1', 'SH', 'SHU', 'SHE'
, 'SW', 'SWE', 'SWC1', 'SWC2', 'SWL', 'SWR', 'SWLE', 'SWRE', 'SWXC1']
算数指令
列出了三种架构的算数指令
x86_mnemonics = ['add', 'sub', 'div', 'imul', 'idiv', 'mul', 'shl', 'dec', 'adc', 'adcx', 'addpd', 'addps',
'addsd', 'addss', 'addsubpd', 'ADDSUBPS', 'adox', 'divpd', 'divps'
, 'divsd', 'divss', 'dppd', 'dpps', 'f2xm1', 'fabs', 'fadd', 'faddp', 'fcos', 'fdiv', 'fdivp', 'fiadd',
'fidiv', 'fimul', 'fisub', 'fisubr', 'fmul', 'fmulp', 'FPATAN', 'FPREM', 'FPREM1', 'FPTAN',
'FRNDINT', 'FSCALE'
, 'FSIN', 'FSINCOS', 'FSQRT', 'FSUB', 'FSUBP', 'FSUBR', 'FSUBRP', 'FYL2X', 'FYL2XP1', 'HADDPD', 'HADDPS',
'HSUBPD', 'HSUBPS', 'KADDB', 'KADDD', 'KADDD', 'KADDW', 'KSHIFTLB', 'KSHIFTLD', 'KSHIFTLQ',
'KSHIFTLW', 'KSHIFTRB', 'KSHIFTRD', 'KSHIFTRQ', 'KSHIFTRW'
, 'MAXPD', 'MAXPS', 'MAXSD', 'MAXSS', 'MINPD', 'MINPS', 'MINSD', 'MINSS', 'MULPD'
, 'MULPS', 'MULSS', 'MULSD', 'MULX', 'PADDB', 'PADDD', 'PADDQ', 'PADDSB', 'PADDSW', 'PADDUSB', 'PADDUSW'
, 'PADDW', 'PAVGB', 'PAVGW', 'PHADDD', 'PHADDSW', 'PHADDW', 'PHMINPOSUW', 'PHSUBD', 'PHSUBSW', 'PHSUBW'
, 'PMADDUBSW', 'PMADDWD', 'PMAXSB', 'PMAXSD', 'PMAXSQ', 'PMAXSW', 'PMAXUB', 'PMAXUD', 'PMAXUQ', 'PMAXUW',
'PMINSB'
, 'PMINSD', 'PMINSQ', 'PMINSW', 'PMINUB', 'PMINUD', 'PMINUQ', 'PMINUW', 'PMULDQ', 'PMULHRSW', 'PMULHUW',
'PMULHW', 'PMULLD', 'PMULLQ'
, 'PMULLW', 'PMULUDQ', 'PSADBW', 'PSLLD', 'PSLLW', 'PSRAD', 'PSLLQ', 'PSRAQ', 'PSRLQ', 'PSRLW'
, 'PSUBB', 'PSUBD', 'PSUBQ', 'PSUBSB', 'PSUBSW', 'PSUBUSB', 'PSUBUSW', 'RCL', 'RCR'
, 'ROL', 'ROR', 'ROUNDPD', 'ROUNDPS', 'ROUNDSD', 'ROUNDSS', 'RSQRTPS'
, 'RSQRTSS', 'SAL', 'SAR', 'SARX', 'SBB', 'inc', 'SHLD', 'SHLX', 'SHR', 'SHRD', 'SHRX', 'SQRTPD', 'SQRTPS',
'SQRTSD', 'SQRTSS'
, 'SUBPD', 'SUBPS', 'SUBSD', 'SUBSS', 'VFMADD132PD', 'VPSLLVD', 'VPSLLVQ', 'VPSLLVW', 'VPSRAVD', 'VPSRAVQ'
, 'VPSRAVW', 'VPSRLVD', 'VPSRLVQ', 'VPSRLVW', 'VRNDSCALEPD', 'VRNDSCALEPS', 'XADD']
arm_mnemonics = ['add', 'adc', 'qadd', 'dadd', 'sub', 'SBC', 'RSB', 'RSC', 'subs', 'qsub',
'add16', 'SUB16', 'add8', 'sub8', 'ASX', 'sax', 'usad8', 'SSAT', 'MUL'
, 'smul', 'MLA', 'MLs', 'UMULL', 'UMLAL', 'UMaAL', 'SMULL', 'smlal'
, 'SMULxy', 'SMULWy', 'SMLAxy', 'SMLAWy', 'SMLALxy', 'SMUAD'
, 'SMLAD', 'SMLALD', 'SMUSD', 'SMLSD', 'SMLSLD', 'SMMUL'
, 'SMMLA', 'MIA', 'MIAPH', 'MIAxy', 'SDIV', 'udiv'
, 'ASR', 'LSL', 'LSR', 'ROR', 'RRX']
mips_mnemonics = ['add', 'addu', 'addi', 'addiu', 'mult', 'multu', 'div', 'divu'
, 'AUI', 'DAUI', 'DAHI', 'DATI', 'CLO', 'CLZ', 'DADD', 'DADDI'
, 'DADDIU', 'DADDU', 'DCLO', 'DCLZ', 'DDIV', 'DDIVU', 'MOD'
, 'MODU', 'DMOD', 'DMODU', 'DMULTU', 'DROTR', 'DROTR32', 'DSLLV'
, 'DSRA', 'DSRA32', 'DSRAV', 'DSRL', 'DSRL32'
, 'DSRLV', 'DSUB', 'DSUBU', 'DSRL', 'FLOOR', 'MAX', 'MIN', 'MINA', 'MAXA'
, 'MSUB', 'MSUBU', 'MUL', 'MUH', 'MULU', 'MUHU', 'DMUL', 'DMUH'
, 'DMULU', 'DMUHU', 'DMUL', 'NEG'
, 'NMADD', 'NMSUB', 'RECIP', 'RINT', 'ROTR', 'ROUND', 'RSQRT'
, 'SLL', 'SLLV', 'SQRT', 'SRA', 'SRAV', 'SRL', 'SRLV'
, 'SUB', 'SUBU', 'madd', 'maddu', 'msub', 'msubu', 'sll'
, 'srl', 'sra', 'sllv', 'srla', 'srlv']