Security Tech
iOS에서 Frida 시작하기 (2탄)
작성자 - 보안왕 김보안최근에 안드로이드 위주로 Frida를 다뤄봤는데, 이번에는 iOS 앱 후킹을 공부해봤다.
안드로이드랑 다른 점이 많아서 비교 위주로 정리한다.

1. 안드로이드 vs iOS 기본 뼈대
- 안드로이드: 항상
Java.perform()안에서 후킹해야 안정적 - iOS:
ObjC.schedule(ObjC.mainQueue, …)안에서 후킹하는 게 일반적 (특히 UI 관련 메서드)
// 안드로이드 기본
Java.perform(function () {
// ...
});
// iOS 기본
if (ObjC.available) {
ObjC.schedule(ObjC.mainQueue, function () {
// ...
});
}
안드로이드는 Java.use("클래스명")으로 접근하지만, iOS는 ObjC.classes.클래스명으로 접근한다.
2. 메서드 지정 방식
- 안드로이드: 메서드 오버로딩이 많아서
.overload('int','int')같이 인자 타입 지정 필요 - iOS: 메서드 이름이 selector로 구분됨
- 인스턴스 메서드:
"- 메서드명:" - 클래스 메서드:
"+ 메서드명:"
- 인스턴스 메서드:
// 안드로이드 예시
var addInt = Calc.add.overload('int','int');
// iOS 예시
var VC = ObjC.classes.UIViewController;
var method = VC["- viewDidAppear:"];
인스턴스 메서드 vs 클래스 메서드
- 인스턴스 메서드(-): 객체(인스턴스)를 생성한 후 그 인스턴스에 대해 호출하는 메서드
- 예:
myViewController.viewDidAppear()
- 예:
- 클래스 메서드(+): 객체를 만들지 않고 클래스 자체에서 직접 호출하는 메서드
- 예:
[UIApplication sharedApplication]은 클래스 메서드 호출
- 예:
즉, selector 앞의 - / + 기호로 어떤 타입의 메서드인지 구분된다.
3. 함수/클래스 탐색
안드로이드와 마찬가지로 이름을 모르면 탐색해야 한다.
- 안드로이드:
Java.enumerateLoadedClasses - iOS:
ObjC.enumerateLoadedClasses
// iOS 예시
ObjC.enumerateLoadedClasses({
onMatch: function (name) {
if (name.indexOf("Security") !== -1) {
console.log(name);
}
},
onComplete: function () {
console.log("Done");
}
});
또한 특정 클래스의 메서드 확인은 $ownMethods()를 쓰면 된다.
var Cls = ObjC.classes.UIApplication;
Cls.$ownMethods().forEach(function (m) { console.log(m); });
4. 후킹 예제 비교
안드로이드
var addInt = Calc.add.overload('int','int');
addInt.implementation = function (a,b) {
console.log("add called");
return addInt.call(this,a,b);
};
iOS
var VC = ObjC.classes.UIViewController;
var m = VC["- viewDidAppear:"];
Interceptor.attach(m.implementation, {
onEnter: function (args) {
var self = new ObjC.Object(args[0]);
console.log(self.$className() + " viewDidAppear:");
}
});
차이점:
- 안드로이드는
.implementation을 직접 재정의 - iOS는
Interceptor.attach로 진입/리턴 지점에 후킹
5. 예제: 탈옥 탐지 함수 관찰
ObjC.schedule(ObjC.mainQueue, function () {
var Sec = ObjC.classes.SecurityChecker;
var detect = Sec["- detectJailbreak"];
Interceptor.attach(detect.implementation, {
onEnter: function () {
console.log("detectJailbreak() called");
},
onLeave: function (retval) {
console.log("detectJailbreak() returned");
}
});
});
안드로이드에서 루팅 탐지 우회를 후킹하는 흐름과 비슷하지만, iOS는 selector 기반으로 집어야 한다는 차이가 있다.
6. 마무리
안드로이드 vs iOS 정리 포인트:
- 실행 환경 진입점:
Java.performvsObjC.schedule - 클래스 접근:
Java.usevsObjC.classes - 메서드 식별: 오버로딩 vs selector (
-인스턴스,+클래스) - 후킹 방법:
.implementation덮어쓰기 vsInterceptor.attach
아직 네이티브 함수(open, ptrace, sysctl) 레벨 후킹은 더 공부가 필요하다.
일단은 ObjC 레벨 후킹에 익숙해지는 게 1순위일 듯.
'Security Tech' 카테고리의 다른 글
| Frida 스크립트 작성 기초(안드로이드 예제) (1) | 2025.08.31 |
|---|---|
| 차량 사이버 보안 - 진단 프로토콜 및 보안 기능 (0) | 2025.08.31 |
| 웹 LLM 공격 (1) | 2025.06.30 |
| MITM RELAY 를 활용한 TCP 패킷 변조 (0) | 2025.06.30 |
| OWASP - MASTG UnCrackable-LEVEL 3 (2) (0) | 2025.05.31 |
Contents