JS调用OC函数

点击打开链接

感谢作者~

一、以前使用js调用object-c的方法

关于如何使用javascript调用object-c中的函数和方法,我搜索了好久

网上所有的方法,基本都指明了一个方向,那就是在UIWebview中载入的js代码中

通过改变document.locations=“”,然后回调UIWebview的

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

函数,在上面这个函数中,通过截取NSURLRequest解析js中传递过来的参数,再根据参数

来选择早已定义好的方法。

有没有别的方法呢? 我找了几个月,没找到!但是有一个转机。

我偶然知道了  javascriptCore.framework 这个库

于是事情有了转机。

 

二、在js中直接调用oc的方法

废话不多说,现在看看如何在UIWebView的javascript中调用oc的方法

首先在建立一个UIWebView,代码如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //  
  2. //  webview.m  
  3. //  login  
  4. //  
  5. //  Created by wangdan on 15-3-19.  
  6. //  Copyright (c) 2015年 wangdan. All rights reserved.  
  7. //  
  8.   
  9. #import "webview.h"  
  10. #import <JavaScriptCore/JavaScriptCore.h>  
  11.   
  12. @implementation webview  
  13.   
  14.   
  15. -(id)initWithFrame:(CGRect)frame  
  16. {  
  17.     self=[super initWithFrame:frame];  
  18.       
  19.     ifself ){  
  20.         self.webview=[[UIWebView alloc]initWithFrame:CGRectMake(0310self.bounds.size.width300)];  
  21.         self.webview.backgroundColor=[UIColor lightGrayColor];  
  22.         NSString *htmlPath=[[NSBundle mainBundle] resourcePath];  
  23.         htmlPath=[htmlPath stringByAppendingPathComponent:@"html/index.html"];  
  24.         NSURL *localURL=[[NSURL alloc]initFileURLWithPath:htmlPath];  
  25.         [self.webview loadRequest:[NSURLRequest requestWithURL:localURL]];  
  26.         [self addSubview:self.webview];  
  27.   
  28.          JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];  
  29.          context[@"log"] = ^() {  
  30.   
  31.             NSLog(@"+++++++Begin Log+++++++");  
  32.             NSArray *args = [JSContext currentArguments];  
  33.   
  34.             for (JSValue *jsVal in args) {  
  35.                 NSLog(@"%@", jsVal);  
  36.             }  
  37.   
  38.             JSValue *this = [JSContext currentThis];  
  39.             NSLog(@"this: %@",this);  
  40.             NSLog(@"-------End Log-------");  
  41.   
  42.         };  
  43.           
  44.   
  45. //        [context evaluateScript:@"log('ider', [7, 21], { hello:'world', js:100 });"];  
  46.   
  47.           
  48.     }  
  49.     return self;  
  50. }  
  51.   
  52.   
  53. @end  

 

(1)在上述代码中,使用javascriptCore.framework,首先使用UIWebview加载一个静态网页,并

使用

JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

获取该UIWebview的javascript执行环境。

(2)在该javascript执行环境中,定义一个js函数,注意关键点来了

这个函数的执行体完全是 objective-c代码写的,也就是下面:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. context[@"jakilllog"] = ^() {  
  2.   
  3.         NSLog(@"Begin Log");  
  4.         NSArray *args = [JSContext currentArguments];  
  5.   
  6.         for (JSValue *jsVal in args) {  
  7.             NSLog(@"%@", jsVal);  
  8.         }  
  9.   
  10.         JSValue *this = [JSContext currentThis];  
  11.         NSLog(@"-------End Log-------");  
  12.   
  13.     };  
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.    
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.    

(3)试想一下,在定义的webview中,如果使用js执行log这个函数,那么会不会调用上面oc中block段代码呢,答案是肯定的!

下面看看UIWebView 中所加载的 html及其js代码是如何写的

(4)index.html代码

 

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <!--//  Created by wangdan on 15-3-19.-->  
  2. <!--//  Copyright (c) 2014年 wangdan. All rights reserved.-->  
  3.   
  4. <!DOCTYPE html>  
  5.   
  6. <html lang="en">  
  7.       
  8.     <head>  
  9.           
  10.          <meta charset="utf-8">  
  11.               
  12.           <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  
  13.             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />      
  14.                   
  15.             <meta name="description" content="">  
  16.                       
  17.             <meta name="viewport" content="width=device-width; initial-scale=1.0">  
  18.              <script type="text/javascript" src="index.js"></script>             
  19.         
  20.                           
  21.       </head>  
  22.       
  23.     <button id="hallo" onclick="buttonClick()"> 点击button</button>  
  24.   
  25.     </body>  
  26.       
  27. </html>  

 
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 上面html定义了一个button,然后引用index.js,点击button的响应函数为buttonClick()  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 该函数在index.js中定义,如下  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. function buttonClick()  
  2. {  
  3.     jakilllog("hello world");  
  4. }  

 

