起因

我们公司在17年的时候有个在手机端设备控制的项目,Android端和iOS端是使用apicloud打包而成。当时有款需要控制的设备用到了庆科的WiFi模组,所以项目中使用了庆科在apicloud的模块Store中提供的模块。
在这个项目上线后,很长一段时间都属于停滞状态。直到最近项目重启,再去看,庆科的模块已经全被下架了,而其它满足需求的模块需要付钱。
虽然庆科的官网中有原生android和iOS开发的文档,但是通过我自定义模块编译的APP甚至官方文档中的APP均无法完成配网和设备发现。

过程

通过用Fiddler抓包观察apicloud添加模块的流程,我发现在apicloud中每个模块都有一个唯一的模块ID,而添加模块的操作是针对模块ID进行的。虽然庆科所有的模块均已被下架,但我估计模块的数据依旧存在于apicloud的数据库中,而只是将数据的状态置为搜索不可见。通过apicloud论坛,我得知了庆科在apicloud上架的模块有两个—mico和fog2。
随后我再在百度中搜索apicloud mico,找到属于它的百度快照。通过百度快照,找到了mico模块的模块ID—8647
再通过添加其它模块,得到添加模块的接口与数据、cookie(我这里是直接用的新版本的fiddler直接抓包,修改,请求)。然后将数据中的模块ID改成mico模块的模块ID—8647,最后执行接口请求。

mico躺在已添加模块中。

在加完mico模块后,我才注意到这个模块居然是只支持Android,并且我打包后的APP依旧无法完成配网和设备发现。

接着我再在百度中搜索apicloud fog2,找到属于它的百度快照,不过与mico模块不同,通过百度快照无法得知fog2的模块ID。


随后我尝试再用其它的搜索引擎,通过Google,找到了模块ID—24853


最后按照添加mico模块的办法添加fog2模块到项目中。

看似到这一步一切已经完成了,其实并没有。因为fog2模块的开发文档失效了。

又回到了原点。

这时我想到,不如打个Android的包,再将这个包反编译,不就可以得到fog2模块的源码了吗?

祭出我的反编译三件套

首先将apk文件解压到文件夹

然后在当前页面启动命令行模式,输入 java -jar apktool_2.3.4.jar d -f app.apk -o app

随后使用VSCode打开apktool反编译apk的输出文件夹,搜索fog2,得知fog2模块代码存在于classes20.dex文件中。

将classes20.dex文件复制到dex2jar-2.0文件夹中

随即在命令行中定位到dex2jar-2.0目录下,输入 d2j-dex2jar classes20.dex,得到classes20-dex2jar.jar包


经过分析代码和转化其它需要的dex文件,得到以下方法

