1. Frida는 뭘까요

1. Frida는 뭘까요

2024년 11월 3일

서론 #

출처 : https://learnfrida.info/
추가1. 스토커의 해부학
추가2. frida document

이 글에서는 툴 사용법에 대한 내용은 담지 않을 것이기 때문에 사용법을 보려면 출처의 링크에서 확인하거나 frida document에서 확인할 수 있다.


Frida 란? #

Dynamic Binary Instrumentation(동적 바이너리 계측)을 지원하는 툴로 프로그램 런타임에 코드를 삽입해서 동작을 분석하거나 메모리를 수정할 수 있는 도구이다.

intel의 PIN과 DynamoRIO 와 비슷한 도구이지만, PC, 모바일, 여러 아키텍쳐 등 지원 범위가 넓고 C/C++ 코드 작성 및 컴파일 없이 자바스크립트 코드 상태로 쉽게 인젝트 할 수 있는 무료 오픈소스 도구라는 것이 큰 장점이다.


DBI 플로우 #

보통 어플리케이션을 계측할때 플로우는 아래 그림과 같다.

8a412ba4-6e49-4383-87b6-5ee30f1affac

  1. 컨트롤 스크립트에서 계측을 위한 스크립트를 버퍼에 읽어온다.
  2. 컨트롤 스크립트에서 타겟 프로세스를 스폰하고 suspend 상태로 만든다.
  3. 컨트롤 스크립트는 타겟에 계측 스크립트를 인젝트하고, 추가적인 콜백을 리슨한다.
    • on_message : 타겟에서 컨트롤 스크립트로 데이터를 전송할 수 있도록 등록하는 콜백 (send 나 console.log 같은것)
    • on_child_added : 자식프로세스가 생성되면 보내주는 콜백이고, 이걸 이용해서 자식프로세스 생성 시점을 확인할 수 있어서 자식프로세스 추가 후킹이 가능해진다.(child-gating)
  4. 계측 스크립트는 타겟 프로세스에서 실행되면서 여러 데이터를 컨트롤 스크립트로 전달한다.
  5. 컨트롤 스크립트는 전달받은 데이터를 처리한다.(로그 저장이나 RPC 호출 등)
  6. 컨트롤 스크립트는 모든 작업이 끝나면 계측을 해제하고 타겟 프로세스를 정상 상태로 복원한다

frida 주요 프로젝트 #

frida 는 기능별(네이티브 후킹, js지원, cpp지원 등)로 여러 프로젝트로 나뉘어 있고 원한다면 각각의 프로젝트 중 필요한 프로젝트만 사용할 수 있지만, frida 전체 프로젝트를 빌드하면 모든 프로젝트 기능들이 합쳐져서 frida-server 바이너리에 포함되는 구조이다.

b53d5418-6340-4100-8b9d-d5b418b54926

frida-tools #

frida-server에 명령을 보내는 cli 도구로, frida-server가 받는 프로토콜에 맞춰서 쉽게 요청을 보내도록 미리 작성된 코드들이다.

frida-server #

루팅된 장치에서 실행되는 서버로, frida-core 코드를 내장하고 그 기능을 클라이언트에게 제공한다. frida-server 프로젝트는 없고, frida-core를 빌드할때 아키텍쳐별로 frida-server 바이너리 파일이 빌드된다.

frida-core #

타겟 프로세스에 frida-agent 라이브러리를 주입하고 통신을 처리하면서 Frida의 API들을 사용자에게 제공한다.

frida-agent #

frida-core에 의해 주입된 공유 라이브러리 frida-agent-64.so 이며, js 코드를 실행시킬 수 있는 런타임이 포함되어 계측을 위한 js 스크립트를 실행시키거나 네이티브 후킹을 위한 gum 코드가 포함된다.
frida-core와 IPC로 통신하며 gum이나 v8을 통한 함수를 호출해준다.

frida-gum #

네이티브 코드 후킹이나 메모리 조작, 명령어단위 추적을 위한 실제 코드가 아키텍쳐마다 구현되어 있고, 바인딩된 gumpp, gumjs에서 호출할 수 있도록 인터페이스가 노출되어 있다.

gumjs(+v8) #

타겟 프로세스에 주입된 js 런타임(v8기반)을 말하며 js 코드의 실행을 담당하고, js로 구현된 API를 frida-gum의 C++ 함수와 연결해준다.

gumpp #

gumjs 는 js 기반이라면 c++을 이용해서 frida를 사용할 수 있도록 만들어진 환경이 gumpp 이다.


Frida API #

주요 모듈 #

Thread #

스레드를 동작, 중지, 백트레이스 얻을때 사용한다.

Process #

프로세스의 정보를 제공하며 아키텍쳐, 포인터 크기, 코드서명 정책, 스레드 ID, 로드된 모듈(라이브러리), 실행되는 모든 스레드 정보, 메모리맵 등을 얻어올 수 있다.

Memory #

메모리에서 문자열, 숫자, 포인터, 구조체 등을 읽고 쓸 수 있는 기능을 제공하며, 메모리덤프 및 스캔해서 패턴을 검색, 권한설정 등의 기능이 있다.

Module #

로드된 모듈에서 정보를 검색하거나 외부 모듈을 로드하는 등의 작업이 가능하다

Kernel #

커널모드의 API에 대한 액세스를 제공하고 커널영역에서 사용하는 Memory, Process 모듈의 기능을 합친 느낌이다.

C Module #

C 소스코드 조각을 메모리에 인젝트하고, js 런타임에서 사용할 수 있도록한다.
C의 구조체를 파싱할때도 좋은 방법일 수 있다.


Stalker 동작 방식 #

코드 추적용 엔진으로, 호출되는 모든 명령어나 함수를 추적할 수 있다.
그냥 라인바이 라인으로 후킹해서 추적을 한다면 너무 느리기 때문에 동적 재컴파일 기술을 사용한다.

fed85cd5-d76f-441b-8a39-1e356c02e2c6

위 그림처럼 원래 실행되어야 하는 코드에 Stalker동작을 위한 코드를 추가한 사본을 만들고 이 사본을 실행시키는 방식으로 변경해서 원래 코드의 체크섬을 해치지 않는 방식으로 동작한다.

Stalker 로 전달한 실제 필요한 옵션(명령어 트레이스, 함수호출 트레이스 중 원하는 것만)에 대한 코드만 call로 포함돼서 재컴파일되기 때문에 속도도 다른 방식에 비해 빠르다.

또다른 점은 이전 함수의 call에 대한 리턴주소 또한 push 되고, 호출할 함수의 주소가 call 되는 것을 볼 수 있는데, 안티디버그나 기존 동작 보존 모두를 위한 방법이다.


Interceptor 동작 방식 #

함수 후킹을 통해 호출을 가로채서 흐름을 검사하거나 수정할 수 있는 API 인데, 트램폴린 기반 인라인 후킹을 사용한다.

bbbf655a-abd7-4e3a-b772-e689afa896d6

function_A를 후킹해서 call function_B 를 추가하고 function_B 가 끝날때 trampoline으로 점프해서 기존 function_A 에서 덮어쓰여진 코드를 실행한 후 function_A 로 점프하는 방식이다.

comments powered by Disqus