Mổ xẻ ứng dụng iOS: Kỹ thuật chống debug và chống giả mạo trong thực tế

 Source: https://blog.calif.io/p/taking-apart-ios-apps-anti-debugging

https://vnhacker.substack.com/p/huy-tao

Claude: https://claude.ai/chat/d0cae64a-9476-4f17-8ff8-f9f4e693638b

EN | Taking Apart iOS Apps: Anti-Debugging and Anti-Tampering in the Wild KO | iOS 앱 해부하기: 실전에서 만나는 디버깅 방지 및 변조 방지 기법 VI | Mổ xẻ ứng dụng iOS: Kỹ thuật chống debug và chống giả mạo trong thực tế

EN | Calif / Mar 18, 2026 KO | Calif / 2026년 3월 18일 VI | Calif / Ngày 18 tháng 3 năm 2026


EN | This journey started from a mix of curiosity and convenience. Some of us wanted to push a game a bit further and show off a better score. At the same time, as part of red team work, we were interested in how banking apps handled money behind the scenes. The goal was simple: attach a debugger, observe behavior, and figure out how things worked. KO | 이 여정은 호기심과 실용적 필요가 뒤섞인 곳에서 시작되었다. 일부는 게임에서 더 높은 점수를 내고 싶었고, 동시에 레드팀 활동의 일환으로 뱅킹 앱이 내부적으로 금융 처리를 어떻게 하는지 궁금했다. 목표는 단순했다: 디버거를 연결하고, 동작을 관찰하고, 작동 방식을 파악하는 것. VI | Hành trình này bắt đầu từ sự pha trộn giữa tò mò và nhu cầu thực tế. Một số người muốn đẩy game xa hơn để khoe điểm số cao hơn. Đồng thời, trong khuôn khổ công việc red team, chúng tôi muốn tìm hiểu cách các ứng dụng ngân hàng xử lý tiền bạc ở hậu trường. Mục tiêu đơn giản: kết nối debugger, quan sát hành vi và tìm hiểu cách mọi thứ vận hành.

EN | That did not always go as expected. KO | 하지만 일이 항상 예상대로 흘러가지는 않았다. VI | Nhưng mọi thứ không phải lúc nào cũng diễn ra như kỳ vọng.

EN | Some apps would exit immediately. Others ran for a while, then failed later without any clear reason. In a few cases, there was no usable crash at all. Each app behaved differently, but after going through enough of them, the same patterns kept showing up. KO | 어떤 앱은 즉시 종료되었다. 어떤 앱은 한동안 실행되다가 뚜렷한 이유 없이 나중에 오류가 발생했다. 일부는 분석에 쓸 만한 크래시 로그조차 남기지 않았다. 앱마다 동작 방식은 달랐지만, 충분히 들여다보다 보니 동일한 패턴이 반복해서 나타났다. VI | Một số ứng dụng thoát ngay lập tức. Một số khác chạy được một lúc rồi lỗi mà không có lý do rõ ràng. Trong vài trường hợp, không có crash log nào có thể sử dụng được. Mỗi ứng dụng hoạt động theo cách khác nhau, nhưng sau khi xem xét đủ nhiều, cùng những mẫu hình đó cứ lặp đi lặp lại.

EN | Developers of these apps are not relying on a single check anymore. They combine multiple techniques to make inspection harder and modification unreliable, even on non-jailbroken devices. The techniques themselves are not new. What stands out is how they are layered together and how early they are applied. Over time, it becomes less about a single protection and more about how they interact. KO | 이런 앱의 개발자들은 더 이상 단일 검사에만 의존하지 않는다. 탈옥하지 않은 기기에서도 분석을 어렵게 하고 수정을 불가능하게 만들기 위해 여러 기법을 조합한다. 기법 자체는 새로운 것이 아니다. 주목할 점은 그것들이 어떻게 겹겹이 결합되고 얼마나 이른 시점부터 적용되는가이다. 결국 단일 보호 수단보다는 각 기법이 서로 어떻게 상호작용하는지가 핵심이 된다. VI | Các nhà phát triển ứng dụng này không còn dựa vào một cơ chế kiểm tra duy nhất nữa. Họ kết hợp nhiều kỹ thuật để khiến việc phân tích trở nên khó khăn hơn và việc sửa đổi trở nên không đáng tin cậy, ngay cả trên các thiết bị chưa jailbreak. Bản thân các kỹ thuật này không mới. Điều nổi bật là cách chúng được xếp lớp với nhau và được áp dụng từ sớm đến mức nào. Theo thời gian, vấn đề không còn là một cơ chế bảo vệ đơn lẻ mà là cách chúng tương tác với nhau.

