본문 바로가기

Technical Docs/IOS

[lldb-10] Anti-Debugging :ptrace (근데 이제 frida를 곁들인)

ptrace를 이용한 안티 디버깅은 여러 방법 중 하나임

함수 궁금증이 있어 관련 정보를 찾아 봄

 

목적 : lldb-10를 이용한 값 변경이기 때문에 디버가 붙기 전 frida를 사용할 예정
사용 lldb-10 명령어
1. proceaa attach -n [AppName]
2. image dump sections [AppName]
3. bs
4. c
5. n
6. register read
7. register write

 

ptrace는 XXXXXXXXXXXXXXXXXXXXX 임

 

총 4개 인자로 이루어져 있으며, 첫 번째 인자 값으로 안티 디버깅 적용할 수 있음

int	ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);

_request에 사용되는 ptrace 정의

#define	PT_TRACE_ME	0	/* child declares it's being traced */
#define	PT_READ_I	1	/* read word in child's I space */
#define	PT_READ_D	2	/* read word in child's D space */
#define	PT_READ_U	3	/* read word in child's user structure */
#define	PT_WRITE_I	4	/* write word in child's I space */
#define	PT_WRITE_D	5	/* write word in child's D space */
#define	PT_WRITE_U	6	/* write word in child's user structure */
#define	PT_CONTINUE	7	/* continue the child */
#define	PT_KILL		8	/* kill the child process */
#define	PT_STEP		9	/* single step the child */
#define	PT_ATTACH	10	/* trace some running process */
#define	PT_DETACH	11	/* stop tracing a process */
#define	PT_SIGEXC	12	/* signals as exceptions for current_proc */
#define PT_THUPDATE	13	/* signal for thread# */
#define PT_ATTACHEXC	14	/* attach to running process with signal exception */
#define	PT_FORCEQUOTA	30	/* Enforce quota for root */
#define	PT_DENY_ATTACH	31
#define	PT_FIRSTMACH	32	/* for machine-specific requests */

ptrace 정보 확인

 

안티 디버깅을 적용한 앱은 디버거 연결되지 않음

 

바이너리 파일에 ptrace 정보 확인

  1. 0x9494 = ptrace
  2. 0x94B8 = 0x1f / PT_DENY_ATTACH 선언

 

frida를 이용해 "ptrace" 사용 및 인자 값 확인

Interceptor.attach(Module.findExportByName(null, "ptrace"), {
    onEnter: function (args) {
        console.log("[ptrace] " + args[0] + " " + args[1] + " " + args[2] + " " + args[3]);
    },
    onLeave: function (retval) {
        console.log("[return] " + retval);

    }
});

 

결과, "ptrace" 이용 및 첫 번째 인자 값이 "0x1f(PT_DENY_ATTACH)"로 선언됨을 확인

define 16진수 10진수
PT_DENY_ATTACH  0x1f 31

 

 

 


frida

 

Interceptor.attach(Module.findExportByName(null, "ptrace"), {
    onEnter: function (args) {
        console.log("[ptrace] " + args[0] + " " + args[1] + " " + args[2] + " " + args[3]);
        if (args[0] == 0x1f) {
            args[0] = ptr("0xA");
        }
    },
    onLeave: function (retval) {
        console.log("[return] " + retval);

    }
});

 

 


lldb-10

사전 필요 정보 "PT_DENY_ATTACH" 주소

  1. 0x94B8 = 0x1f / PT_DENY_ATTACH 선언

로직 추측 : 앱 실행 ⇀ 디버거 탐지  ⇀ 루팅 탐지

앱 실행과 동시에 디버거 탐지로 인해 sleep 설정하여 frida attach 시도

Thread.sleep(3);
Interceptor.attach(Module.findExportByName(null, "ptrace"), {
    onEnter: function (args) {
        console.log("[ptrace] " + args[0] + " " + args[1] + " " + args[2] + " " + args[3]);
    },
    onLeave: function (retval) {
        console.log("[return] " + retval);

    }
});

1. Thread.sleep 확인
2. $ frida -l sleeep.js -U --no-pause -f [AppName]
3. Spawing 확인
4. 디버깅할 앱 Attach
  4-1. $ lldb-10
  4-2. $ process attach -n [AppName]

 

lldb-10가 attach 될 경우 아래와 같이 확인 가능

 

image 명령어를 통해 파일 및 공유 라이브러리의 모든 섹션 덤프 함

ptrace에 브레이크포인트를 위해 빨간 박스 되어 있는 "0x00000001044a4000" 주소 값을 가져옴

image dump sections [AppName]
image dump sections safari

 
브레이크 포인트를 설정하기 위해 ptrace 첫번째 인자 값 주소(0x94B8)와 시작 위치의 주소(0x00000001044a4000) 주소 값을 더한 뒤 "C" 명령어 실행하면 해당 함수까지 진행되며, 바이너리에서 본 코드를 확인할 수 있음
br s -a 0x94B8+0x00000001044a4000
c
 

"n" 입력한 뒤 w0 값을 확인할 경우 0x1F(PT_DENY_ATTACH, 10진수 31)가 선언됨

n
register read w0

 

w0 값을 0xA(PT_ATTACH, 10진수 10)로 변경한 뒤 "c" 실행

register write x0 0xa
register read w0
c

 

결과, "ptrace" 첫 번째 인자 값이 "0xa(PT_ATTACH)"로 변경됨

 


마치며

lldb-10을 이용해 간단하게 디버깅 하는 법을 배움

이 방법을 이용해 다양한 디버깅 시도가 가능할 것으로 예상됨

 

frida를 사용하지 못하는 환경일 경우 차선책 필요

 

참고

https://opensource.apple.com/source/xnu/xnu-792.13.8/bsd/sys/ptrace.h

 

 

'Technical Docs > IOS' 카테고리의 다른 글

IOS에서 reverse proxy 사용하기  (0) 2024.02.16
Objective C에서 Method 앞 +,- 뭘까?  (0) 2022.06.20