효투의 세상 로딩중...
효투의 세상 로딩중...
반응형

안드로이드 Frida Trace와 같이 ios에서도 스크립트를 이용하여 비슷한 기능이 있다.

2022.04.14 - [모바일/Android] - [Android] 안드로이드 apk 메소드 추적 프리다 트레이스 (Frida Trace)

 

[Android] 안드로이드 apk 메소드 추적 프리다 트레이스 (Frida Trace)

앱 진단 시 소스 코드를 분석함에 있어서 어디에서 어떤 클래스와 메소드가 실행되어 동작하는지 프리다 트레이스(Frida-Trace)를 이용하여 파악할 수 있는 방법이 있다. 루팅 탐지를 하는 앱에서

hyotwo.tistory.com

 

프리다 후킹글에서 받은 많은 스크립트들 중 raptor_frida_ios_trace는 추적 스크립트로 유명한 스크립트인데

 

아래 그림처럼 실제로 동작해보면 앱이 종료되거나 시작은 잡지만 제대로 마무리하지 못하거나 하는 오류가 있다.

 

그래서 핵캐트믈님이 수정하신 스크립트가 있는데 이거는 매우잘됨

https://hackcatml.tistory.com/50

 

Frida iOS Method Trace

잘 알려진 method trace 코드인 raptor_frida_ios_trace 를 다운받아서 실행해보면 가끔 에러가 발생하여 수정하였음. // generic trace function trace(pattern) { var type = (pattern.indexOf(" ") === -1) ? "..

hackcatml.tistory.com

 

사진을 보면 클래스 및 메소드는 당연히 포함 어디서부터 시작해서 리턴값이 무엇인지 까지 추적할 수 있다.

반응형

코드 하단에 추적하고싶은 클래스를 적고 실행하면된다.

// generic trace
function trace(pattern)
{
    var type = (pattern.indexOf(" ") === -1) ? "module" : "objc";    // [A B]와 같이 공백이 있으면 objc, 없으면 모듈  
    var res = new ApiResolver(type);
    var matches = res.enumerateMatchesSync(pattern);
    var targets = uniqBy(matches, JSON.stringify);

    targets.forEach(function(target) {
      if (type === "objc")
          traceObjC(target.address, target.name);
      else if (type === "module")
          traceModule(target.address, target.name);
  });
}

// remove duplicates from array
function uniqBy(array, key) 
{
    var seen = {};
    return array.filter(function(item) {
        var k = key(item);
        return seen.hasOwnProperty(k) ? false : (seen[k] = true);
    });
}

// trace ObjC methods
function traceObjC(impl, name)
{
    console.log("Tracing " + name);

    Interceptor.attach(impl, {

        onEnter: function(args) {

            // debug only the intended calls
            this.flag = 0;
            // if (ObjC.Object(args[2]).toString() === "1234567890abcdef1234567890abcdef12345678")
                this.flag = 1;

            if (this.flag) {
                console.warn("\n[+] entered " + name);
                // print caller
                console.log("\x1b[31mCaller:\x1b[0m \x1b[34m" + DebugSymbol.fromAddress(this.returnAddress) + "\x1b[0m\n");

                // print args
                console.log("\x1b[31margs[2]:\x1b[0m \x1b[34m" + args[2] + ", \x1b[32m" + ObjC.Object(args[2]) + "\x1b[0m")
                console.log("\x1b[31margs[3]:\x1b[0m \x1b[34m" + args[3] + ", \x1b[32m" + ObjC.Object(args[3]) + "\x1b[0m")
                // console.log("\x1b[31margs[4]:\x1b[0m \x1b[34m" + args[4] + ", \x1b[32m" + ObjC.Object(args[4]) + "\x1b[0m")
                
                // print full backtrace
                // console.log("\nBacktrace:\n" + Thread.backtrace(this.context, Backtracer.ACCURATE)
                //      .map(DebugSymbol.fromAddress).join("\n"));
            }
        },

        onLeave: function(retval) {

            if (this.flag) {
                // print retval
                console.log("\n\x1b[31mretval:\x1b[0m \x1b[34m" + retval + "\x1b[0m");
                console.warn("[-] exiting " + name);
            }
        }

    });
}

// trace Module functions
function traceModule(impl, name)
{
    console.log("Tracing " + name);

    Interceptor.attach(impl, {

        onEnter: function(args) {

            // debug only the intended calls
            this.flag = 0;
            // var filename = Memory.readCString(ptr(args[0]));
            // if (filename.indexOf("Bundle") === -1 && filename.indexOf("Cache") === -1) // exclusion list
            // if (filename.indexOf("my.interesting.file") !== -1) // inclusion list
                this.flag = 1;

            if (this.flag) {
                console.warn("\n*** entered " + name);

                // print backtrace
                console.log("\nBacktrace:\n" + Thread.backtrace(this.context, Backtracer.ACCURATE)
                        .map(DebugSymbol.fromAddress).join("\n"));
            }
        },

        onLeave: function(retval) {

            if (this.flag) {
                // print retval
                console.log("\nretval: " + retval);
                console.warn("\n*** exiting " + name);
            }
        }

    });
}

// usage examples. 관심있는 클래스를 명시. 대소문자 구분
if (ObjC.available) {
    trace("*[JailbreakDetection *]")
    // trace("*[FireflySecurityUtil *]")
    // trace("*[ *ncrypt*]");
    // trace("*[* *]"); 모든 클래스 추적. 앱이 다운됨
    // trace("exports:libSystem.B.dylib!CCCrypt");
    // trace("exports:libSystem.B.dylib!open");
    // trace("exports:*!open*");
    
} else {
    send("error: Objective-C Runtime is not available!");
}

 

반응형
  • hyotwo7658@gmail.com

복사 완료 👍