MDCycript/MS.cy
git 地址:https://github.com/AloneMonkey/MDCycript/blob/master/MS.cy
(function(ms) {
// 获取存储 libcycript.dylib 的目录的路径
let GetLibraryPath = function() {
let handle = dlopen(NULL, RTLD_NOLOAD);
if (handle == null)
return null;
try {
let CYListenServer = dlsym(handle, "CYListenServer");
if (CYListenServer == null)
return null;
let info = new Dl_info;
if (dladdr(CYListenServer, info) == 0)
return null;
let path = info->dli_fname;
let slash = path.lastIndexOf('/');
if (slash == -1)
return null;
path = path.substr(0, slash);
GetLibraryPath = function() {
return path;
};
return GetLibraryPath();
} finally {
dlclose(handle);
}
};
// 安全性判断: libcycript.dylib 必须存在
var libcycript = dlopen(GetLibraryPath() + "/libcycript.dylib", RTLD_NOLOAD);
if (libcycript == null) {
return;
}
// 安全性判断: libsubstrate.dylib 必须存在
var libsubstrate = dlopen(GetLibraryPath() + "/libsubstrate.dylib", RTLD_GLOBAL | RTLD_LAZY);
if (libsubstrate == null) {
return;
}
// 导入 libsubstrate.dylib 中的 C 函数
extern "C" void* MSGetImageByName(const char *);
extern "C" void* MSFindSymbol(void *, const char *);
extern "C" void MSHookFunction(void *, void *, void **);
extern "C" void MSHookMessageEx(Class, SEL, void *, void **);
var slice = Array.prototype.slice;
// 用于封装 Cydia Substrate 的 MSHookFunction 函数
// @param.func 原始函数
// @param.hook 替换函数
// @param.old 用于保存原始实现
ms.HookFunction = function(func, hook, old) {
var type = typeid(func);
var pointer;
if (old == null || typeof old === "undefined")
pointer = null;
else {
pointer = new (typedef void **);
*old = function() {
return type(*pointer).apply(null, arguments); };
}
MSHookFunction(func.valueOf(), type(hook), pointer);
};
// 用于封装 Cydia Substrate 的 MSHookMessageEx 函数
// @param.isa 要 hook 的 OC 类
// @param.sel 要 hook 的方法的名称
// @param.imp 替换实现
// @param.old 用于保存原始实现
ms.HookMessage = function(isa, sel, imp, old) {
var type = sel.type(isa);
var pointer;
if (old == null || typeof old === "undefined")
pointer = null;
else {
pointer = new (typedef void **);
*old = function() {
return type(*pointer).apply(null, [this, sel].concat(slice.call(arguments))); };
}
MSHookMessageEx(isa, sel, type(function(self, sel) {
return imp.apply(self, slice.call(arguments, 2)); }), pointer);
};
// 将当前脚本的 ms 中定义的函数暴露给 Cycript 的全局作用域
for (var k in ms) {
if(ms.hasOwnProperty(k)) {
var f = ms[k];
if(typeof f === 'function') {
Cycript.all[k] = f;
}
}
}
})(exports);
MDCycript/md.cy
git 地址:https://github.com/AloneMonkey/MDCycript/blob/master/md.cy
(function(utils) {
utils.constants = {
APPID: NSBundle.mainBundle.bundleIdentifier, // 当前 App 的 BundleID
APPPATH: NSBundle.mainBundle.bundlePath, // 当前 App 的工程主目录
APPHOME: NSHomeDirectory(), // 当前 App 的沙盒主目录
APPDOC: NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0], // 当前 App 的沙盒目录(Documents)
APPLIBRARY: NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0], // 当前 App 的沙盒目录(Library)
APPCACHE: NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0] // 当前 App 的沙盒目录(Caches)
};
// 打印当前 App 主窗口(keyWindow)的视图层级的递归描述
utils.pviews = function() {
return UIApp.keyWindow.recursiveDescription().toString();
};
// 打印当前 App 主窗口(keyWindow)的控制器层级的递归描述
utils.pvcs = function() {
return UIWindow.keyWindow().rootViewController._printHierarchy().toString();
};
// 打印从指定的响应者(target)开始的响应者链条
// @param.target 因为 nextResponder 方法位于 UIResponder 中
// 所以 target 必须是继承自 UIResponder 的类
// 即,target 可以是 UIApplication、UIViewController、UIWindow、UIView、等等
utils.rp = function(target) {
var result = "" + target.toString();
while(target.nextResponder){
result += "\n" + target.nextResponder.toString();
target = target.nextResponder;
}
return result;
};
// 打印指定的控件(target)的所有 Target 和 Action
// @param.target 因为 allTargets 方法位于 UIControl 中
// 所以 target 必须是继承自 UIControl 的类
// 即,target 可以是 UIButton、UITextField、等等
utils.pactions = function(target) {
var result = '';
var objs = target.allTargets.allObjects();
for(var i = 0; i < objs.length; i++){
var actions = [target actionsForTarget:objs[i] forControlEvent:0];
result += objs[i] + " " + [actions componentsJoinedByString:@","];
}
return result;
}
// 将当前脚本的 utils 中定义的常量暴露给 Cycript 的全局作用域
for (var k in utils.constants) {
Cycript.all[k] = utils.constants[k];
}
// 将当前脚本的 utils 中定义的函数暴露给 Cycript 的全局作用域
for (var k in utils) {
if(utils.hasOwnProperty(k)) {
var f = utils[k];
if(typeof f === 'function') {
Cycript.all[k] = f;
}
}
}
})(exports);
mjcript/mjcript.cy
git 地址:https://github.com/CoderMJLee/mjcript/blob/master/mjcript.cy
(function(exports) {
var invalidParamStr = 'Invalid parameter';
var missingParamStr = 'Missing parameter';
// 当前 App 的 BundleID
MJAppId = [NSBundle mainBundle].bundleIdentifier;
// 当前 App 的工程主目录
MJAppPath = [NSBundle mainBundle].bundlePath;
// 当前 App 的沙盒目录(Documents)
MJDocPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// 当前 App 的沙盒目录(Caches)
MJCachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
// 加载系统动态库
// @param.name 动态库的名称,例如: UIKit、Foundation、等等
MJLoadFramework = function(name) {
var head = "/System/Library/";
var foot = "Frameworks/" + name + ".framework";
var bundle = [NSBundle bundleWithPath:head + foot] || [NSBundle bundleWithPath:head + "Private" + foot];
[bundle load];
return bundle;
};
// 当前 App 的主窗口
MJKeyWin = function() {
return UIApp.keyWindow;
};
// 当前 App 的主窗口的根控制器
MJRootVc = function() {
return UIApp.keyWindow.rootViewController;
};
var _MJFrontVc = function(vc) {
if (vc.presentedViewController) {
return _MJFrontVc(vc.presentedViewController);
} else if ([vc isKindOfClass:[UITabBarController class]]) {
return _MJFrontVc(vc.selectedViewController);
} else if ([vc isKindOfClass:[UINavigationController class]]) {
return _MJFrontVc(vc.visibleViewController);
} else {
var count = vc.childViewControllers.count;
for (var i = count - 1; i >= 0; i--) {
var childVc = vc.childViewControllers[i];
if (childVc && childVc.view.window) {
vc = _MJFrontVc(childVc);
break;
}
}
return vc;
}
};
// 找到当前 App 的主窗口中显示在最前面的控制器
MJFrontVc = function() {
return _MJFrontVc(UIApp.keyWindow.rootViewController);
};
// 递归打印指定的控制器 vc 的视图的层级结构
MJVcSubviews = function(vc) {
if (![vc isKindOfClass:[UIViewController class]]) throw new Error(invalidParamStr);
return vc.view.recursiveDescription().toString();
};
// 递归打印当前 App 的主窗口中显示在最前面的控制器的视图的层级结构
MJFrontVcSubViews = function() {
return MJVcSubviews(_MJFrontVc(UIApp.keyWindow.rootViewController));
};
// 获取指定的按钮 btn 绑定的所有 TouchUpInside 事件的方法名
MJBtnTouchUpEvent = function(btn) {
var events = [];
var allTargets = btn.allTargets().allObjects()
var count = allTargets.count;
for (var i = count - 1; i >= 0; i--) {
if (btn != allTargets[i]) {
var e = [btn actionsForTarget:allTargets[i] forControlEvent:UIControlEventTouchUpInside];
events.push(e);
}
}
return events;
};
// 封装 CGPointMake 函数
MJPointMake = function(x, y) {
return {
0 : x, 1 : y};
};
// 封装 CGSizeMake 函数
MJSizeMake = function(w, h) {
return {
0 : w, 1 : h};
};
// 封装 CGRectMake 函数
MJRectMake = function(x, y, w, h) {
return {
0 : MJPointMake(x, y), 1 : MJSizeMake(w, h)};
};
// 递归打印指定的控制器 vc 的层级结构
MJChildVcs = function(vc) {
if (![vc isKindOfClass:[UIViewController class]]) throw new Error(invalidParamStr);
return [vc _printHierarchy].toString();
};
// 递归打印指定的视图 view 的层级结构
MJSubviews = function(view) {
if (![view isKindOfClass:[UIView class]]) throw new Error(invalidParamStr)

本文探讨了MDCycript、MD.cy、mjcript.cy、libcycript.cy、cycript-utils/utils.cy等脚本库,介绍了如何利用它们在iOS和JavaScript环境中进行安全性和功能扩展,如Hook函数、操作Objective-C对象、访问系统资源等。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