EN | This article walks through a set of these techniques and how they show up in practice on iOS apps. KO | 이 글은 이러한 기법들의 목록과 실제 iOS 앱에서 어떻게 나타나는지를 살펴본다. VI | Bài viết này đi qua từng kỹ thuật trong số đó và cách chúng xuất hiện trong thực tế trên các ứng dụng iOS.


EN | 1. The App That Exploited iOS Side Channels KO | 1. iOS 사이드 채널을 악용한 앱 VI | 1. Ứng dụng khai thác side channel của iOS

EN | One app we looked at would fail before any meaningful logic executed. With no debugger attached and no modifications in place, the app still exits immediately on launch. KO | 우리가 살펴본 한 앱은 의미 있는 로직이 실행되기도 전에 종료되었다. 디버거도 연결하지 않고 아무것도 수정하지 않은 상태에서도 앱은 실행 즉시 종료되었다. VI | Một ứng dụng chúng tôi xem xét đã dừng lại trước khi bất kỳ logic có ý nghĩa nào được thực thi. Không có debugger nào được kết nối, không có bất kỳ sửa đổi nào, nhưng ứng dụng vẫn thoát ngay khi khởi động.

EN | It turned out the app was performing early environment checks by relying on side-channel signals rather than explicit APIs. It called into a private system API and used the return behavior to infer whether certain apps were installed on the device. If anything suspicious showed up, it stopped there. KO | 알고 보니 해당 앱은 명시적인 API 대신 사이드 채널 신호에 의존하여 초기 환경 검사를 수행하고 있었다. 비공개 시스템 API를 호출한 뒤, 반환 동작을 분석해 특정 앱이 기기에 설치되어 있는지 추론했다. 의심스러운 항목이 발견되면 그 자리에서 실행을 중단했다. VI | Hóa ra ứng dụng đang thực hiện kiểm tra môi trường sớm bằng cách dựa vào các tín hiệu side-channel thay vì API tường minh. Nó gọi vào một API hệ thống riêng tư và sử dụng hành vi trả về để suy luận xem có ứng dụng nào nhất định được cài đặt trên thiết bị hay không. Nếu có gì đó đáng ngờ xuất hiện, nó dừng lại ở đó.

EN | A notable case involved a banking application that used the private API SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions. It did not use the API for its intended purpose. Instead, it inspected the return logs as a side channel. By doing this, it could detect the presence of applications commonly associated with modified environments, based on bundle identifiers such as com.opa334.TrollStore, org.coolstar.SileoStore, com.tigisoftware.Filza, and others. If any of these were detected, the app assumed the device was not trustworthy and refused to proceed. KO | 주목할 만한 사례는 비공개 API인 SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions를 사용한 뱅킹 앱이었다. 이 앱은 해당 API를 본래 목적으로 사용하지 않았다. 대신 반환 로그를 사이드 채널로 활용했다. 이를 통해 com.opa334.TrollStore, org.coolstar.SileoStore, com.tigisoftware.Filza 등의 번들 식별자를 기반으로, 변조 환경과 관련된 앱의 존재 여부를 탐지할 수 있었다. 이 중 하나라도 감지되면 앱은 해당 기기를 신뢰할 수 없다고 판단하고 실행을 거부했다. VI | Một trường hợp đáng chú ý liên quan đến một ứng dụng ngân hàng sử dụng API riêng tư SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions. Nó không dùng API này theo mục đích thiết kế ban đầu. Thay vào đó, nó kiểm tra log trả về như một side channel. Qua đó, nó có thể phát hiện sự hiện diện của các ứng dụng thường gắn với môi trường đã bị sửa đổi, dựa trên bundle identifier như com.opa334.TrollStore, org.coolstar.SileoStore, com.tigisoftware.Filza và nhiều ứng dụng khác. Nếu phát hiện bất kỳ ứng dụng nào trong số này, ứng dụng ngân hàng sẽ coi thiết bị là không đáng tin cậy và từ chối tiếp tục.

