angr 문서를 보고 조금 더 세부적으로 정리를 해보려고 한다. 시작!

Project

angr.project.Project

angr의 메인 클래스이다. 바이너리 분석을 위한 클래스.

>>> angr.project.Project
<class 'angr.project.Project'>

parameters

  • thing - 분석할 바이너리 또는 CLE 로더. 당연하게도 필수적으로 들어가야 한다.
  • default_analysis_mode - 분석 모드. 기본적으로 'symbolic'으로 설정되어 있다.
  • arch - The target architecture. 따로 설정하지 않으면 알아서 angr가 찾는다.

등등 굉장히 많지만 생략하겠다.

variables

>>> p=angr.Project('unbreakable')
# The available analyses
>>> p.analyses
<angr.analyses.analysis.AnalysesHub object at 0x7f8ea961f6d0>
# The program entrypoint
>>> p.entry
0x400729
# 실행 결과 등 중요한 분석 요소에 접근할 수 있게 해준다.
>>> p.factory
<angr.factory.AngrObjectFactory object at 0x7f8eb0a79040>
# filename
>>> p.filename
'unbreakable'
# The program loader
>>> p.loader
<Loaded unbreakable, maps [0x400000:0x5008000]>
# Dictionary of things that should be loaded/stored with the Project.
>>> p.storage
defaultdict(<class 'list'>, {})

hook

후킹하는 데 사용된다.

>>> @p.hook(p.entry)
... def my_hook(state):
...     print("HELLO WORLD!")

parameters

  • addr - 후킹할 주소
  • length - 후킹이 끝난 후 몇 바이트를 뛰어넘어 실행할 것인지.
  • replace - 이미 후킹된 주소를 다시 후킹하려고 할 때, 이 값이 참이려면 후킹을 하고 거짓이라면 후킹하지 않고 경고를 한다. 기본적으로 거짓이다.
WARNING | 2020-04-26 19:28:02,851 | angr.project | Address is already hooked, during hook(0x400729, <function my_hook at 0x7f8ea93b6d30>). Not re-hooking.
# 그 주소가 후킹되어 있으면 참을 반환한다.
>>> p.is_hooked(p.entry)
True
# 그 주소를 어떤 놈이 후킹했는지 반환한다.
>>> p.hooked_by(p.entry)
<SimProcedure UserHook>
# 후킹 해제
>>> p.unhook(p.entry)

angr.factory.AngrObjectFactory

The factory provides access to important analysis elements.

blank_state

대부분 초기화되지 않은 Simstate를 리턴한다. Simstate는 뒤에서 다룰 것이다.

parameters

  • addr - state가 entry point 대신 시작하는 주소값

  • initial_prefix - 이 값이 문자열로 설정되어 있으면, 모든 symbolic 레지스터는 그 문자열이 앞에 붙어있는 이름과 symbolic 값을 가진다.

  • chroot - 리눅스의 chroot

entry_state

entry point에서 바이너리를 나타내는 Simstate를 리턴한다.

parameters

  • 위에 있는 거 다 포함.
  • argc - 바이너리 argc 설정. 따로 값 안주면 args의 길이로 알아서 설정된다.
  • args - 바이너리 argv 설정. 문자열도 되고 bit-vector도 된다.
  • env - 바이너리 환경변수 설정.

full_init_state

entry_state랑 굉장히 유사한데, 바이너리가 아닌 SimProcedure에서 실행하는 것만 다르다.

call_state

주어진 함수의 초기 state를 리턴한다.

parameters

  • addr
  • args - function call에 사용될 argv
  • base_state - blank state 대신 이 state를 사용한다.
  • ret_addr - return address 설정

등등 많은데 사실 안쓸거 같다.

simulation_manager

Constructs a new simulation manager. 편하게 simgr로 쓸 수 있다.

parameters

  • thing : Simstate

Program State

angr.sim_state.SimState

SimState는 메모리, 레지스터 등등 프로그램의 상태를 표시한다.

parameters

  • project - The project instance
  • arch - The architecture of the state
>>> state = p.factory.entry_state()
>>> state
<SimState @ 0x400729>

variables

  • regs - state의 레지스터
>>> state.regs
<angr.state_plugins.view.SimRegNameView object at 0x7f8ea95766d0>
>>> state.regs.rax
<BV64 0x1c>
  • mem - state의 메모리
>>> state.mem[p.entry].char
<char <BV8 49> at 0x400729>
  • registers - state의 레지스터 파일 as a flat memory region
  • memory - state의 메모리 as a flat memory region
  • solver - symbolic solver, variable manager
  • posix : information about the operating system or environment model

add_constraints

state에 조건을 걸어준다. solver를 이용하기 위해서겠지?

step

symbolic execution을 한 단계 진행하고 그 결과를 리턴한다.

지금 필요한 기능들만 정리를 하였고 문제를 풀다가 추가적으로 정리할 게 있으면 수정하겠음.

+ Recent posts