Objection

설치

pip install objection

사용방법

objection -g [app name] explore
ios jailbreak disable
ios hooking watch method "[후킹 메소드]" --dump-return
ios hooking set return_value "[메소드]" 0x0
file download <FILENAME> : iOS > PC 파일 다운받기
file upload <local_file_path> : PC > iOS 파일 업로드

frida-trace

사용방법

open을 사용하는 클래스 추출

frida-trace -U -f [PACKAGE_NAME] -i “open*”

 init으로 시작하는 클래스 추출

frida-trace -U -i “init*” [PID]

 

Class 내 모든 Method 추출

function hook_class_method(class_name, method_name)
{
	var hook = ObjC.classes[class_name][method_name];
		Interceptor.attach(hook.implementation, {
			onEnter: function(args) {
			console.log("[*] Detected call to: " + class_name + " -> " + method_name);
		}
	});
}

function run_hook_all_methods_of_specific_class(className_arg)
{
	console.log("[*] Started: Hook all methods of a specific class");
	console.log("[+] Class Name: " + className_arg);
	//Your class name here
	var className = className_arg;
	//var methods = ObjC.classes[className].$methods;
	var methods = ObjC.classes[className].$ownMethods;
	for (var i = 0; i < methods.length; i++)
	{
		console.log("[-] "+methods[i]);
		console.log("\t[*] Hooking into implementation");
		//eval('var className2 = "'+className+'"; var funcName2 = "'+methods[i]+'"; var hook = eval(\'ObjC.classes.\'+className2+\'["\'+funcName2+\'"]\'); Interceptor.attach(hook.implementation, {   onEnter: function(args) {    console.log("[*] Detected call to: " + className2 + " -> " + funcName2);  } });');
		var className2 = className;
		var funcName2 = methods[i];
		hook_class_method(className2, funcName2);
		console.log("\t[*] Hooking successful");
	}
	console.log("[*] Completed: Hook all methods of a specific class");
}

function hook_all_methods_of_specific_class(className_arg)
{
	setImmediate(run_hook_all_methods_of_specific_class,[className_arg])
}

//Your class name goes here
hook_all_methods_of_specific_class("추출한 Class Name")

Method trace 스크립트 by hackcatml

// 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!");
}

 

UI Dump by hackcatml

var window = ObjC.classes.UIWindow.keyWindow();
var rootControl = window.rootViewController();

var ui = window.recursiveDescription().toString();
var ui_autolayout = window['- _autolayoutTrace']().toString();
var control = rootControl['- _printHierarchy']().toString();

// 전체 UI 계층 출력하고 싶은 경우    
// console.log("\n\x1b[31m" + ui + "\x1b[0m"); 

// Simplified recursiveDescription
// console.log("\n\x1b[34m" + ui_autolayout + "\x1b[0m");

// 현재 화면에 보여지는 UIController를 알고 싶은 경우
console.log("\n\x1b[32m" + control + "\x1b[0m");

 

'APP 모의해킹 > Setting' 카테고리의 다른 글

Burp Fiddler 연동  (0) 2023.07.10
TCP Proxy  (0) 2023.04.04
IDA Setting  (0) 2023.04.03
Anaconda Setting for virtual environment + frida  (0) 2023.03.23
pip 인증서 문제  (0) 2023.03.22

+ Recent posts