radare2中文版
  • 介绍
  • 历史
  • 框架
  • 下载 radare2
  • 编译和可移植性
  • 在Windows上编译
  • 用户界面
  • 第一步
    • 命令行标志
    • 命令格式
    • 表达式
    • 基本调试器会话
    • 对radare2的贡献
  • 配置
    • 颜色
    • 配置变量
    • Files
  • 基本命令
    • Seeking(寻求)
    • Block Size(区块大小)
    • Sections(分节)
    • Mapping Files(映射文件)
    • Print Modes(打印模式)
    • Flags(标志)
    • Write(写)
    • Zoom(缩放)
    • Yank/Paste(拉伸/粘贴)
    • Comparing Bytes(比较字节)
    • SDB
    • Dietline
  • 视图模式
    • 反汇编
    • 汇编
    • 配置编辑器
    • 面板
  • 搜索字节
    • 基本搜索
    • 配置搜索
    • 正则搜索
    • 自动化
    • 向后搜索
    • 在程序集中搜索
    • 搜索AES密钥
  • 反汇编
    • 添加元数据
    • ESIL
  • 分析
    • 代码分析
    • 变量
    • 类型
    • 调用约定
    • 虚拟表
    • 系统调用
    • 模拟
    • 符号信息
    • 签名
    • 图形命令
  • 脚本
    • 循环
    • 宏
    • R2pipe
  • 调试器
    • 入门
    • 迁移自ida, GDB or WinDBG
    • 寄存器
    • 内存映射
    • 堆
    • Files
    • 反向调试
  • 远程访问
    • 远程GDB
    • 远程WinDbg
  • 命令行工具
    • Rax2(数值转换)
    • Rafind2(查找)
    • Rarun2
    • Rabin2(文件格式)
      • 文件标识
      • 入口
      • 导入
      • 导出
      • 符号 (导出)
      • 库
      • 字符串
      • 程序节
    • Radiff2(比较)
      • Binary Diffing
    • Rasm2(反汇编)
      • 汇编
      • 反汇编
      • 配置
    • Ragg2(C编译器)
      • Language
    • Rahash2(加密算法)
      • Rahash Tool
  • 插件
    • IO 插件
    • 汇编插件
    • 分析插件
    • 二进制插件
    • 其他插件
    • Python插件
    • 调试
    • 测试
    • Packaging
  • Crackmes
    • IOLI
      • IOLI 0x00
      • IOLI 0x01
    • Avatao R3v3rs3 4
      • .radare2
      • .first_steps
      • .main
      • .vmloop
      • .instructionset
      • .bytecode
      • .outro
  • 参考卡
  • 致谢
由 GitBook 提供支持
在本页

这有帮助吗?

  1. 分析

变量

Radare2 allows managing local variables, no matter their location, stack or registers. The variables' auto analysis is enabled by default but can be disabled with anal.vars configuration option.

The main variables commands are located in afv namespace:

|Usage: afv[rbs]
| afvr[?]                     manipulate register based arguments
| afvb[?]                     manipulate bp based arguments/locals
| afvs[?]                     manipulate sp based arguments/locals
| afv*                        output r2 command to add args/locals to flagspace
| afvR [varname]              list addresses where vars are accessed (READ)
| afvW [varname]              list addresses where vars are accessed (WRITE)
| afva                        analyze function arguments/locals
| afvd name                   output r2 command for displaying the value of args/locals in the
debugger
| afvn [old_name] [new_name]  rename argument/local
| afvt [name] [new_type]      change type for given argument/local
| afv-([name])                remove all or given var

afvr, afvb and afvs commands are uniform but allow manipulation of register-based arguments and variables, BP/FP-based arguments and variables, and SP-based arguments and variables respectively. If we check the help for afvr we will get the way two others commands works too:

|Usage: afvr [reg] [type] [name]
| afvr                        list register based arguments
| afvr*                       same as afvr but in r2 commands
| afvr [reg] [name] ([type])  define register arguments
| afvrj                       return list of register arguments in JSON format
| afvr- [name]                delete register arguments at the given index
| afvrg [reg] [addr]          define argument get reference
| afvrs [reg] [addr]          define argument set reference

The most important aspect of reverse engineering - naming things. Of course, you can rename variable too, affecting all places it was referenced. This can be achieved with afvn for any type of argument or variable. Or you can simply remove the variable or argument with afv- command.

As mentioned before the analysis loop relies heavily on types information while performing variables analysis stages. Thus comes next very important command - afvt, which allows you to change the type of variable:

