아주 예전에 잠깐 해봤었던 IDA Plugin 개발에 대해 간략하게 적고자한다.
IDA Plugin을 개발하기 위해서는 IDAPython을 활용해야 한다.
먼저 References
IDA 파이썬 공식 API 레퍼런스:
https://www.hex-rays.com/products/ida/support/idapython_docs/
IDA 파이썬 공식 예제 모음:
https://github.com/idapython/src/tree/master/examples
IDA 파이썬 가이드 모음:
https://reverseengineering.stackexchange.com/questions/11391/good-training-for-idapython
IDA 파이썬 간단 가이드 (한글):
https://suspected.tistory.com/244?category=773669
Action 의 등록과 사용
IDA 파이썬 모듈 별 예제:
https://www.programcreek.com/python/example/85186/idaapi.action_desc_t
BWN value검색
IDA Python 함수
- 주소 얻는 함수
idc.get_screen_ea(), idc.here(), idc.ScreenEA() : 커서가 있는 곳의 주소를 리턴해 준다.

idc.MinEA(), idc.MaxEA() : 최대, 최소 주소를 리턴해 준다.

idc.get_inf_attr(INF_MIN_EA 또는 INF_MAX_EA) : 처음과 끝의 주소를 리턴해 준다.
- 각 영역의 정보 얻기
idc.SegName(주소)(= idc.get_segm_name(주소)),
idc.SegStart(주소)(=idc.get_segm_start(주소)),
idc.SegEnd(주소)(=idc.get_segm_end(주소)) : 주소에 대한 영역 이름, 시작, 마지막 주소 리턴

idautils.Segments() : 모든 영역을 거치는 함수
idc.get_next_seg(주소) : 다음 영역을 찾아준다
idc.selector_by_name(세그먼트 이름) : 세그먼트 셀렉터를 리턴, 실행파일의 각영역 개수에 따라 증가

- 함수 정보 리턴
idc.GetFunctionName(주소)(=idc.get_func_name(주소)) : 입력 주소의 함수 이름을 리턴

idc.get_name_ea_simple(이름) : 함수 이름으로 함수 주소를 리턴

idc.set_name(함수의 시작 주소, name, SN_CHECK) : 해당 주소의 함수의 이름을 바꾼다.
idautils.Functions(시작 주소, 마지막 주소) : 함수 목록을 리스트 형태로 리턴


idaapi.get_func(ea) : 클래스 타입으로 그 주소가 있는 함수의 경계를 리턴
* func.startEA = 함수시작
* func.endEA = 함수끝 (참고로 ea는 '분석된' 함수경계 '내부'에 있어야한다.)


idc.create_insn(주소) : 열거 과정이 없는 빨간색레이블으로 표시되는 함수를 고정하거나 자동화한다.
Funcltems (주소) : 지정한 함수 주소에서 모든 주소를 리턴해 준다, 리턴 값이 iterator이다.

Names : 이름을 가지고 있는 주소를 리턴해 준다, 리턴 값이 iterator 형태이다.

idautils.DataRefsTo(주소) : 주소가 쓰인 곳 모두 반환
idautils.DataRefsFrom(주소) : 주소에서 쓰는 데이터들의 주소 반환
idautils.CodeRefsTo (주소, 0/1) : 주소를 참조하는 곳을 iterator 형태로 리턴

idautils.XrefsTo : CodeRefsTo와 비슷하지만 type 값을 확인
xref.type( = idautils.XrefTypeName(xref.type)) : xrefs type value 출력
xref.iscode : 참조된 주소가 코드 세그먼트에 존재하면 1를 리턴
Xref type value
0 = Data_Unknown
1 = Data_Offset
2 = Data_Write
3 = Data_Read
4 = Data_Text
5 = Data_information
16 = Code_Far_Call
17 = Code_Near_Call
18 = Code_Far_Call
19 = Code_Nead_Jump
20 = Code_User
21 = Ordinary Flow
idautils.CodeRefsFrom(주소, 0/1) : 주소가 정의된 곳을 참조
0 과 1 은 False 와 True 를 가리킨다.
- 어셈블리 코드 리턴
idc.GetDisasm(주소)( = idc.print_insn_mnem(주소)) : 해당 주소의 어셈블리 코드를 리턴

- 플래그 값 리턴
idc.GetFunctionFlags(주소) : 주소의 플래그 값을 리턴


