Cycript

cycript

动态调试工具,在越狱设备上通过 MobileSubstrate 加载。通过 cycript -p pid 命令 hook 指定进程。

另外可以在自己的应用中继承 Cycript。详见官方文档

打印 UI 层级

UIApp.keyWindow.recursiveDescription().toString();

打印所有 ViewController

[[[UIWindow keyWindow] rootViewController] _printHierarchy].toString()

加载 Framworks

function loadFramework(fw) { 
   var h="/System/Library/",t="Frameworks/"+fw+".framework";
   [[NSBundle bundleWithPath:h+t] || [NSBundle bundleWithPath:h+"Private"+t] load];
}

输出对象的属性

// 方法1: 简单基本获取方法。
*controller(直接在对象前面加个*

// 方法2:方法一无法获取,就使用方法2
[i for (i in *UIApp)]

// 方法3:建议方法三,方法三能获取到更多
function tryPrintIvars(a){ var x={}; for(i in *a){ try{ x[i] = (*a)[i]; } catch(e){} } return x; }

获取所有方法:

function printMethods(className, isa) { 
    var count = new new Type("I");
    var classObj = (isa != undefined) ? objc_getClass(className)->isa :     
    objc_getClass(className); 
    var methods = class_copyMethodList(classObj, count); 
    var methodsArray = [];
    for(var i = 0; i < *count; i++) { 
        var method = methods[i]; 
        methodsArray.push({selector:method_getName(method),     
        implementation:method_getImplementation(method)});
    }
    free(methods); 
    return methodsArray;
}

获取当前控制器

function currentVC() {
    var app = [UIApplication sharedApplication]  
    var keyWindow = app.keyWindow  
    var rootController = keyWindow.rootViewController  
    var visibleController = rootController.visibleViewController  
    if (!visibleController){
       return rootController
    }
    return visibleController.childViewControllers[0]
}
var vc = currentVC()

获取沙盒路径

[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]

其它

官方文档
利用 Cycript 调试 iOS 应用(无需越狱)