EN | This specific behavior was later addressed by Apple in iOS 18.5 (CVE-2025-31207), but the pattern is still relevant. KO | 이 특정 동작은 이후 iOS 18.5(CVE-2025-31207)에서 Apple에 의해 수정되었지만, 해당 패턴은 여전히 유효하다. VI | Hành vi cụ thể này sau đó đã được Apple xử lý trong iOS 18.5 (CVE-2025-31207), nhưng mẫu hình này vẫn còn giá trị tham khảo.

EN | Technique: Pre-execution environment checks / Query system APIs, including undocumented ones, for indirect signals / Use side-channel behavior such as API return logs to detect installed applications / Detect presence of known tools via bundle identifiers KO | 기법: 실행 전 환경 검사 / 비문서화 API 포함 시스템 API 쿼리를 통한 간접 신호 수집 / API 반환 로그 등 사이드 채널 동작으로 설치 앱 탐지 / 번들 식별자를 통한 알려진 툴 존재 여부 감지 VI | Kỹ thuật: Kiểm tra môi trường trước khi thực thi / Truy vấn các API hệ thống, kể cả API không có tài liệu, để thu thập tín hiệu gián tiếp / Sử dụng hành vi side-channel như log trả về của API để phát hiện ứng dụng đã cài / Phát hiện sự hiện diện của các công cụ đã biết thông qua bundle identifier


EN | 2. The App That Checked Itself KO | 2. 자기 자신을 검사한 앱 VI | 2. Ứng dụng tự kiểm tra bản thân

EN | Some apps go further and verify their own state before doing anything useful. KO | 일부 앱은 더 나아가 유용한 동작을 수행하기 전에 자신의 상태를 직접 검증한다. VI | Một số ứng dụng tiến xa hơn và xác minh trạng thái của chính mình trước khi thực hiện bất kỳ điều gì hữu ích.

EN | A common approach, especially in games, is to query code signing state using csops(). In particular, checking CS_OPS_ENTITLEMENTS_BLOB allows the app to retrieve its own entitlements. Unexpected entitlements can indicate a modified or non-standard environment. This gives the app another signal to decide whether it is running on a jailbroken device. KO | 특히 게임에서 흔히 볼 수 있는 방식은 csops()를 사용해 코드 서명 상태를 조회하는 것이다. 구체적으로 CS_OPS_ENTITLEMENTS_BLOB를 확인하면 앱이 자신의 entitlement를 가져올 수 있다. 예상치 못한 entitlement는 수정된 환경이나 비정상적인 환경을 나타낼 수 있다. 이는 앱이 탈옥 기기에서 실행 중인지 판단하는 추가 신호가 된다. VI | Một cách tiếp cận phổ biến, đặc biệt trong các trò chơi, là truy vấn trạng thái ký mã bằng csops(). Cụ thể, việc kiểm tra CS_OPS_ENTITLEMENTS_BLOB cho phép ứng dụng lấy lại các entitlement của chính mình. Các entitlement bất thường có thể cho thấy môi trường đã bị sửa đổi hoặc không chuẩn. Điều này cung cấp cho ứng dụng thêm một tín hiệu để quyết định xem nó có đang chạy trên thiết bị jailbreak hay không.

EN | Some apps also verify their own integrity before continuing. This includes computing hashes such as CRC32 or MD5 across application data and checking the signing certificate of the installed IPA. Structures like LC_ENCRYPTION_INFO_64 are used to detect whether the app has been re-signed or altered. KO | 일부 앱은 계속 실행하기 전에 자체 무결성도 검증한다. 여기에는 앱 데이터 전반에 걸쳐 CRC32 또는 MD5 해시를 계산하고, 설치된 IPA의 서명 인증서를 확인하는 작업이 포함된다. LC_ENCRYPTION_INFO_64와 같은 구조체는 앱이 재서명되거나 변조되었는지 탐지하는 데 사용된다. VI | Một số ứng dụng cũng xác minh tính toàn vẹn của bản thân trước khi tiếp tục. Điều này bao gồm tính toán hash như CRC32 hoặc MD5 trên dữ liệu ứng dụng và kiểm tra chứng chỉ ký của IPA đã cài đặt. Các cấu trúc như LC_ENCRYPTION_INFO_64 được sử dụng để phát hiện xem ứng dụng có bị ký lại hoặc bị thay đổi hay không.

