import angr, monkeyhex
angr.types.parse_type('int')
angr.types.parse_type('char **')
angr.types.parse_type('struct aa {int x; long y;}')
angr.types.parse_type('struct aa {int x; long y;}').fields
angr.types.parse_defns("int x; typedef struct llist { char* str; struct llist *next; } list_node; list_node *y;")
defs = angr.types.parse_types("int x; typedef struct llist { char* str; struct llist *next; } list_node; list_node *y;")
#defs
angr.types.parse_file("int x; typedef struct llist { char* str; struct llist *next; } list_node; list_node *y;")
defs['list_node'].fields
defs['list_node'].fields['next'].pts_to.fields
angr.types.parse_type("int (int y, double z)")
angr.types.register_types(angr.types.parse_type('struct abcd { int x; int y; }'))
angr.types.register_types(angr.types.parse_types('typedef long time_t;'))
angr.types.parse_defns('struct abcd a; time_t b;')
p = angr.Project('fauxware')
s = p.factory.entry_state()
s.mem[0x601048]
s.mem[0x601048].long
s.mem[0x601048].long.resolved
s.mem[0x601048].long.concrete
s.mem[0x601048].struct.abcd
s.mem[0x601048].struct.abcd.x
s.mem[0x601048].struct.abcd.y
s.mem[0x601048].deref
s.mem[0x601048].deref.string
s.mem[0x601048].deref.string.resolved
s.mem[0x601048].deref.string.concrete
这一块代码是将二进制中的数据具体化:
步骤:
- 您首先使用 [array index notation] 来指定您要从中加载的地址
- 如果在该地址是一个指针,您可以访问 deref 属性以在内存中存在的地址处返回一个 SimMemView。
- 然后,您只需访问该名称的属性即可指定数据的类型。 有关受支持类型的列表,请查看 state.mem.types
- 然后,您可以细化类型。 任何类型都可以支持它喜欢的任何改进。 目前支持的唯一改进是您可以通过成员名称访问结构的任何成员,并且您可以索引到字符串或数组以访问该元素。
- 如果您指定的地址最初指向该类型的数组,您可以说 .array(n) 将数据视为 n 个元素的数组。
- 最后,使用 .resolved 或 .concrete 提取结构化数据。 .resolved 将返回位向量值,而 .concrete 将返回整数、字符串、数组等值,只要最能代表数据。
- 或者,您可以通过分配给您构建的属性链将值存储到内存中。 请注意,由于 Python 的工作方式,x = s.mem[...].prop; x = val 将不起作用,您必须说 s.mem[...].prop = val。
The interface works like this:
-
You first use [array index notation] to specify the address you'd like to load from
-
If at that address is a pointer, you may access the
deref
property to return a SimMemView at the address present in memory.
-
You then specify a type for the data by simply accessing a property of that name. For a list of supported types, look at
state.mem.types
.
-
You can then refine the type. Any type may support any refinement it likes. Right now the only refinements supported are that you may access any member of a struct by its member name, and you may index into a string or array to access that element.
-
If the address you specified initially points to an array of that type, you can say
.array(n)
to view the data as an array of n elements.
-
Finally, extract the structured data with
.resolved
or.concrete
..resolved
will return bitvector values, while.concrete
will return integer, string, array, etc values, whatever best represents the data.
-
Alternately, you may store a value to memory, by assigning to the chain of properties that you've constructed. Note that because of the way Python works,
x = s.mem[...].prop; x = val
will NOT work, you must says.mem[...].prop = val
.
可调用对象是用于符号执行的外部函数接口 (FFI)。 基本的callable用法是用myfunc = p.factory.callable(addr)创建一个,然后调用它! result = myfunc(args, ...) 当你调用 callable 时,angr 会在给定的地址设置一个 call_state,将给定的参数转储到内存中,并根据这个状态运行一个 path_group,直到所有路径都退出 功能。 然后,它将所有结果状态合并在一起,将返回值拉出该状态,然后返回。