'디버깅'에 해당되는 글 1건

  1. 2012.10.04 Cycript 소개
iOS2012. 10. 4. 16:31

Cycript 를 소개하겠습니다.

Cycript 는 본래 javascript와 Obj-C 를 결합한 스크립트의 인터프리터 이지만

실행중인 프로세스에 침투하여 프로퍼티를 변경하고 함수를 동적으로 후킹하는ㅜ, 개발자가 존경스러워지는,

엄청난 기능을 가지고 있습니다.

이것으로 무엇을 할 수있는지만 간단히 알아보겠습니다.

ssh 로 아이폰(물론 JailBroken 된) 쉘에 접속한후 -p 옵션을 이용하여 요즘 대세인 애니팡 프로세스에 접속합니다.

Link9-iPhone:/var/mobile/Documents root# ps aux | grep pang
mobile    2432  39.0 15.2   483860  78744   ??  Rs    3:14PM   0:17.45 /var/mobile/Applications/7BD9255D-E2AD-467A-B393-DCCC40FF3864/Anipang-iOS.app/Anipang-iOS root      2445   0.0  0.1   273028    420 s000  R+    3:15PM   0:00.01 grep pang
Link9-iPhone:/var/mobile/Documents root# cycript -p 2432 std.cy
8
Link9-iPhone:/var/mobile/Documents root# cycript -p 2432
cy#


cycript 쉘에서는 obj-c 언어를 컴파일과정없이 실행중인 프로세스에 동적으로 한줄한줄 명령을 내리고 메세지를 보내는 환상적인 자유를 느낄수있습니다 ^^

아이폰 프로그래밍을 조금이라도 해본 분은 아시겠지만 아이폰 앱은 객체지향언어인 Obj-c 를 기본으로 하며, View hierarchy 로 이루어져 있습니다.

먼저 UIApplication 의 객체 주소를 얻어내고 key 윈도우의 recursiveDescription 을 출력해봅시다. 디버깅에 매우 유용한 API 입니다. gdb 에서도 자주 사용합니다.

cy# var app = [UIApplication sharedApplication]
"<CTApplication: 0x1b6cc20>"
cy# app.keyWindow.recursiveDescription
"<UIWindow: 0x199a2c0; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x199a3b0>>\n   | <CTStandaloneView: 0x1b7ab60; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x1b7abf0>>\n   |    | <CTStageView: 0x1b7ad20; frame = (0 0; 320 480); autoresize = W+H; layer = <CAEAGLLayer: 0x1b70fc0>>"
cy# var stageview = new Instance(0x1b7ad20)
"<CTStageView: 0x1b7ad20; frame = (0 0; 320 480); autoresize = W+H; layer = <CAEAGLLayer: 0x1b70fc0>>"

1개의 key 윈도우와 2개의 View 로 이루어져있는것을 볼 수 있는데요.

여기까지는 gdb 로도 할 수있는 것이니, 여기서는 View 객체를 가져와서
addSubview 로 UITextView 를 추가하고 텍스트를 입력후, 화면을 45도 돌려봅시다 --;

cy# [stageview addSubview:[[UITextView alloc] initWithFrame:CGRectMake(10, 100, 200, 120)]]
cy# var xform = CGAffineTransformMakeRotation(3.14/4.0)
{a:0.70738822221755981,b:0.70682519674301147,c:-0.70682519674301147,d:0.70738822221755981,tx:0,ty:0}
cy# stageview.transform = xform
{a:0.70738822221755981,b:0.70682519674301147,c:-0.70682519674301147,d:0.70738822221755981,tx:0,ty:0}

놀랍게도 위와같이 [] 로 메세지를 보내고 . 과 = 으로 프로퍼티를 변경하는 Obj-c 문법이 가능합니다 ㅎㅎ

CTStageView 의 Sub에 UITextView 를 넣었습니다. 텍스트 입력도 문제가 없네요.

45도로 돌렸습니다. 여전히 게임은 제데로 진행중입니다 ㅋㅋ


한가지더, 저는 애니팡을 분석하여 조금더 해본게 있는데요.

[stageview pause], [stageview resume] 메세지를 보내면

게임이 완전히 멈추게 하고 다시 실행되게 할 수 있습니다.

이건 애니팡에만 적용되는 함수이지만 아주 간단한 리버싱을 통해 함수를 찾아내었습니다. 

Mach-O 바이너리 암호화를 푼후에 class-dump-z 로 클래스덤프 .h파일 추출하면 쉽게 가능합니다.


저의 cycript 소개는 여기까지 입니다! ㅋㅋ

여기에선 아주 간단한것만 보였지만 더 나아가 메소드를 찾고 후킹하는것도 가능한것같습니다.

http://iphonedevwiki.net/index.php/Cycript_Tricks 를 참고하세요.

응용하기에 따라 더 깊은 분석을 하면 애니팡의 타이머를 멈춰버릴수 있을지도 모릅니다 ;)

즐거운 아이폰 생활 되세요^^

Posted by 다오나무