public void jsmethod_getSSID(UZModuleContext paramUZModuleContext){this.mJsCallback = paramUZModuleContext;paramUZModuleContext = this.micodev.getSSID();execCallBack("success", this.errorCode.setSuccJson("{\"ssid\":\"" + paramUZModuleContext + "\"}"), true);}public void jsmethod_init(UZModuleContext paramUZModuleContext){this.mJsCallback = paramUZModuleContext;paramUZModuleContext = paramUZModuleContext.optString("host");if (checkAndCallBack(true, new String[] { paramUZModuleContext })) {MiCO.init(paramUZModuleContext);}}public void jsmethod_startEasyLink(UZModuleContext paramUZModuleContext){this.mJsCallback = paramUZModuleContext;String str1 = paramUZModuleContext.optString("ssid");String str2 = paramUZModuleContext.optString("password");int j = paramUZModuleContext.optInt("runSecond");int k = paramUZModuleContext.optInt("sleeptime");paramUZModuleContext = paramUZModuleContext.optString("extraData");int i = j;if (j == 0) {i = 60000;}j = k;if (k == 0) {j = 20;}if ((checkAndCallBack(true, new String[] { str1 })) && (i > 0) && (j > 0)) {this.micodev.startEasyLink(str1, str2, i, j, new EasyLinkCallBack(){public void onFailure(int paramAnonymousInt, String paramAnonymousString){Fog2sdk.this.execCallBack("error", Fog2sdk.this.errorCode.setFailureJsonCode(paramAnonymousInt, paramAnonymousString), true);}public void onSuccess(String paramAnonymousString){if ("success".equals(paramAnonymousString)){Fog2sdk.this.execCallBack("keep", Fog2sdk.this.errorCode.setSuccJson("{\"message\":\"" + paramAnonymousString + "\"}"), false);return;}Fog2sdk.this.execCallBack("keep", Fog2sdk.this.errorCode.setSuccJson("{\"message\":\"" + paramAnonymousString + "\"}"), true);}}, paramUZModuleContext);}}public void jsmethod_startSearchDevices(UZModuleContext paramUZModuleContext){this.mNDSCallBack = paramUZModuleContext;this.micodev.startSearchDevices("_easylink._tcp.local.", new SearchDeviceCallBack(){public void onDevicesFind(JSONArray paramAnonymousJSONArray){if (Fog2sdk.this.mNDSCallBack != null) {Fog2sdk.this.mNDSCallBack.success(Fog2sdk.this.errorCode.setSuccJson("{\"devices\":" + paramAnonymousJSONArray.toString() + "}"), false);}}public void onFailure(int paramAnonymousInt, String paramAnonymousString){Fog2sdk.this.mNDSCallBack.error(null, Fog2sdk.this.errorCode.setFailureJsonCode(paramAnonymousInt, paramAnonymousString), true);}public void onSuccess(String paramAnonymousString){Fog2sdk.this.mNDSCallBack.success(Fog2sdk.this.errorCode.setSuccJson("{\"message\":\"" + paramAnonymousString + "\"}"), false);}});}public void jsmethod_stopEasyLink(UZModuleContext paramUZModuleContext){this.mJsCallback = paramUZModuleContext;this.micodev.stopEasyLink(new EasyLinkCallBack(){public void onFailure(int paramAnonymousInt, String paramAnonymousString){Fog2sdk.this.execCallBack("error", Fog2sdk.this.errorCode.setFailureJsonCode(paramAnonymousInt, paramAnonymousString), true);}public void onSuccess(String paramAnonymousString){Fog2sdk.this.execCallBack("success", Fog2sdk.this.errorCode.setSuccJson("{\"message\":\"" + paramAnonymousString + "\"}"), true);}});}public void jsmethod_stopSearchDevices(UZModuleContext paramUZModuleContext){this.mJsCallback = paramUZModuleContext;this.micodev.stopSearchDevices(new SearchDeviceCallBack(){public void onFailure(int paramAnonymousInt, String paramAnonymousString){Fog2sdk.this.execCallBack("error", Fog2sdk.this.errorCode.setFailureJsonCode(paramAnonymousInt, paramAnonymousString), true);Fog2sdk.this.mNDSCallBack = null;}public void onSuccess(String paramAnonymousString){Fog2sdk.this.execCallBack("success", Fog2sdk.this.errorCode.setSuccJson("{\"message\":\"" + paramAnonymousString + "\"}"), true);Fog2sdk.this.mNDSCallBack = null;}});}
package com.mxchip.helper;public class MiCO
{public static void init(String paramString){Configuration._APIHOST = paramString;}
}public static String _APIHOST = "https://v2.fogcloud.io";

最终得出的js代码

let fog2 = null;
let easyLinkService = {hasInit: false,init: function() {if(fog2 == null){fog2 = api.require('fog2')}if (!this.hasInit) {this.initEasyLink()this.hasInit = true}},initEasyLink: function() {fog2.init({host: "https://v2.fogcloud.io"})},getSSID: function() {return new Promise ( function(resolve, reject) {fog2.getSSID(function(ret, err) {if (ret) {resolve(ret.ssid)} else {reject(err)}});})},startEasyLink: function(ssid_val, psw_val) {return new Promise ( function(resolve, reject) {let param = {ssid: ssid_val,password: psw_val};fog2.startEasyLink(param, function(ret, err) {if (ret) {resolve(ret.message)} else {reject(err.message)}});})},stopEasyLink: function() {return new Promise ( function(resolve, reject) {fog2.stopEasyLink(function(ret, err) {if (ret) {console.log(ret.message);resolve(ret.message)} else {console.log(err.message);reject(err.message)}});})},startSearchDevices: function() {return new Promise ( function(resolve, reject) {fog2.startSearchDevices(function(ret, err) {if (ret) {let deviceList = [];if (null != ret.devices && ret.devices.length > 0) {deviceList = ret.devicesresolve(deviceList)}} else {reject(err)}});})},stopSearchDevices: function() {return new Promise ( function(resolve, reject) {fog2.stopSearchDevices(function(ret, err) {if (ret) {resolve(ret)} else {reject(err)}});})},
}
window.easyLinkService = easyLinkService
export default easyLinkService

完成配网并成功发现设备,大功告成

结尾

这篇文章主要是记录这次操作中的思路,以及抓包、改包、反编译等技能的实践操作,真正做到学以致用,将我们所学的知识,运用到实际操作当中去。

