Ghidra Python Script

­3zu·2022년 6월 23일
0

졸업프로젝트

목록 보기
1/3
post-thumbnail

Ghidra에서 Python Script 만들기

Ghidra에서 python으로 script를 작성해보자.

Ghidra를 켜면 이렇게 script manager를 켤 수 있는 버튼이 있다.

그러면 이렇게 이미 만들어져있는 많은 스크립트를 볼 수 있다.
직접 스크립트를 작성하기 위해서는 이 버튼을 눌러서 bundle manager를 실행시켜야 한다.

bundle manager를 보면 내가 작성한 스크립트가 저장될 것 같은 폴더가 not found...
그래서 새로운 폴더를 생성해 지정해보자.

그러면 이렇게 초록색으로 사용가능한 폴더가 추가되었다.
이제 이 폴더에 python으로 스크립트를 작성해 저장하면 된다.

그러면 이렇게 오른쪽에 script를 쓸 수 있는 창이 생긴다.

저장한 후 hello.py를 더블클릭하면

이렇게 콘솔에 제대로 명령어가 출력되는 것을 볼 수 있다.

계속 ghidra.app.decompiler같은 package를 import해서 사용하는 예제가 엄청 많은데 이렇게 Ghidra 내에서 스크립트를 작성해 사용하면 이걸 찾아서 install할 필요가 없는 것 같다.

솔직히 install 할 수 있는지도 모르겠다.
사실 저 패키지 없이는 유의미한 뭔가를 할 수 없는 상황이었어서 어떻게든 살아보려고(?) 설치 방법을 찾는 도중 찾은 방법이다.

교수님께 여쭤보니 기드라 외부에서 코드를 돌리는건 고오급기술이라 복잡하다고 하심. 내부에서 해결하자.
Ghidra의 Window - Python에서 Python shell을 열 수 있다!

다른 예제

짤막한 snippet을 몇 개 더 실행해보자.
이 snippet은 여기에서 구한 것이다.

내가 이 snippet을 적용한 코드는 유명한 abex' crackme 이다.
그냥 검색하면 다운받을 수 있는데 검색하면 나오는 블로그 중 하나 링크를 단다.

snippet 중 아래를 보자.

value = 0x00401010

## transform to a Ghidra Address object
addr = toAddr(value)

## get the containing function
fn = getFunctionContaining(addr)

## get the function's entry point
entry = fn.getEntryPoint()

print(addr)
print(fn.getName())
print(entry.toString())

value의 값은 내가 임의로 바꾼 것이다. 이 value의 값은 Ghidra로 확인할 수 있는 function 안에 속한 주소이다.

위의 snippet을 실행하면 value에 담긴 주소를 toAddr()에 넣어 그 address를 addr에 넣는다.
그리고 getFunctionContaining()을 통해 addr를 담고 있는 function을 fn에 넣는다.

getEntryPoint()를 사용하면 fn의 entry point를 entry에 담을 수 있다.

위의 script를 실행시킨 결과는 다음과 같다.

함수의 이름은 entry(), entry point의 주소는 0x00401000이다.

초기 value의 값은 function의 entry point인 0x00401000이 될 수도 있다.
함수 entry()내의 모든 주소는 다 같은 결과가 나온다.

다음 snippet을 보자.

## let fn be a function
callers = fn.getCallingFunctions(monitor)
print(callers)

callees = fn.getCalledFunctions(monitor)
print(callees)

이 snippet은 function의 caller와 callee를 출력해준다.
실행결과는 아래와 같다.

결과를 보면, entry()를 호출한 caller는 없고, entry()가 호출한 callee는 총 3개임을 확인할 수 있다.

기존의 결과와 동일함을 확인할 수 있다.

다음 snippet을 보자.

import ghidra.app.decompiler as decomp

## let addr be a valid Address
fn = getFunctionContaining(addr)

## get the decompiler interface
iface = decomp.DecompInterface()

## decompile the function
iface.openProgram(fn.getProgram())
d = iface.decompileFunction(fn, 5, monitor)

## get the C code as string
if not d.decompileCompleted():
    print(d.getErrorMessage())
else:
    code = d.getDecompiledFunction()
    ccode = code.getC()
    print(ccode)
    

위의 code는 addr(위처럼 valid한, 함수 내부의 address)를 주면 그것을 가지고 decompile interface인 iface를 얻는다.

그것을 가지고 decompile해서 그 결과를 C로 출력하는 코드이다.

결과는 다음과 같다.


[참고자료]
https://hackyboiz.github.io/2021/03/07/idioth/ghidra_part2/
https://deadc0de.re/articles/ghidra-scripting-python.html

0개의 댓글