热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS支付宝小程序与原生交互分析

1.从 https:github.commpaas-demoios-tinyapp?spma2c4g.11186623.2.23.7e386fe0mar9s5 下载支付宝

 

1.从 https://github.com/mpaas-demo/ios-tinyapp?spm=a2c4g.11186623.2.23.7e386fe0mar9s5 下载支付宝小程序demo,

按照说明执行

1).修改Podfile,设置基线号,支持设置为10.1.68-beta

2)、pod mpaas update --all

3)、pod update

根据提示再升级pod的mpaas版本,然后再pod update

demo能正常运行了

 

 

2.从官方文档可以看到FalconLooks库小程序需要

 

3.hook push方法先从进入页面的堆栈看,看不出啥

 

4.hook一下WKWebView的@selector(evaluateJavascript:completionHandlerS:)


.h
#import
NS_ASSUME_NONNULL_BEGIN
@interface WKWebView (YYY)
@end
NS_ASSUME_NONNULL_END
.m
#import "WKWebView+YYY.h"
#import
typedef void (^BLOCKYYY)(id _Nullable str7 , NSError * er7) ;
@implementation WKWebView (YYY)
+(void)load{


{
Method originalMethod = class_getInstanceMethod([NSClassFromString(@"WKWebView") class], @selector(evaluateJavascript:completionHandler:));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(evaluateJavascript:completionHandlerS:));
method_exchangeImplementations(originalMethod, swizzledMethod);
}


}
-(void)evaluateJavascript:(NSString *)JavascriptString completionHandlerS:(void (^)(id _Nullable str7 , NSError * er7))completionHandler{

NSLog(@"小程序 %@ ",JavascriptString);

[self evaluateJavascript:JavascriptString completionHandlerS:^(id _Nullable str, NSError *er) {
NSLog(@"小程序返回 %@ ",str);
// completionHandler(str,er);
}];

[self evaluateJavascript:JavascriptString completionHandlerS:completionHandler];



}
@end

分类添加属性要使用关联,不能直接加

 

5.点击API->警告框

,看到的打印是:


2020-07-21 09:52:24.934694+0800 MPTinyAppDemo_pod[18373:5199176] 小程序 location.href
2020-07-21 09:52:35.072146+0800 MPTinyAppDemo_pod[18373:5199176] 小程序 AlipayJSBridge._handleMessageFromObjC('{\"responseId\":\"postMessage_15952963380340.17604869608612228\",\"responseData\":{\"messageEventCanceled\":false}}');
2020-07-21 09:52:38.605279+0800 MPTinyAppDemo_pod[18373:5199176] 小程序 location.href
2020-07-21 09:52:38.615518+0800 MPTinyAppDemo_pod[18373:5199176] 小程序 location.href
2020-07-21 09:52:38.616711+0800 MPTinyAppDemo_pod[18373:5199176] 小程序返回 (null)
2020-07-21 09:52:38.617399+0800 MPTinyAppDemo_pod[18373:5199176] 小程序返回 https://2020012000000001.h5app.com/index.html#page/API/alert/alert?__appxPageId=102
2020-07-21 09:52:38.620946+0800 MPTinyAppDemo_pod[18373:5199176] 小程序返回 https://2020012000000001.h5app.com/index.html#page/API/alert/alert?__appxPageId=102
2020-07-21 09:59:38.614236+0800 MPTinyAppDemo_pod[18373:5199176] 小程序 location.href
2020-07-21 09:59:39.114819+0800 MPTinyAppDemo_pod[18373:5199176] 小程序 location.href
2020-07-21 09:59:39.372248+0800 MPTinyAppDemo_pod[18373:5199176] 小程序返回 https://2020012000000001.h5app.com/index.html#page/API/alert/alert?__appxPageId=102
2020-07-21 09:59:40.035466+0800 MPTinyAppDemo_pod[18373:5199176] 小程序 AlipayJSBridge._handleMessageFromObjC('{\"callbackId\":\"objc_cb_3\",\"handlerName\":\"back\"}');

可以看到也没有什么有用信息

 

6.但是在上面方法打个断点,可以看到

H5JSCBridge的@selector(doCallWithItem:callBack:)这个方法

 

7.hook这个方法


- (void)doCallWithItem:(id)arg1 callBackS:(id)arg2;
{
NSLog(@"doCallWithItem参数%@",arg1);
[self doCallWithItem:arg1 callBackS:arg2 ];
}

并点击警告框 看其打印