意思是点击这个button,就调用jakilllog()函数,jakilllog()函数显然是我们在oc中实现的一个block段,

就是上述绿色部分的block段。

 

点击button会执行么?答案是肯定的。

下面上图

 

下图是执行的结果



点击html中的button,能够执行oc中的代码

说明直接从js调用oc的意图达到。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Frida是一款针对移动应用的动态分析工具,它可以对APP进行hook和脱壳等操作。Frida在调用OC函数时,需要使用Objective-C Runtime的方法进行调用。 首先,Frida需要与应用进行通信,以便能够在运行时hook应用中的方法和函数。Frida提供了多种方式与应用进行通信,其中较为常用的是通过Frida提供的JavaScript API来实现。在JavaScript中,可以使用frida的API来遍历当前运行的进程,找到目标进程,并获取到其Objective-C运行时。 接下来,就可以使用Objective-C Runtime提供的方法,比如`class_addMethod`或`method_exchangeImplementations`来hook目标类或方法,从而达到调用OC函数的目的。需要注意的是,在hook之前,必须先对目标类或方法进行类定义或方法定义,以便后续在hook中调用。此外,还需要考虑hook时所使用的参数和返回值类型,必须与被hook的函数或方法保持一致,否则可能会导致异常。 在Frida中,调用OC函数的过程需要注意一些细节和注意事项,但总体来说,通过Objective-C Runtime的方式,可以实现在运行时hook和调用OC函数的目的。 ### 回答2: Frida是一款逆向工程工具,可以用来调用Objective-C函数Objective-C是一种面向对象的编程语言,是苹果公司开发和推广的语言。Frida支持通过绕开iOS的应用程序级加密,直接访问内存,可以在iOS设备上实现针对Objective-C的Hook。 在使用Frida调用Objective-C函数时,需要先安装Frida到设备上并连接上Frida服务。接着,需要在Frida中编写脚本代码,来调用Objective-C函数。 在Frida中,可以使用以下函数来执行Objective-C方法: 1. ObjC.classes:获取所有Objective-C类。 2. ObjC.choose():获取匹配模式的某个实例。 3. ObjC.classes['类名称'].方法名.implementation(参数):调用Objective-C类的方法。 例如,在Frida中调用方法名为“test”且参数为“hello”的Objective-C函数,代码如下: ```javascript var className = ObjC.classes['Test']; var methodName = "test"; var parameter = "hello"; var hook = eval('var temp = '+ className +'; '+ '(function() {return temp["'+ methodName +'"]})()'); Interceptor.attach(hook.implementation, { onEnter: function (args) { console.log("[*] Starting Test"); console.log("[+] Parameters: " + Memory.readUtf8String(args[2])); }, onLeave: function (retval) { console.log("[*] Completed Test"); } }); ``` 其中,ObjC.classes获取Objective-C类,eval函数获取某个类的方法,Interceptor.attach则是在某个函数调用前后注入进程。 总之,使用Frida调用Objective-C函数需要先了解Objective-C类和方法的概念,并在Frida中编写相应的脚本进行调用。 ### 回答3: Frida是一款用于Windows、macOS、Linux、iOS和Android平台的动态分析工具,可在运行时修改应用程序的行为和拦截网络通信。在iOS平台上,Frida可以利用Objective-C的运行时库注入自己的代码,从而调用Objective-C代码。 要在Frida中调用OC函数,需要先获取要调用函数的地址。可以使用以下命令在Frida控制台中获取函数地址: ``` var className = "ViewController"; // 要调用函数所在的类名 var funcName = "-(void)showAlert:(NSString *)message"; // 要调用函数名 var ptr = ObjC.classes[className][funcName].implementation; console.log("Function Address: " + ptr); ``` 在获取到函数地址后,可以使用以下命令在Frida控制台中调用OC函数: ``` var funcPtr = new NativePointer("0x12345678"); // 0x12345678为要调用函数地址 var showAlertFunc = new NativeFunction(funcPtr, 'void', ['pointer']); showAlertFunc(Memory.allocUtf8String("Hello, Frida!")); ``` 其中,'void'是函数返回类型,['pointer']是参数类型的数组。在这个例子中,函数只有一个NSString类型的参数,因此参数类型为['pointer'],并需要使用Memory.allocUtf8String()函数将字符串转换为指针类型。 使用Frida调用OC函数需要一定的Objective-CJavaScript基础,对iOS平台下的应用开发有一定的了解,同时也要注意避免对应用程序造成不良影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值