[0x00003b92]> afvs
var int local_8h @ rsp+0x8
var int local_10h @ rsp+0x10
var int local_28h @ rsp+0x28
var int local_30h @ rsp+0x30
var int local_32h @ rsp+0x32
var int local_38h @ rsp+0x38
var int local_45h @ rsp+0x45
var int local_46h @ rsp+0x46
var int local_47h @ rsp+0x47
var int local_48h @ rsp+0x48
[0x00003b92]> afvt local_10h char*
[0x00003b92]> afvs
var int local_8h @ rsp+0x8
var char* local_10h @ rsp+0x10
var int local_28h @ rsp+0x28
var int local_30h @ rsp+0x30
var int local_32h @ rsp+0x32
var int local_38h @ rsp+0x38
var int local_45h @ rsp+0x45
var int local_46h @ rsp+0x46
var int local_47h @ rsp+0x47
var int local_48h @ rsp+0x48

Less commonly used feature, which is still under heavy development - distinction between variables being read and written. You can list those being read with afvR command and those being written with afvW command. Both commands provide a list of the places those operations are performed:

[0x00003b92]> afvR
local_48h  0x48ee
local_30h  0x3c93,0x520b,0x52ea,0x532c,0x5400,0x3cfb
local_10h  0x4b53,0x5225,0x53bd,0x50cc
local_8h  0x4d40,0x4d99,0x5221,0x53b9,0x50c8,0x4620
local_28h  0x503a,0x51d8,0x51fa,0x52d3,0x531b
local_38h
local_45h  0x50a1
local_47h
local_46h
local_32h  0x3cb1
[0x00003b92]> afvW
local_48h  0x3adf
local_30h  0x3d3e,0x4868,0x5030
local_10h  0x3d0e,0x5035
local_8h  0x3d13,0x4d39,0x5025
local_28h  0x4d00,0x52dc,0x53af,0x5060,0x507a,0x508b
local_38h  0x486d
local_45h  0x5014,0x5068
local_47h  0x501b
local_46h  0x5083
local_32h
[0x00003b92]>

Type inference

The type inference for local variables and arguments is well integrated with the command afta.

[0x000007aa]> pdf
|           ;-- main:
/ (fcn) sym.main 157
| sym.main ();
| ; var int local_20h @ rbp-0x20
| ; var int local_1ch @ rbp-0x1c
| ; var int local_18h @ rbp-0x18
| ; var int local_10h @ rbp-0x10
| ; var int local_8h @ rbp-0x8
| ; DATA XREF from entry0 (0x6bd)
| 0x000007aa  push rbp
| 0x000007ab  mov rbp, rsp
| 0x000007ae  sub rsp, 0x20
| 0x000007b2  lea rax, str.Hello          ; 0x8d4 ; "Hello"
| 0x000007b9  mov qword [local_18h], rax
| 0x000007bd  lea rax, str.r2_folks       ; 0x8da ; " r2-folks"
| 0x000007c4  mov qword [local_10h], rax
| 0x000007c8  mov rax, qword [local_18h]
| 0x000007cc  mov rdi, rax
| 0x000007cf  call sym.imp.strlen         ; size_t strlen(const char *s)
  • After applying afta

[0x000007aa]> afta
[0x000007aa]> pdf
| ;-- main:
| ;-- rip:
/ (fcn) sym.main 157
| sym.main ();
| ; var size_t local_20h @ rbp-0x20
| ; var size_t size @ rbp-0x1c
| ; var char *src @ rbp-0x18
| ; var char *s2 @ rbp-0x10
| ; var char *dest @ rbp-0x8
| ; DATA XREF from entry0 (0x6bd)
| 0x000007aa  push rbp
| 0x000007ab  mov rbp, rsp
| 0x000007ae  sub rsp, 0x20
| 0x000007b2  lea rax, str.Hello          ; 0x8d4 ; "Hello"
| 0x000007b9  mov qword [src], rax
| 0x000007bd  lea rax, str.r2_folks       ; 0x8da ; " r2-folks"
| 0x000007c4  mov qword [s2], rax
| 0x000007c8  mov rax, qword [src]
| 0x000007cc  mov rdi, rax                ; const char *s
| 0x000007cf  call sym.imp.strlen         ; size_t strlen(const char *s)

It also extracts type information from format strings like printf ("fmt : %s , %u , %d", ...), the format specifications are extracted from anal/d/spec.sdb

You could create a new profile for specifying a set of format chars depending on different libraries/operating systems/programming languages like this :

win=spec
spec.win.u32=unsigned int

Then change your default specification to newly created one using this config variable e anal.spec = win

上一页代码分析下一页类型

最后更新于4年前

这有帮助吗?

Like many other things variables detection is performed by radare2 automatically, but results can be changed with those arguments/variables control commands. This kind of analysis relies heavily on preloaded function prototypes and the calling-convention, thus loading symbols can improve it. Moreover, after changing something we can rerun variables analysis with afva command. Quite often variables analysis is accompanied with , see afta command.

Let's see an example of this with a simple binary

For more information about primitive and user-defined types support in radare2 refer to chapter.

types analysis
hello_world
types