记录一次体现前端工具仔综合实力的实际操作相关推荐

  1. 基于客户端用户行为记录的网站可用性分析工具研究

    基于客户端用户行为记录的网站可用性分析工具研究 白文涛 刘正捷 陈军亮 大连海事大学欧盟可用性中国中心 116026 http://usability.dlmu.edu.cn 摘要:如何改善网站的可用 ...

  2. 2022,前端工具链十年盘点

    大家好,我是若川.持续组织了6个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列& ...

  3. 前端工具--less篇

    前端工具–less篇 less 中文网http://www.bootcss.com/p/lesscss/ 常见错误及解决: sublime text 3 安装less2css保存less出现错误 未安 ...

  4. 前端工具:2015年我最喜欢的一些发现

    We're just about at the end of 2015 and I'm sure you'd all agree it's been another year jam-packed w ...

  5. 如何在公司里体现前端的价值以及提升自己的议价能力

    前言 最近在闰土大叔的前端圈里有很多小伙伴南下杭州应聘求职拿OFFER,货比三家之后,最终入职了适合自己的公司,并且还拿到了不错的薪水.在这些小伙伴当中,不乏刚刚大学毕业或者师出培训班的职场萌新,在顺 ...

  6. 50个好用的前端工具,建议收藏!

    来源 | https://www.jianshu.com/p/182b69e54fe8 今天跟你分享一些目前比较热门新鲜度靠前的50款前端工具,希望对你有所帮助. 一.构建工具 1. Parcel 地 ...

  7. 如何在公司里体现前端的价值以及提升自己的议价能力 1

    前言 最近在闰土大叔的前端圈里有很多小伙伴南下杭州应聘求职拿OFFER,货比三家之后,最终入职了适合自己的公司,并且还拿到了不错的薪水.在这些小伙伴当中,不乏刚刚大学毕业或者师出培训班的职场萌新,在顺 ...

  8. 如何在公司里体现前端的价值以及提升自己的议价能力?

    前言 最近在闰土大叔的前端圈里有很多小伙伴南下杭州应聘求职拿OFFER,货比三家之后,最终入职了适合自己的公司,并且还拿到了不错的薪水.在这些小伙伴当中,不乏刚刚大学毕业或者师出培训班的职场萌新,在顺 ...

  9. 记录一次扇贝前端面试经历

    记录一次扇贝前端面试经历 最近在上家公司由于换部门的关系干的不是很舒服,一直想换个环境,于是找时间投了简历,打开招聘软件查找了一番,发现了"扇贝"这家公司,嗯,好熟悉啊,话说他们的 ...

最新文章

  1. k8s 通过环境变量获取Pod信息
  2. 图像转换 之 方形图转化扇形图
  3. SQL内连接和左连接的区别 - 使用SQLite演示
  4. #ifdef ...#else...#endif等条件编译用法
  5. 184使用 Core Image 框架处理照片
  6. sql语句Order by 报错列名不明确
  7. C# 使用TCP创建HTTP客户程序
  8. Android获取手机和系统版本等信息的代码
  9. Java中BigDecimal类型的加减乘除及大小比对
  10. bzoj 4443: [Scoi2015]小凸玩矩阵(二分+二分匹配)
  11. 传统企业信息化的成功案例的一些感想(原创)
  12. dlp型3d打印机_创想三维一台3d打印机是多少钱
  13. 来,亮点抢先看!网易智企机器之心即将联合发布 AI 白皮书
  14. impress.js css模板,使用impress.js制作幻灯片
  15. wr720n刷成网络打印_USB打印机通过路由共享wifi局域网打印,同网段
  16. 解决“attempted relative import with no known parent package“的错误
  17. 数据库性能系列之索引(中)
  18. 二十四节气-冬至,海报/文案分享,一口饺子,一口吉。
  19. 【Solidity】8. 杂项 - 深入理解Solidity
  20. 二、SQLServer 的适配记录

热门文章

  1. 实习面经(网易雷火)
  2. 提供大数据分析服务以及机器学习API的公司
  3. Html5 CSS设置背景图片
  4. 百度AI身份证识别接口开发
  5. MSM平台上的AMSS 概述
  6. PGN(Pointer-Generator Networks)
  7. 基于BERT-PGN模型的中文新闻文本自动摘要生成——文本摘要生成(论文研读)
  8. 效率神奇,这是最好用的电子笔记工具
  9. 【Linux】磁盘分区常用方案
  10. python3 微博群关注 自动发群消息