EN | Technique: Pre-execution environment checks / Use csops() with CS_OPS_ENTITLEMENTS_BLOB to inspect entitlements and infer jailbreak state / Perform file integrity checks using CRC32 and MD5 / Validate signing certificates and detect re-signing via LC_ENCRYPTION_INFO64 KO | 기법: 실행 전 환경 검사 / CS_OPS_ENTITLEMENTS_BLOB와 함께 csops()를 사용하여 entitlement 검사 및 탈옥 상태 추론 / CRC32 및 MD5를 이용한 파일 무결성 검사 / 서명 인증서 검증 및 LC_ENCRYPTION_INFO64를 통한 재서명 탐지 VI | Kỹ thuật: Kiểm tra môi trường trước khi thực thi / Sử dụng csops() với CS_OPS_ENTITLEMENTS_BLOB để kiểm tra entitlement và suy luận trạng thái jailbreak / Thực hiện kiểm tra toàn vẹn file bằng CRC32 và MD5 / Xác thực chứng chỉ ký và phát hiện ký lại qua LC_ENCRYPTION_INFO64


EN | 3. The App That Killed Itself on Attach KO | 3. 디버거 연결 시 스스로 종료한 앱 VI | 3. Ứng dụng tự hủy khi bị attach

EN | Another pattern shows up once you try to attach a debugger: the app exits immediately. KO | 디버거를 연결하려 하면 또 다른 패턴이 나타난다: 앱이 즉시 종료되는 것이다. VI | Một mẫu hình khác xuất hiện ngay khi bạn cố gắng attach debugger: ứng dụng thoát ngay lập tức.

EN | In most cases, this comes down to ptrace() with PT_DENY_ATTACH. When that flag is set, any attempt to attach a debugger causes the process to terminate, usually through abort() or exit(). KO | 대부분의 경우 이는 PT_DENY_ATTACH 플래그를 사용한 ptrace() 호출로 귀결된다. 이 플래그가 설정되면 디버거 연결 시도 시 abort() 또는 exit()을 통해 프로세스가 종료된다. VI | Trong hầu hết các trường hợp, điều này đến từ ptrace() với PT_DENY_ATTACH. Khi cờ đó được đặt, bất kỳ nỗ lực attach debugger nào đều khiến tiến trình kết thúc, thường thông qua abort() hoặc exit().

EN | The usual way around this is to deal with the termination path rather than the detection. If the app cannot terminate itself, it continues running. Patching the execution flow to bypass calls to abort() and exit() is often enough to keep the process alive and allow runtime inspection. KO | 일반적인 우회 방법은 탐지 자체가 아닌 종료 경로를 처리하는 것이다. 앱이 스스로 종료할 수 없다면 계속 실행된다. abort()와 exit() 호출을 우회하도록 실행 흐름을 패치하는 것만으로도 프로세스를 살려두고 런타임 분석을 가능하게 하는 경우가 많다. VI | Cách thông thường để vượt qua điều này là xử lý đường dẫn kết thúc thay vì cơ chế phát hiện. Nếu ứng dụng không thể tự kết thúc, nó sẽ tiếp tục chạy. Việc vá luồng thực thi để bỏ qua các lời gọi abort() và exit() thường là đủ để giữ tiến trình sống và cho phép kiểm tra runtime.

EN | Technique: Runtime anti-debugging with ptrace() / Call ptrace(PT_DENY_ATTACH) to block debugger attachment / Trigger process termination when debugging is detected KO | 기법: ptrace()를 이용한 런타임 디버깅 방지 / ptrace(PT_DENY_ATTACH) 호출로 디버거 연결 차단 / 디버깅 감지 시 프로세스 강제 종료 VI | Kỹ thuật: Chống debug runtime với ptrace() / Gọi ptrace(PT_DENY_ATTACH) để chặn việc attach debugger / Kích hoạt kết thúc tiến trình khi phát hiện debugging


EN | 4. The App That Ruined Its Own Crash Logs KO | 4. 자신의 크래시 로그를 망가뜨린 앱 VI | 4. Ứng dụng tự phá hủy crash log của mình

EN | Some apps do not just exit. They also make sure you cannot learn anything from the crash. KO | 어떤 앱은 그냥 종료하는 데서 그치지 않는다. 크래시에서 아무것도 알아낼 수 없도록 조치하기도 한다. VI | Một số ứng dụng không chỉ đơn giản là thoát. Chúng còn đảm bảo bạn không thể học được gì từ crash đó.