2020-07-21 10:12:39.742773+0800 MPTinyAppDemo_pod[18410:5206087] doCallWithItem参数{
callbackId = "pushWindow_15952975597410.2726862088613564";
data = "{\"url\":\"#page/API/alert/alert?__appxPageId=101\",\"viewId\":3,\"launchParamsTag\":\"page/API/alert/alert\"}";
handlerName = pushWindow;
}
2020-07-21 10:12:40.268824+0800 MPTinyAppDemo_pod[18410:5206087] doCallWithItem参数{
callbackId = "postMessage_15952975602670.6360432434314175";
data = "{\"data\":\"{\\\"data\\\":{\\\"c\\\":\\\"self\\\",\\\"m\\\":\\\"invokeCallback\\\",\\\"d\\\":101,\\\"a\\\":[1,{\\\"showOptionMenu\\\":false,\\\"app_startup_type\\\":\\\"inner\\\",\\\"url\\\":\\\"https://2020012000000001.h5app.com/index.html#page/tabBar/component/index\\\",\\\"enableKeepAlive\\\":false,\\\"backgroundColor\\\":16119289,\\\"transparentTitle\\\":\\\"auto\\\",\\\"allowsBounceVertical\\\":\\\"NO\\\",\\\"version\\\":\\\"1.0.99.0\\\",\\\"enableTabBar\\\":true,\\\"backBehavior\\\":\\\"pop\\\",\\\"inPageRenderType\\\":\\\"map|video|camera|canvas|cdp|ai-camera|ad\\\",\\\"nboffline\\\":\\\"sync\\\",\\\"titleBarColor\\\":16777215,\\\"kPSDSceneInjectRequest\\\":true,\\\"sourceId\\\":\\\"\\\",\\\"enableDSL\\\":true,\\\"kPSDSessionH5Mode\\\":0,\\\"kPSDSessionPSDType\\\":0,\\\"appId\\\":\\\"2020012000000001\\\",\\\"tinyPubRes\\\":true,\\\"launchParamsTag\\\":\\\"page/tabBar/component/index\\\",\\\"defaultTitle\\
2020-07-21 10:12:41.427530+0800 MPTinyAppDemo_pod[18410:5206087] doCallWithItem参数{
callbackId = "alert_15952975614230.9276469663708761";
data = "{\"title\":\"\U4eb2\",\"message\":\"\U60a8\U672c\U6708\U7684\U8d26\U5355\U5df2\U51fa\",\"button\":\"\U6211\U77e5\U9053\U4e86\"}";
handlerName = alert;
}

这样就能看到插件名字和参数了。

上面用到了跳页的pushWindow,弹框的alert。

到这里一般开发中遇到的问题及参数打印应该就没多大问题了。

 

 

 

 

 

8.按照惯例doFlushMessageQueue的功能是与h5交互,将返回的数据交给不同的插件去跳页或展示

用模拟器运行一下拖到hopper看一下,


void -[H5JSCBridge doFlushMessageQueue:](void * self, void * _cmd, void * arg2) {
r14 = [arg2 retain];
objc_initWeak(&var_-40, self);
*(&var_-48 + 0xffffffffffffffd8) = __NSConcreteStackBlock;
*(&var_-48 + 0xffffffffffffffe0) = 0xc2000000;
*(&var_-48 + 0xffffffffffffffe8) = ___35-[H5JSCBridge doFlushMessageQueue:]_block_invoke;
*(&var_-48 + 0xfffffffffffffff0) = ___block_descriptor_48_e8_32s40w_e5_v8?0l;
objc_copyWeak(&var_-48, &var_-40);
rax = [r14 retain];
*(&var_-48 + 0xfffffffffffffff8) = rax;
_ExMainCall_NebulaSDK("-[H5JSCBridge doFlushMessageQueue:]", 0x0, &var_-88);
[var_-56 release];
objc_destroyWeak(&var_-48);
objc_destroyWeak(&var_-40);
[rax release];
return;
}
function ___35-[H5JSCBridge doFlushMessageQueue:]_block_invoke {
r14 = rdi;
rax = objc_loadWeakRetained(rdi + 0x28);
rbx = rax;
if (rax != 0x0) {
rdx = [NSArray class];
if ([*(r14 + 0x20) isKindOfClass:rdx] != 0x0) {
rax = [*(r14 + 0x20) copy];
var_-56 = rax;
rax = [rax count];
var_-48 = rbx;
if (rax > 0x0) {
r13 = rax;
r15 = _objc_msgSend;
r12 = 0x0;
do {
rax = (r15)(var_-56, @selector(objectAtIndex:), r12, 0x0);
rax = [rax retain];
(r15)(var_-48, @selector(doCallWithItem:callBack:), rax, 0x0);
[rax release];
r12 = r12 + 0x1;
} while (r13 != r12);
}
[var_-56 release];
rbx = var_-48;
}
}
rax = [rbx release];
return rax;
}
void -[H5JSCBridge doFlushMessageQueue:callBack:](void * self, void * _cmd, void * arg2, void * arg3) {
r15 = [arg2 retain];
r12 = [arg3 retain];
objc_initWeak(&var_-48, self);
*(&var_-56 + 0xffffffffffffffd0) = __NSConcreteStackBlock;
*(&var_-56 + 0xffffffffffffffd8) = 0xc2000000;
*(&var_-56 + 0xffffffffffffffe0) = ___44-[H5JSCBridge doFlushMessageQueue:callBack:]_block_invoke;
*(&var_-56 + 0xffffffffffffffe8) = ___block_descriptor_56_e8_32s40bs48w_e5_v8?0l;
objc_copyWeak(&var_-56, &var_-48);
rax = [r15 retain];
r14 = rax;
*(&var_-56 + 0xfffffffffffffff0) = rax;
rax = [r12 retain];
*(&var_-56 + 0xfffffffffffffff8) = rax;
_ExMainCall_NebulaSDK("-[H5JSCBridge doFlushMessageQueue:callBack:]", 0x0, &var_-104);
[var_-64 release];
[var_-72 release];
objc_destroyWeak(&var_-56);
objc_destroyWeak(&var_-48);
[rax release];
[r14 release];
return;
}

但这个不是

 

9.在void -[PSDJsBridge _doFlushMessageQueue:url:]打断点

看到了这个方法

MPTinyAppDemo_pod`-[PSDScriptMessageHandlerProxy userContentController:didReceiveScriptMessage:]:

这个应该就是h5直接调用原生的源方法

hook它,



#import "PSDScriptMessageHandlerProxy+YYY.h"
#import
@implementation PSDScriptMessageHandlerProxy (YYY)
+(void)load{
Method originalMethod = class_getInstanceMethod([self class], @selector(userContentController:didReceiveScriptMessage:));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(userContentController:didReceiveScriptMessageS:));
method_exchangeImplementations(originalMethod, swizzledMethod);

}
- (void)userContentController:(nonnull WKUserContentController *)arg1 didReceiveScriptMessageS:(nonnull WKScriptMessage *)arg2;{

NSLog(@"userContentController %@ %@ %@",arg1,arg2.body,arg2.name);

[self userContentController:arg1 didReceiveScriptMessageS:arg2];

}
@end

 

打印数据有下面这个,应该还有间接的取值过程


2020-07-21 11:08:40.929573+0800 MPTinyAppDemo_pod[64206:6239032] userContentController {
msgKt = 41fa91654a13b6bca904cfcea7279bc1;
queue = "[{\"responseId\":\"objc_cb_1\",\"responseData\":{\"messageEventCanceled\":false,\"syncJsApis\":[]}}]";
type = api;
} PSDBRIDGEMESSAGEHANDLER

 

 

暂时先这样,后面遇到相关问题再完善

 

 

10.容器控制器打印创建参数


PSDScene *delegate = (PSDScene *)self.delegate;
PSDSceneParam *psdScene = [delegate createParam];
NSDictionary *dic = psdScene.expandParams;

参数中包含tinyPubRes = 1;

猜想这个参数可以判断当前打开的是小程序还是离线包。

 

 

 


本文地址:https://blog.csdn.net/qq_15509071/article/details/107406227



推荐阅读
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文介绍了在满足特定条件时如何在输入字段中使用默认值的方法和相应的代码。当输入字段填充100或更多的金额时,使用50作为默认值;当输入字段填充有-20或更多(负数)时,使用-10作为默认值。文章还提供了相关的JavaScript和Jquery代码,用于动态地根据条件使用默认值。 ... [详细]
  • 在Windows10系统上使用VMware创建CentOS虚拟机的详细步骤教程
    本文详细介绍了在Windows10系统上使用VMware创建CentOS虚拟机的步骤,包括准备条件、安装VMware、下载CentOS ISO文件、创建虚拟机并进行自定义配置、设置虚拟机的ISO与网络、进行安装和配置等。通过本文的指导,读者可以轻松地创建自己的CentOS虚拟机并进行相应的配置和操作。 ... [详细]
  • 判断编码是否可立即解码的程序及电话号码一致性判断程序
    本文介绍了两个编程题目,一个是判断编码是否可立即解码的程序,另一个是判断电话号码一致性的程序。对于第一个题目,给出一组二进制编码,判断是否存在一个编码是另一个编码的前缀,如果不存在则称为可立即解码的编码。对于第二个题目,给出一些电话号码,判断是否存在一个号码是另一个号码的前缀,如果不存在则说明这些号码是一致的。两个题目的解法类似,都使用了树的数据结构来实现。 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • 获取时间的函数js代码,js获取时区代码
    本文目录一览:1、js获取服务器时间(动态)2 ... [详细]
  • 详解 Python 的二元算术运算,为什么说减法只是语法糖?[Python常见问题]
    原题|UnravellingbinaryarithmeticoperationsinPython作者|BrettCannon译者|豌豆花下猫(“Python猫 ... [详细]
  • Imdevelopinganappwhichneedstogetmusicfilebystreamingforplayinglive.我正在开发一个应用程序,需要通过流 ... [详细]
  • fileuploadJS@sectionscripts{<scriptsrc~Contentjsfileuploadvendorjquery.ui.widget.js ... [详细]
author-avatar
AD社团
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有