入门学习逆向的个人笔记,预览(欢迎探讨)
[原创][calleng的逆向日记] 22y11m-23y3m29d 实现macOS编辑, iOS端编译和调试C/C++
[原创] [calleng的逆向日记] 23/03/30 (C++概念构建篇01) 补充完毕
[分享][calleng的逆向日记] 22y11m-23y6m7d Win10Arm下的 gdb调试.[数据结构/严蔚敏-之迷宫问题]
[分享] IOS软件安全工程师技能表(2017.7by非虫) (为自己学习导航) 图片不清楚下面有导图下载
[分享] Frida-Tool的一些 介绍, 和在 iOS下的一些用法 [个人笔记汇总]
[原创] [calleng的逆向日记] 弹窗的修改原理-OC篇 [源码学习和HOOK实践]23/09/24 --待续
[讨论] [calleng的逆向日记] 自学iOS逆向时候,如何自己解决问题.
[分享] [calleng逆向日记] iOS crackMe的破解 与 Frida(Objection) 的入门使用(thanks to roysue)
[分享] (iOS Hook原理,OC底层实现)Frida前置知识的(royuse)的一些知识注解(图片三次压缩失真,详情见附件)
[原创] (calleng逆向日记)Frida前置知识, ObjC runtime的"反射"-KVC-实例代码理解和分析
[分享] [calleng的逆向日记] Frida 前置知识, 类与方法的底层实现, 逻辑批注, (参考AloneMonkey的书)
[原创] (calleng逆向日记)Frida前置知识, ObjC runtime的"反射" KVC实例Demo分析第二部(Demo底部下载)
[分享] [calleng的逆向日记] iOS crackMe and Frida(Objection) Get Started (Oct,16th)
[分享] [calleng的逆向日记] Frida在iOS上内存漫游与黑盒调用 Get Started Section 4
学到的内容
- iOS hooking search 源码解析
- ApiResolver搜刮内存中的所有符号
- 枚举搜索所有类/所有方法/所有重载
- hook所有类/所有方法/所有重载
- 输出(修改)解析参数/调用栈/返回值
ios hooking search classes ViewController // search classes name which have .
ios hooking list class_methods ViewController // search all ViewController's method
ios hooking search methods buttonClick:
ios hooking search methods "- buttonClick:"
ios hooking search methods "buttonClick"
ios hooking search methods "[- buttonClick:]"
git clone https://github.com/sensepost/objection.git
code objection
"new ApiResolver(type): create a new resolver of the given type, allowing you to quickly find functions by name, with globs permitted."
(新建ApiResolver(type):创建一个给定类型的新解析器,允许您通过名称快速查找函数,支持通配符。)
"Precisely which resolvers are available depends on the current platform and runtimes loaded in the current process."
(可用的解析器取决于当前平台和当前进程中加载的运行时。)
"As of the time of writing, the available resolvers are:"
(截止到写作时,可用的解析器如下:)
"module: Resolves exported and imported functions of shared libraries currently loaded. Always available."
(module: 解析当前加载的共享库的导出和导入函数。始终可用。)
"objc: Resolves Objective-C methods of classes currently loaded. Available on macOS and iOS in processes that have the Objective-C runtime loaded. Use ObjC.available to check at runtime, or wrap your new ApiResolver('objc') call in a try-catch."
(objc: 解析当前加载的类的Objective-C方法。在具有加载了Objective-C运行时的macOS和iOS进程中可用。在运行时使用ObjC.available进行检查,或将您的new ApiResolver('objc')调用包装在try-catch中。)
"The resolver will load the minimum amount of data required on creation, and lazy-load the rest depending on the queries it receives. It is thus recommended to use the same instance for a batch of queries, but recreate it for future batches to avoid looking at stale data."
(解析器在创建时将加载所需的最少数据,并根据收到的查询进行延迟加载其余数据。因此,建议对一批查询使用相同的实例,但对未来的批次重新创建实例,以避免查看过期数据。)
"ObjC.available: a boolean specifying whether the current process has an Objective-C runtime loaded. Do not invoke any other ObjC properties or methods unless this is the case."
(ObjC.available:一个布尔值,指示当前进程是否已加载Objective-C运行时。除非是这种情况,否则不要调用任何其他ObjC属性或方法。)
"ObjC.api: an object mapping function names to NativeFunction instances for direct access to a big portion of the Objective-C runtime API."
(ObjC.api:一个将函数名称映射到NativeFunction实例的对象,用于直接访问Objective-C运行时API的大部分内容。)
"ObjC.classes: an object mapping class names to ObjC.Object JavaScript bindings for each of the currently registered classes. You can interact with objects by using dot notation and replacing colons with underscores, i.e.: [NSString stringWithString:@"Hello World"] becomes const { NSString } = ObjC.classes; NSString.stringWithString_("Hello World");. Note the underscore after the method name. Refer to iOS Examples section for more details."
(ObjC.classes:一个将类名称映射到当前已注册类的每个ObjC.Object JavaScript绑定的对象。您可以使用点表示法与对象交互,并用下划线替换冒号,例如:[NSString stringWithString:@"Hello World"] 变成 const { NSString } = ObjC.classes; NSString.stringWithString_("Hello World");。请注意方法名称后面的下划线。有关更多详细信息,请参阅iOS示例部分。)
"ObjC.protocols: an object mapping protocol names to ObjC.Protocol JavaScript bindings for each of the currently registered protocols."
(ObjC.protocols:一个将协议名称映射到当前已注册协议的每个ObjC.Protocol JavaScript绑定的对象。)
"ObjC.mainQueue: the GCD queue of the main thread"
(ObjC.mainQueue:主线程的GCD队列)
"ObjC.schedule(queue, work): schedule the JavaScript function work on the GCD queue specified by queue. An NSAutoreleasePool is created just before calling work, and cleaned up on return."
(ObjC.schedule(queue, work):在由queue指定的GCD队列上安排JavaScript函数work。在调用work之前,会创建一个NSAutoreleasePool,并在返回时进行清理。)
ApiResolver搜刮内存中的所有符号
枚举搜索所有类/所有方法/所有重载
Using ApiResolver come true code search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
setImmediate(() => {
console.log( "hello world! calleng! ObjC => " , ObjC.available)
const resolver = new ApiResolver( 'objc' );
const matches = resolver.enumerateMatches( '*[* theLabel]' );
matches.forEach((match)=>{
console.log(JSON.stringify(match))
})
})
|
hook所有类/所有方法/所有重载
ios hooking watch class ViewController
jobs list
jobs kill 232233
ios hooking list class_methods ViewController
ios hooking watch method "*[ViewController buttonClick:]"
--dump-args
--dump-backtrace
--dump-return
// (classname and method name )must type completely. add , [Parameters , CallStacks, Return Value.]at the tail.
new ObjC.Object(handle[, protocol]):
create a JavaScript binding given the existing object at handle (a NativePointer). You may also specify the protocol argument if you’d like to treat handle as an object implementing a certain protocol only."
new ObjC.Object(handle[, protocol]):
基于指定的 NativePointer(句柄),创建一个 JavaScript 绑定。如果需要将该句柄视为仅实现特定协议的对象,则还可以指定 protocol 参数。"
Definition new ObjC.Object(handle[, protocol]):
1 2 3 4 5 6 7 | Interceptor.attach(myFunction.implementation, {
onEnter(args) {
const myString = new ObjC.Object(args[2]);
console.log( "String argument: " + myString.toString());
}
});
|
Objection hooking.ts
Source Code about watchInvocation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | const watchInvocation: InvocationListener = Interceptor.attach(matchedMethod.address, {
onEnter: function (args) {
const argumentCount: number = (selector.match(/:/g) || []).length;
const receiver = new ObjC.Object(args[0]);
send(
c.blackBright(`[${job.identifier}] `) +
`Called: ${c.green(`${selector}`)} ${c.blue(`${argumentCount}`)} arguments` +
`(Kind: ${c.cyan(receiver.$kind)}) (Super: ${c.cyan(receiver.$superClass.$className)})`,
);
if (dbt) {
send(
c.blackBright(`[${job.identifier}] `) +
`${c.green(`${selector}`)} Backtrace:\n\t` +
Thread.backtrace( this .context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join( "\n\t" ),
);
}
if (dargs && argumentCount > 0) {
const methodSplit = ObjC.selectorAsString(args[1]).split( ":" ).filter((val) => val);
const r = methodSplit.map((argName, position) => {
const t = new ObjC.Object(args[position + 2]);
return `${argName}: ${c.greenBright(`${t}`)}`;
});
send(c.blackBright(`[${job.identifier}] `) +
`Argument dump: [${c.green(receiver.$className)} ${r.join( " " )}]`);
}
},
onLeave: (retval) => {
if (!dret) { return ; }
send(c.blackBright(`[${job.identifier}] `) + `Return Value: ${c.red(retval.toString())}`);
},
});
|
Write Self Script for Hooking Function
put blew content code
to 09.js
running it frida -UF -l 09.js
when it UnCrakable1
running Front of SpringBoard.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | setImmediate(() => {
console.log( "hello world! calleng! ObjC => " , ObjC.available)
const resolver = new ApiResolver( 'objc' );
const matches = resolver.enumerateMatches( '*[* buttonClick:*]' );
matches.forEach((match)=>{
console.log(JSON.stringify(match))
Interceptor.attach(match.address,{
onEnter: function (args){
const receiver = new ObjC.Object(args[0]);
console.log( "receiver is =>" ,receiver.$className, " => " ,JSON.stringify(receiver));
},onLeave: function (ret){
console.log( "ret=>" ,ret)
}
})
})
})
|
and touch screen
input some characters
.then click Verify
will disappear, below messages.
then , go to food delivery and finish it , go on ~ (40:24 Lesson09)
官网的案例也有问题,
缺少 args 参数
看参数, 调用栈(不看了,非常麻烦.), 返回值 ,.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | setImmediate(() => {
console.log( "hello world! calleng! ObjC => " , ObjC.available)
const resolver = new ApiResolver( 'objc' );
const matches = resolver.enumerateMatches( '*[* isEqualToString:*]' );
matches.forEach((match) => {
console.log(JSON.stringify(match))
Interceptor.attach(match.address, {
onEnter: function (args){
const receiver = new ObjC.Object(args[0]);
console.log( "receiver is =>" , receiver.$className, " => " , receiver.toString());
}, onLeave: function (ret) {
console.log( "ret=>" , ret)
}
})
})
})
|
这是一个自己, 是一个对象. receiver.toString()); 转换成字符串, 而非地址,使用这个函数后. 入上图 , =》 便是
修改返回值成功了.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | setImmediate(() => {
console.log( "hello world! calleng! ObjC => " , ObjC.available)
const resolver = new ApiResolver( 'objc' );
const matches = resolver.enumerateMatches( '*[* isEqualToString:*]' );
matches.forEach((match) => {
console.log(JSON.stringify(match))
Interceptor.attach(match.address, {
onEnter: function (args){
this .change = false ;
const receiver = new ObjC.Object(args[0]);
console.log( "receiver is =>" , receiver.$className, " => " , receiver.toString());
if (receiver.toString().indexOf( "aaaabbbb" )>=0) {
this .change = true ;
console.log( "need change" )
}
}, onLeave: function (ret) {
console.log( "ret=>" , ret)
if ( this .change){
ret.replace( new NativePointer(0x1))
}
}
})
})
})
|
//只是 hook了 isEqualToString
让他在参数里面带4个a, 4个b ,返回,修改通过.
以上代码的解释
- 检查是否有Objective-C运行环境
- 通过ApiResolver枚举所有符合特定条件的函数
- 对于每个符合条件的函数,使用Interceptor进行拦截
- 在函数进入时,检查接收者的类名和字符串表示中是否包含"aaaabbbb"
- 如果接收者满足条件(包含"aaaabbbb"),则修改该函数返回值
// 以上是修改返回值的例子.
Output (modify) parsing parameters
ObjC.classes
: an object mapping class names to ObjC.Object
JavaScript bindings for each of the currently registered classes. You can interact with objects by using dot notation and replacing colons with underscores, i.e.: [NSString stringWithString:@"Hello World"]
becomes const { NSString } = ObjC.classes; NSString.stringWithString_("Hello World");
. Note the underscore after the method name. Refer to iOS Examples section for more details.
key code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | setImmediate(() => {
console.log( "hello world! calleng! ObjC => " , ObjC.available)
const resolver = new ApiResolver( 'objc' );
const matches = resolver.enumerateMatches( '*[* isEqualToString:*]' );
matches.forEach((match) => {
console.log(JSON.stringify(match))
Interceptor.attach(match.address, {
onEnter: function (args){
this .change = false ;
const receiver = new ObjC.Object(args[0]);
console.log( "receiver is =>" , receiver.$className, " => " , receiver.toString());
if (receiver.toString().indexOf( "aaaabbbb" )>=0) {
this .change = true ;
console.log( "need change" )
const { NSString } = ObjC.classes;
var newString = NSSting.stringWithString_( "aaaabbbb" );
args[2] = newString;
}
}, onLeave: function (ret) {
console.log( "ret=>" , ret)
}
})
})
})
|
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2023-11-8 00:23
被calleng编辑
,原因: 修改大纲,填充内容