EN | We ran into one that behaved normally until you tried to debug it. Then the crash logs stopped being useful. Registers were filled with the same, impossible value, and the backtrace did not point to anything meaningful. KO | 우리는 디버깅을 시도하기 전까지는 정상적으로 동작하다가, 이후 크래시 로그가 전혀 쓸모없어진 앱을 만났다. 레지스터는 동일한 이상한 값으로 채워져 있었고, 백트레이스는 의미 있는 어떤 것도 가리키지 않았다. VI | Chúng tôi gặp một ứng dụng hoạt động bình thường cho đến khi bạn cố debug nó. Sau đó crash log trở nên vô dụng. Các register bị lấp đầy bởi cùng một giá trị bất thường, và backtrace không trỏ đến bất kỳ điều gì có ý nghĩa.

EN | Looking closer, the app was writing garbage into the CPU registers before crashing. In one case, every register was set to a constant like 0x123456789a00. The crash still happened, but the state was no longer trustworthy, so there was nothing useful to extract from it. KO | 자세히 살펴보니, 앱은 크래시 전에 CPU 레지스터에 쓰레기 값을 기록하고 있었다. 한 경우에는 모든 레지스터가 0x123456789a00 같은 상수로 설정되어 있었다. 크래시는 여전히 발생했지만, 상태 자체가 더 이상 신뢰할 수 없었기 때문에 거기서 유용한 정보를 추출할 수 없었다. VI | Nhìn kỹ hơn, ứng dụng đang ghi giá trị rác vào các CPU register trước khi crash. Trong một trường hợp, mọi register đều được đặt thành một hằng số như 0x123456789a00. Crash vẫn xảy ra, nhưng trạng thái không còn đáng tin cậy, vì vậy không có gì hữu ích để trích xuất từ đó.

EN | This makes it difficult to trace where the detection actually occurred. Even if you hit the right code path, the information you get back is already corrupted. KO | 이로 인해 탐지가 실제로 어디서 발생했는지 추적하기가 어려워진다. 올바른 코드 경로에 도달하더라도 돌아오는 정보는 이미 오염되어 있다. VI | Điều này khiến việc truy vết nơi phát hiện thực sự xảy ra trở nên khó khăn. Ngay cả khi bạn đến đúng code path, thông tin bạn nhận lại đã bị hỏng.

EN | It does not prevent debugging entirely, but it slows things down. You have to find the check before the crash instead of relying on the crash itself. KO | 이 기법이 디버깅을 완전히 막지는 않지만, 속도를 크게 늦춘다. 크래시 자체에 의존하는 대신, 크래시 이전에 검사 지점을 직접 찾아야 한다. VI | Nó không ngăn chặn hoàn toàn việc debug, nhưng làm chậm mọi thứ lại. Bạn phải tìm ra điểm kiểm tra trước khi crash thay vì dựa vào chính crash đó.

EN | Technique: Register corruption for analysis resistance / Overwrite register state before crashing / Produce garbage register values in crash logs / Obscure the origin of detection logic and break backtraces KO | 기법: 분석 저항을 위한 레지스터 오염 / 크래시 전 레지스터 상태 덮어쓰기 / 크래시 로그에 쓰레기 레지스터 값 생성 / 탐지 로직의 출처 은폐 및 백트레이스 파괴 VI | Kỹ thuật: Làm hỏng register để chống phân tích / Ghi đè trạng thái register trước khi crash / Tạo ra giá trị register rác trong crash log / Che giấu nguồn gốc logic phát hiện và phá vỡ backtrace


EN | 5. The App That Let iOS Do the Killing KO | 5. iOS에게 종료를 맡긴 앱 VI | 5. Ứng dụng nhờ iOS tự ra tay

EN | One game app produced probably the weirdest "crash" we have dealt with. The app would run, and as soon as we tried to debug it, it would get terminated without leaving any crash logs. KO | 한 게임 앱은 아마도 우리가 다뤄본 것 중 가장 이상한 "크래시"를 만들어냈다. 앱은 실행되다가 디버깅을 시도하는 순간 크래시 로그를 전혀 남기지 않고 종료되었다. VI | Một ứng dụng game tạo ra crash kỳ lạ nhất mà chúng tôi từng xử lý. Ứng dụng đang chạy, và ngay khi chúng tôi cố debug nó, nó bị kết thúc mà không để lại bất kỳ crash log nào.

