-안드로이드 Native (C, C++) .so 파일 디컴파일 하기-
IDA와 Hex ray 가 필요하다. Hex ray는 코드를 잘 정리해서 보여주는데
이게 없으면 디컴파일이 한층 더 힘드니 있는게 좋다.
그리고 원래 IDA 에서 Edit - Patch program - Assemble 을 하면
어셈블리어를 쉽게 조작 할 수 있는데, 안드로이드 so파일에 시도하면
ARM 프로세서 모듈이라면서 안해준다.
그래서 어셈블리어 레벨에서 패치는 불가하고, 기계어 레벨 패치를 해야 한다.
근데 ARM 기계어는 잘 정리된 곳을 못 찾았고
내가 쓸 코드는 MOVS, CMP, BEQ, BNE 정도 밖에 안되서 그냥 노가다로 정리 했다.
--- MOVS R0 는 기계어로 0x20 ---
MOVS R0, #1 -> 1을 R0에 저장
0x01 0x20
MOVS R1, #0
0x00 0x21
MOVS R2, #0
0x00 0x22
MOVS R2, #0x10
0x10 0x22
MOVS R3, #0
0x00 0x23
MOVS R7 R4
0x27 0x1C
MOVS R0 R5
0x28 0x1C
--- CMP R0 는 기계어로 0x28 ---
CMP R0, #0 -> R0 가 0 이면 플래그 0
0x00 0x28
CMP R3, #0
0x00 0x2B
CMP R3, #6 -> R3 이 6 이면 플래그 0
0x06 0x2B
CMP R0, R3
0x98 0x42
---BEQ, BNE 는 각각 기계어로 0xd0, 0xd1---
BEQ loc_7E4C -> 플래그 값이 0이면 점프
0x07 0xD0
BNE loc_7E52 -> 플래그 값이 0이 아니면 점프
0x04 0xD1
---------------------------------------------------
다행히 기계어 코드 패치는 프로세서에 관계없이 IDA에서 가능하다.
Edit - Patch program - Change byte 하고 Apply patches to input file 을 하면 적용 된다.
이제 한번 시험삼아 도전해 본다.
저 네모박스를 다음과 같이 고칠 것이다.
1. MOVS R0, #0 //return 에 0 복사
2. CMP R0, #0 //return 값이 0이면 Flag 0
3. BEQ loc_ret //Flag 0 이면 loc_ret 로 이동 (loc_ret은 임시로 붙인 이름)
그럼 리턴값에 0을 넣고 특정 위치로 점프한다.
단순히 NOP로 채운게 아니라서 다시 복구하거나 다른 곳으로 점프시키기도 쉽다.
먼저 1, 2번을 아까 노가다로 알아낸 기계어로 패치하면 다음과 같다.
이제 3번 BEQ점프를 하면 되는데 이것도 단순히 주소를 빼면 안되서
직접 한칸 두칸 점프해 보면서 식을 구해 보았다.
X = (목적지 주소 – 출발지
주소 – 2)/2 - 1
나는 00007E2A 에서 00007F1A 로 점프할거니까 위 식으로 계산해보면 0x76 이 나온다.
기계어 코드 패치하고 그래프를 확인 해 보면 새로운 분기가 생긴 것을 확인 해 볼 수 있다.
처음 해 보는거라 뭔가 노가다가 많이 들어갔지만 나름 재미있었고 유용할 것 같다.