FUNC_NORET(0X00000001) : 리턴 명령을 수행하지 않는 함수를 가리킨다.
FUNC_LIB (0X00000004) : 라이브러리 함수를 가리킨다.
FUNC_STATIC (0X00000008) : 정적 함수로 컴파일된 함수를 가리킨다.
FUNC_FRAME (0X00000010) : 프레임 포인터를 사용하는 함수를 가리킨다.
FUNC_TUNK : 점프 함수인 TUNK 를 식별하는 데 사용된다.
- 명령어 리턴
GetMnem(주소) : 해당 주소의 명령어를 리턴

- 오퍼랜드 리턴
GetOpnd(주소, 숫자)( = idc.print_operand(주소, 숫자), idc.get_operand_value(주소, 숫자)) : 주소의 n 번째 오퍼랜드 값을 리턴

GetOpType(주소, 숫자) : 주소의 n 번째 오퍼랜드 타입을 리턴
O_void : 오퍼랜드가 없을 때 0 리턴
O_reg : 오퍼랜드가 일반 레지스터 이면 1을 리턴
O_mem : 오퍼랜드가 직접적으로 메모리를 참조하면 2를 리턴
O_phrase : 오퍼랜드가 인덱스 레지스터로 구성된 경우 3을 리턴
O_displ : 오퍼랜드가 레지스터, 변위값으로 구성된 경우 4를 리턴
O_imm : 두 번째 오퍼랜드의 값이 정수와 같은 값이면 5를 리턴
- 바이트 검색
idc.find_binary(주소, flag, 검색 바이트) : 해당 주소에서부터 조건에 따라 바이트를 검색

* flag 목록
SEARCH_UP = 0
SEARCH_DOWN = 1 # 위 또는 아래 방향
SEARCH_NEXT = 2 # 다음 찾기
SEARCH_CASE = 4 # 대소문자 구별 여부
SEARCH_REGEX = 8
SEARCH_NOBRK = 16
SEARCH_NOSHOW = 32
SEARCH_UNICODE = 64 **
SEARCH_IDENT = 128 **
SEARCH_BRK = 256 **
**은 ida 옛날버전은 지원 X
- 문자열 찾기
idc.find_text(주소, flag, y, x, 검색 문자열) : flag 의 조건에 따라 주소에서 부터 문자열을 검색


- 주소의 특징 판단
idc.is_code(주소) : 해당 주소부분이 코드면 True
idc.is_data(주소) : 해당 주소부분이 데이터면 True
idc.is_unknown(주소) : 해당 주소부분이 unknown 이면 True
idc.find_code(주소, flag) : 다음 코드부분을 반환
ex) addr = idc.find_code(주소, SEARCH_DOWN|SEARCH_NEXT)
idc.find_data(주소, flag) : 다음 데이터부분을 반환
ex) addr = idc.find_data(주소, SEARCH_UP|SEARCH_NEXT)
idc.find_unknown(주소, flag) : 다음 unknown 부분을 반환
idc.find_defined(주소, flag) : 다음 unknown 이 아닌 부분을 반환
idc.find_imm(주소, flag, 상수) : 특정 상수 값을 찾기. (주소, 오퍼랜드에서의 위치) 튜플을 반환
ex) 0x343fd찾기
addr = idc.find_imm(get_inf_attr(INF_MIN_EA), SEARCH_DOWN, 0x343FD )
- 바이트 가져오기
idc.get_wide_byte(주소)
idc.get_wide_word(주소)
idc.get_wide_dword(주소)
idc.get_qword(주소)

idc.GetFloat(주소)
idc.GetDouble(주소)

- 바이트 수정
idc.patch_byte(주소, 수정 바이트)
idc.patch_word(주소, 수정 바이트)
idc.patch_dword(주소, 수정 바이트)
처음에 자료 정리할 때, 누군가의 블로그를 본 것 같은데...
댓글남겨주시면 바로 출처 적겠습니다.
'Rev > Info' 카테고리의 다른 글
[Malware] Formbook (0) | 2021.12.27 |
---|---|
[Excel] Very hidden Sheet VBA Macro (0) | 2021.12.27 |
Decompilation failure - positive sp value has been found (0) | 2021.01.13 |
Python3 Angr Install & How to use (0) | 2021.01.04 |
RecStudio - Decompile [MIPS] (0) | 2019.10.28 |