EN | The reason was memory pressure. Instead of crashing directly through abort() or access violations, the app pushed memory usage high enough to trigger a jetsam condition. On iOS, jetsam is a kernel mechanism that kills processes when the system is under memory pressure or when an app exceeds its memory limits. KO | 이유는 메모리 압박이었다. abort()나 접근 위반으로 직접 크래시를 내는 대신, 앱은 메모리 사용량을 jetsam 조건을 유발할 만큼 높였다. iOS에서 jetsam은 시스템이 메모리 압박을 받거나 앱이 메모리 한도를 초과할 때 프로세스를 강제 종료하는 커널 메커니즘이다. VI | Lý do là áp lực bộ nhớ. Thay vì crash trực tiếp qua abort() hoặc access violation, ứng dụng đẩy mức sử dụng bộ nhớ lên đủ cao để kích hoạt điều kiện jetsam. Trên iOS, jetsam là cơ chế kernel giết tiến trình khi hệ thống chịu áp lực bộ nhớ hoặc khi ứng dụng vượt quá giới hạn bộ nhớ của mình.

EN | Because the system performs the termination, there is no normal crash log. You only get a jetsam record, and the anti-debug detection logic does not show up in any backtrace. KO | 시스템이 종료를 수행하기 때문에 일반적인 크래시 로그가 없다. jetsam 기록만 남을 뿐, 어떤 백트레이스에도 안티디버그 탐지 로직은 나타나지 않는다. VI | Vì hệ thống thực hiện việc kết thúc, không có crash log thông thường. Bạn chỉ nhận được một bản ghi jetsam, và logic phát hiện anti-debug không xuất hiện trong bất kỳ backtrace nào.

EN | Technique: Resource exhaustion to trigger jetsam / Allocate excessive memory to force OS-level termination / Avoid generating application crash logs / Leave only system-level jetsam records KO | 기법: jetsam 유발을 위한 리소스 고갈 / 과도한 메모리 할당으로 OS 수준 강제 종료 유도 / 앱 크래시 로그 생성 방지 / 시스템 수준 jetsam 기록만 남김 VI | Kỹ thuật: Làm cạn kiệt tài nguyên để kích hoạt jetsam / Cấp phát bộ nhớ quá mức để buộc hệ điều hành kết thúc tiến trình / Tránh tạo ra crash log của ứng dụng / Chỉ để lại bản ghi jetsam ở cấp hệ thống


EN | 6. The App That Kept Checking KO | 6. 계속해서 검사한 앱 VI | 6. Ứng dụng không ngừng kiểm tra

EN | Some apps pass the initial checks but still fail later. KO | 일부 앱은 초기 검사를 통과하지만 이후에도 여전히 실패한다. VI | Một số ứng dụng vượt qua được các kiểm tra ban đầu nhưng vẫn thất bại về sau.

EN | In these cases, detection continues in the background and is enforced with delay. When a check fails, the app may record the state and only terminate after a timer elapses. That delay makes it harder to link the crash to the original trigger. KO | 이런 경우 탐지는 백그라운드에서 계속되며 지연을 두고 시행된다. 검사가 실패하면 앱은 상태를 기록해 두고, 타이머가 경과한 후에야 종료될 수 있다. 이 지연으로 인해 크래시와 원래 트리거를 연결하기가 더 어려워진다. VI | Trong những trường hợp này, việc phát hiện tiếp tục ở nền và được thực thi có độ trễ. Khi một kiểm tra thất bại, ứng dụng có thể ghi lại trạng thái và chỉ kết thúc sau khi hết thời gian đếm ngược. Độ trễ đó khiến việc liên kết crash với tác nhân ban đầu trở nên khó khăn hơn.

EN | There is often a periodic task acting as a heartbeat. It wakes up at fixed intervals and re-runs parts of the detection logic, so passing checks once does not mean you are in the clear. KO | 주기적인 작업이 하트비트처럼 작동하는 경우가 많다. 일정 간격으로 깨어나 탐지 로직의 일부를 다시 실행하므로, 한 번 검사를 통과했다고 해서 안심할 수 없다. VI | Thường có một tác vụ định kỳ hoạt động như một heartbeat. Nó thức dậy theo các khoảng thời gian cố định và chạy lại các phần của logic phát hiện, vì vậy vượt qua kiểm tra một lần không có nghĩa là bạn đã an toàn.

