Cycript高级技巧(转载)

转自 http://lsq.me/2014/01/12/cycript-tricks/ 自己留着看看的


引言

在分析iOS应用程序的时候,经常会用到Cycript这个工具。本文将介绍使用Cycript的一些基本命令和高级技巧。

打印Ivar值

很多时候输入*varName就可以:

cy# *controller

{isa:"PrefsRootController",_contentView:">",_navBar:...

cy#

然而有时候却不行:

cy# *UIApp

{message:"hasProperty callback returned true for a property that doesn't exist.",name:"ReferenceError"}

但是你可以这样:

cy# [i for (i in *UIApp)]

["isa","_delegate","_touchMap","_exclusiveTouchWindows","_event",...

为了取得尽可能多的ivar值,你可以用下面这个函数:

function tryPrintIvars(a){ var x={}; for(i in *a){ try{ x[i] = (*a)[i]; } catch(e){} } return x; }

用法是:

cy# *a

{message:"hasProperty callback returned true for a property that doesn't exist.",name:"ReferenceError"}

cy# tryPrintIvars(a)

{isa:"SBWaveView",_layer:"",_tapInfo:null,_gestureInfo:null,_gestureRecognizers:...

打印方法名

可以取得方法名的函数:

function printMethods(className) {

var count = new new Type("I");

var methods =      class_copyMethodList(objc_getClass(className), 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);

free(count);

return methodsArray;

}

可以这样用:

cy# printMethods("MailboxPrefsTableCell")

[{selector:@selector(layoutSubviews),implementation:0x302bf2e9},{selector:@selector(setCurrentMailbox:),implementation:0x302bee0d},...

cy#

你也可以只看isa的消息属性,例如用UIApp.keyWindow.rootViewController.isa.messages可以取得rootViewControllers的方法。

用正则表达式取方法名

function methodsMatching(cls, regexp) { return [[new Selector(m).type(cls), m] for (m in cls.messages) if (!regexp || regexp.test(m))]; }

用法:

cy# methodsMatching(NSRunLoop, /forKey:$/)

[["v20@0:4I8@12@16","didChange:valuesAtIndexes:forKey:"],["v20@0:4I8@12@16","willChange:valuesAtIndexes:forKey:"],["v16@0:4@8@12","setValue:forKey:"]]

从地址获取Objective-C对象

用new Instance(0xdeadbabe):

cy# var p = new Instance(0x8614390)

cy# p

[""]

载入框架

function loadFramework(fw) {

var h="/System/Library/",t="Frameworks/"+fw+".framework";

[[NSBundle bundleWithPath:h+t]||[NSBundle bundleWithPath:h+"Private"+t] load];

}

替换Objective-C方法

你可以通过替换messages数组的内容来模拟MSHookMessage:

cy# original_NSRunLoop_description = NSRunLoop.messages['description'];

0x339d94c3

cy# NSRunLoop.messages['description'] = function() { return original_NSRunLoop_description.call(this).toString().substr(0, 80)+", etc."; }

{}

cy# [NSRunLoop currentRunLoop]

"{locked = false, wait port = 0x1303, stopped = , etc."

注意func.call(this)的结构,就是它把原函数的this绑定到用户指定的那个去了。如果需要更多地参数,用function(arg1, arg2, arg3, ...) {...func.call(self, arg1, arg2, arg3, ...);}来代替,例如:

cy# original_SpringBoard_menuButtonDown = SpringBoard.messages['menuButtonDown:']

0x17dbab1

cy# SpringBoard.messages['menuButtonDown:'] = function(arg1) {original_SpringBoard_menuButtonDown.call(this, arg1);}

function (e) {var e;var $cy0=this;original_SpringBoard_menuButtonDown.call($cy0,e);}

注意参数不会被自动映射到相对应的Objective-C类型,所以参数应该用[NSString stringWithString:"foo"]而不是简单的"foo"。

获取类方法

class.messages只包含实例方法。要hook类方法,你需要得到他的metaclass,一个简单地方法是:

cy# NSRunLoop->isa.messages['currentRunLoop'] = ...

引入其他Cycript文件

从0.9.274-1开始,取消了导入native文件的组件。当Cycript需要hook到其他进程时,既然数据都保留在那儿,你可以首先加载那个.cy文件:

localhost:~ mobile$ cycript -p SpringBoard main.cy

0x12345678

localhost:~ mobile$ cycript -p SpringBoard

cy# ...

如果Cycript是独立启动的,使用Cycript编译器和Javascript的eval表达式相结合也可以使引入作伪:

// include other .cy files

function include(fn) {

var t = [new NSTask init]; [t setLaunchPath:@"/usr/bin/cycript"]; [t setArguments:["-c", fn]];

var p = [NSPipe pipe]; [t setStandardOutput:p]; [t launch]; [t waitUntilExit];

var s = [new NSString initWithData:[[p fileHandleForReading] readDataToEndOfFile] encoding:4];

return this.eval(s.toString());

}

使用NSLog

在控制台输入:

NSLog_ = dlsym(RTLD_DEFAULT, "NSLog")

NSLog = function() { var types = 'v', args = [], count = arguments.length; for (var i = 0; i != count; ++i) { types += '@'; args.push(arguments[i]); } new Functor(NSLog_, types).apply(null, args); }

然后就可以像平常一样使用NSLog:

cy# NSLog_ = dlsym(RTLD_DEFAULT, "NSLog")

0x31451329

cy# NSLog = function() { var types = 'v', args = [], count = arguments.length; for (var i = 0; i != count; ++i) { types += '@'; args.push(arguments[i]); } new Functor(NSLog_, types).apply(null, args); }

{}

cy# NSLog("w ivars: %@", tryPrintIvars(w))

如果已经attach到一个进程了,输出就已经写到syslog了:

Nov 17 20:26:01 iPhone3GS Foobar[551]: w ivars: {\n    contentView =

使用CGGeometry功能

为了使用CGGeometry类的函数,必须要在Cycript窗体输入:

function CGPointMake(x, y) { return {x:x, y:y}; }

function CGSizeMake(w, h) { return {width:w, height:h}; }

function CGRectMake(x, y, w, h) { return    {origin:CGPointMake(x,y), size:CGSizeMake(w, h)}; }

将Cycript输出写入文件

Cycript的输出时NSString,所以调用writeToFile然后把它保存起来时可能的,例如:

[[someObject someFunction] writeToFile:"/var/mobile/cycriptoutput.txt" atomically:NO encoding:4 error:NULL]

你可以这么用,下面是获取SpringBoard view的结构的示例:

iPhone:~$ cycript -p SpringBoard

cy# [[UIApp->_uiController.window recursiveDescription] writeToFile:"/var/mobile/viewdump.txt" atomically:NO encoding:4 error:NULL]

打印View的继承关系

iPhone:~$ cycript -p SpringBoard

cy# ?expand

expand == true

cy# UIApp.keyWindow.recursiveDescription

">

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>"

?expand命令使换行显示的更加正常,而不仅仅是\n。

参考文献

Cycript Tricks

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,678评论 0 9
  • 工具 class-dump 用来提取已经砸过壳的 app 的头文件 下载地址 http://stevenygard...
    辉g_9274阅读 2,571评论 1 7
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,050评论 1 10
  • 今天去马达单位咯 是惊喜的午餐约饭 然后愉快的下午电影时光 两个人一起的值班 真是什么工作的干不了 喝咖啡 吃哈密...
    ninvxv阅读 190评论 0 0
  • 我爱你 愿意变成一条狗 你总说你生活得像屎一样 而狗也改不了吃屎 我爱你 愿意变成夸父 你做我的太阳 追你海角天边...
    哥窑阅读 410评论 0 5