如何调试变量(仅限于有调试信息的二进制文件)¶
angr 现在支持在带有调试信息的二进制文件中解析源级变量(调试变量)。本文将介绍如何使用它。
Setting up¶
To use it you need binary that is compiled with dwarf debugging
information (ex: gcc -g) and load in angr with the option
load_debug_info. After that you need to run
project.kb.dvars.load_from_dwarf() to set up the feature and we’re
set.
Overall it looks like this:
# compile your binary with debug information
gcc -g -o debug_var debug_var.c
>>> import angr
>>> project = angr.Project('./examples/debug_var/simple_var', load_debug_info = True)
>>> project.kb.dvars.load_from_dwarf()
Core feature¶
With things now set up you can view the value in the angr memory view of
the debug variable within a state with:
state.dvars['variable_name'].mem or the value that it point to if it
is a pointer with: state.dvars['pointer_name'].deref.mem. Here are
some example:
Given the source code in examples/debug_var/simple_var.c
#include<stdio.h>
int global_var = 100;
int main(void){
int a = 10;
int* b = &a;
printf("%d\n", *b);
{
int a = 24;
*b = *b + a;
int c[] = {5, 6, 7, 8};
printf("%d\n", a);
}
return 0;
}
# Get a state before executing printf(%d\n", *b) (line 7)
# the addr to line 7 is 0x401193 you can search for it with
>>> project.loader.main_object.addr_to_line
{...}
>>> addr = 0x401193
# Create an simulation manager and run to that addr
>>> simgr = project.factory.simgr()
>>> simgr.explore(find = addr)
<SimulationManager with 1 found>
>>> state = simgr.found[0]
# Resolve 'a' in state
>>> state.dvars['a'].mem
<int (32 bits) <BV32 0xa> at 0x7fffffffffeff30>
# Dereference pointer b
>>> state.dvars['b'].deref.mem
<int (32 bits) <BV32 0xa> at 0x7fffffffffeff30>
# It works as expected when resolving the value of b gives the address of a
>>> state.dvars['b'].mem
<reg64_t <BV64 0x7fffffffffeff30> at 0x7fffffffffeff38>
Side-note: For string type you can use .string instead of .mem
to resolve it. For struct type you can resolve its member by
.member("member_name").mem. For array type you can use
.array(index).mem to access the element in array.
如何查看当前可用的变量¶
如果你有许多同名但在不同作用域的变量,调用 state.dvars['var_name'] 会解析最近作用域的变量。
Example:
# Find the addr before executing printf("%d\n", a) (line 12)
# with the same method to find addr
>>> addr = 0x4011e0
# Explore until find state
>>> simgr.move(from_stash='found', to_stash='active')
<SimulationManager with 1 active>
>>> simgr.explore(find = addr)
<SimulationManager with 1 found>
>>> state = simgr.found[0]
# Resolve 'a' in state before execute line 10
>>> state.dvars['a'].mem
<int (32 bits) <BV32 0x18> at 0x7fffffffffeff34>
Congratulation, you’ve now know how to resolve debug variable using angr, for more info check out the api-doc.