EN | Technique: Continuous detection with delayed enforcement / Record tamper state and trigger crashes after a delay / Use timers to decouple detection from enforcement / Run periodic heartbeat tasks to re-check state / Re-trigger enforcement even after initial checks pass KO | 기법: 지연 시행을 동반한 지속적 탐지 / 변조 상태 기록 후 지연을 두고 크래시 유발 / 타이머를 이용해 탐지와 시행을 분리 / 주기적 하트비트 태스크를 통한 상태 재검사 / 초기 검사 통과 후에도 시행 재발동 VI | Kỹ thuật: Phát hiện liên tục với thực thi có độ trễ / Ghi lại trạng thái giả mạo và kích hoạt crash sau một khoảng trễ / Sử dụng timer để tách rời việc phát hiện khỏi thực thi / Chạy các tác vụ heartbeat định kỳ để kiểm tra lại trạng thái / Kích hoạt lại thực thi ngay cả sau khi các kiểm tra ban đầu đã qua


EN | Conclusion KO | 결론 VI | Kết luận

EN | Taken together, these examples show how things have changed. What used to be a single check or a simple ptrace() call is now a combination of techniques. Environment checks happen early, debugger detection is enforced at runtime, crash logs are made useless, and in some cases removed entirely through jetsam. On top of that, integrity checks and timed enforcement add another layer that keeps running after launch. KO | 이 사례들을 종합하면 상황이 어떻게 변화했는지 알 수 있다. 과거의 단일 검사나 단순한 ptrace() 호출은 이제 여러 기법의 조합으로 발전했다. 환경 검사는 초기에 이루어지고, 디버거 탐지는 런타임에 시행되며, 크래시 로그는 무용지물이 되고, 경우에 따라서는 jetsam을 통해 완전히 제거된다. 거기에 더해 무결성 검사와 타이머 기반 시행이 또 하나의 층을 형성하며 실행 후에도 계속 작동한다. VI | Nhìn tổng thể, những ví dụ này cho thấy mọi thứ đã thay đổi như thế nào. Thứ từng là một kiểm tra đơn lẻ hay một lời gọi ptrace() đơn giản giờ đây là sự kết hợp của nhiều kỹ thuật. Kiểm tra môi trường xảy ra sớm, phát hiện debugger được thực thi ở runtime, crash log bị vô hiệu hóa, và trong một số trường hợp bị loại bỏ hoàn toàn qua jetsam. Trên tất cả, các kiểm tra toàn vẹn và thực thi có hẹn giờ bổ sung thêm một lớp nữa tiếp tục chạy sau khi khởi động.

EN | None of these techniques are especially complex on their own. The difficulty comes from how they are combined. You are not dealing with one mechanism, but a system where each part covers gaps left by the others. KO | 이 기법들 중 어느 것도 그 자체로 특별히 복잡하지는 않다. 어려움은 그것들이 어떻게 결합되는가에서 온다. 하나의 메커니즘을 다루는 것이 아니라, 각 부분이 다른 부분이 남긴 빈틈을 메우는 하나의 시스템을 상대하는 것이다. VI | Không có kỹ thuật nào trong số này đặc biệt phức tạp khi đứng một mình. Sự khó khăn đến từ cách chúng được kết hợp. Bạn không đang đối phó với một cơ chế, mà là một hệ thống nơi mỗi phần bù đắp cho những khoảng trống mà các phần khác để lại.

EN | For readers who are familiar with protection systems on Windows (anti-cheat, anti-debug, anti-tampering, etc.), you may wonder why they don't use more aggressive techniques such as kernel level drivers and code injection. The answer is that iOS has a different security model and it does not allow kernel extensions or unsigned code execution. KO | Windows의 보호 시스템(안티치트, 안티디버그, 안티탬퍼링 등)에 익숙한 독자라면, 왜 커널 수준 드라이버나 코드 인젝션 같은 더 공격적인 기법을 사용하지 않는지 궁금할 것이다. 그 답은 iOS가 다른 보안 모델을 가지고 있으며, 커널 확장이나 서명되지 않은 코드 실행을 허용하지 않기 때문이다. VI | Đối với những độc giả quen thuộc với các hệ thống bảo vệ trên Windows (anti-cheat, anti-debug, anti-tampering, v.v.), bạn có thể thắc mắc tại sao họ không sử dụng các kỹ thuật mạnh hơn như driver cấp kernel và code injection. Câu trả lời là iOS có mô hình bảo mật khác và không cho phép kernel extension hay thực thi mã không được ký.


Post a Comment

0 Comments