解密SuperWebview的一种另类方法
解密SuperWebview的一种另类方法
什么是SuperWebview
SuperWebview是APICloud官方推出的另一项重量级API生态产品,以SDK方式提供,致力于提升和改善移动设备Webview体验差的整套解决方案。APP通过嵌入SuperWebview替代系统Webview,即可在HTML5中使用APICloud平台现有的所有端API,以及包括增量更新、版本管理、数据云、推送云、统计分析、积木式模块化开发、所有已经聚合的开方平台服务等在内的云服务能力,增强用户体验,解决移动设备Webview使用过程中出现的兼容能力弱、加载速度慢、功能缺陷等任何问题,帮助开发者解决使用Webview过程中的所有痛点。
SuperWebview继承APICloud终端引擎的包括跨平台能力,模块扩展机制,生命周期管理,窗口系统,事件模型,APP级别的用户体验等在内的所有优秀能力,并且全面打通html5与android和iOS之间的交互,同步提供APICloud平台最新的API技术能力和服务,APICloud团队将保持对SuperWebview的持续更新和优化,兼容Html5的新特性,持续推出优质服务。
-----要弄别人,总得知道别人是谁。
总结来说有三点:
- 安卓原生Webview的扩展
- 结合native app 和 web app
- APICloud实现安卓框架,自己开发web
上个图,一目了然:
SuperWebview的安全措施
全包加密
- 网页全包加密:对网页中全包的html,css,javascript代码进行加密,加密后的网友代码都是不可读的,并且不能通过常用的格式化工具恢复。代码在运行前都是加密的,在运行时进行动态解密。
- 一键加密、运行时解密 在开发过程中无需对代码做任何特殊处理,在云编译时选择代码加密即可。
- 零修改、零影响 加密后不改变代码的大小,不影响运行效率。
- 安全盒子 定义了一个安全盒子,在盒子内的代码按照加密和解密进行处理,其他代码不受影响。
- 重新定义资源标准 对保护的代码进行统一资源管理,加速资源加载,加速代码运行。
为什么要去解密
使用SuperWebview,安卓app基本上就是框架,一般的核心代码都放在web中。最近遇到一个灰色的软件,需要利用其中的一些东西。经过大半个星期的逆向,最终确定核心代码在web里。
上点直观的东西
加密后的文件
如图:云端加密,本地运行时解密
解密后的文件
如图:对于一个web app来说,这就是核心代码
如果要做,HOW?
准备工作
- 目标安卓app(最好没有加固,有加固的需要脱壳。vmp的搞不定。)
- 一台root的手机
- 安装xposed框架
- 安卓开发环境(Android Studio)
原理概述
由于SuperWebview要兼容原生的Webview(或者说由其派生而来),所以这决定了web的代码必须要符合规范,即:必须是能让浏览器引擎识别的有效代码。很明白,在引擎中执行的都是明文。所以一下就找到一个核心点:怎么样从Webview中dump出代码。不论百度还是google都能找到方法。可以先看看这篇博客。
简单来说有4步:
- 开启SuperWebview/Webview的JavaScript功能
- 自定义本地JavaScript的接口
- 向网页中添加自定义接口
- 调用js,实现dump网页
具体操作
开启JavaScript支持功能
一般来说,使用SuperWebview的app有99%的都开启了这个功能的。可以使用jadx打开app,全包搜索setJavaScriptEnabled函数,如果不放心,可以在找到的地方通过xposed再调用一次。
webView.getSettings().setJavaScriptEnabled(true);
搜索setJavaScriptEnabled函数
自定义JavaScript接口
注意添加@JavascriptInterface声明
/*
原因:only public methods that are annotated with
{@link android.webkit.JavascriptInterface} can be accessed
from JavaScript.
*/
import android.webkit.JavascriptInterface; final class LocalJavaScript {
@JavascriptInterface
public String dumpSource(String html) {
return html;
}
}
向网页中添加自定义接口
这一步很关键,需要额外说明一下。先看看addJavascriptInterface函数的注释,其中有这样一句:
Note that injected objects will not appear in JavaScript until the page is next (re)loaded.
意思是这次加载的JavaScript代码要重载页面的时候才会生效。所以调用webView.addJavascriptInterface的时机就很重要,如果太迟则会导致后面的webView.loadUrl执行实效(因为没有添加上本地的接口):
webView.addJavascriptInterface(new JsObject(), "injectedObject");
webView.loadData("", "text/html", null);
webView.loadUrl("javascript:alert(injectedObject.toString())");怎样确定addJavascriptInterface函数调用的时机呢?
好简单。因为SuperWebview一定会调用这个接口的(框架决定的),利用jadx定位到该方法所在的函数,hook该函数再调用addJavascriptInterface就行了。
对于SuperWebview,一般是在
com.uzmap.pkg.uzcore.uzmodule.b
包中的public void a(boolean r, String d)函数里调用:webView.addJavascriptInterface(new LocalJavaScript(),"dump_html");
搜索addJavascriptInterface函数:
注入JS代码,dump页面
对于SuperWebview,一般是在
com.uzmap.pkg.uzcore.x
包中的public void onPageFinished(WebView view, String url)函数里调用:
webView.loadUrl("javascript:alert(dump_html.dumpSource(''+document.getElementsByTagName('html')[0].innerHTML+''))");
```
代码执行效果:
写xposed代码的tips
如果需要hook的函数里有自定义类型怎么办?
加载该类,然后作为参数传递:
Class<?> UZWebView =null;
UZWebView =lpparam.classLoader.loadClass("com.uzmap.pkg.uzcore.UZWebView");
* 如何获取对象的成员属性?
通过反射调用:
```java
// 获取实例对象
Class clazz = param.thisObject.getClass();
// 获取类成员属性
Field field = clazz.getDeclaredField("a");
field.setAccessible(true);
// 获取指定对象的成员属性
WebView webView = (WebView) field.get(param.thisObject);
// 调用该对象的方法
webView.addJavascriptInterface(new InJavaScriptLocalObj(), "dump_html");
```
注1:如果成员属性是自定类型的,暂时还不知道该怎么办。在此向大神们请教。谢谢。
注2:如果hook的是静态方法,是不能获取到对象的属性的。
* 如何调用对象的方法?
通过反射调用:只能调用对象实现的方法,如果该方法在本类中没有实现(如调用父类的方法),则无法成功
```java
// 获取实例对象---也有可能是从参数获取,如param.args[0]
Class clazz = param.thisObject.getClass();
// 如果类有该方法就可以用反射调用的方式
Method c = a.getClass().getDeclaredMethod("c", int.class);
c.invoke(a,12);
```
* 如何hook函数?
hook构造函数使用:**findAndHookConstructor**
```java
findAndHookConstructor(className,
lpparam.classLoader,
param,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//do something
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//do something
}
}
);
```
hook一般函数使用:**findAndHookMethod**
```java
findAndHookMethod(className,
lpparam.classLoader,
methods,
param,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// do somethin
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// do somethin
}
});
```
* 如何查看调用流程?
抛出异常,打印调用栈:
```java
String exceptionName = "whatever";
new Exception(exceptionName).printStackTrace();
XposedBridge.log(new Exception(exceptionName));
```
## 总结
诚然通过这种方式是无法获取到所有的解密文件的。例如html里面加载的js脚本,css文件。我也曾想通过注入js的方法来获取加载的js文件,但并未成功。
诚然最简单的方法还是去逆向SuperWebview,找到核心函数,可以获取到所有的解密文件。
诚然这个过程并没有帮助我达到最终的目的,可它还是很有趣。
目的不是想教大家怎么去逆向别人的产品,只是在研究学习的过程中发现了一些有趣好玩的iead。特别想将这个idea分享一下。无他。
当然,对于这款灰色的软件,最终还是达到了最初的目的。只是并非使用了如此手段。
## 后记
技术的道路看不到尽头。或者只身一人,或者三五成群,有时狂奔,有时懒散。我们终究停不下这个脚步,逢山翻山,遇水淌水。也许那里也有一片天,一片地。保持初心,勇敢前行。
解密SuperWebview的一种另类方法的更多相关文章
- 一种另类的解决URL中文乱码问题--对中文进行加密、解密处理
情景:在资源调度中,首先用户需要选择工作目标,然后跟据选择的工作目标不同而选择不同的账号和代理ip.处理过程如下:点击选择账号,在js中获取工作目标对工作目标进行两次编码(encodeURI(enco ...
- Linux下几种另类创建文件之方法
以前我们用编辑器例如vi来新建文件,下面介绍几种另类生成文件的方法,多用在备份和测试上. 创建文件的方法: 1.echo 命令 #echo "set bell" >& ...
- 另类方法解决设计Web页面出现:Error Creating Control
在B/S开发的过程中,经常会遇到这样的提示:Error Creating Control ,而这些页面明明之前是可以打开的,但还是出现如下图所示: 网上找到的方法是把控件初始化放在OnInit里去写, ...
- 解决 SQL 注入的另类方法
本文是翻译,版权归原作者所有 原文地址(original source):https://bitcoinrevolt.wordpress.com/2016/03/08/solving-the-prob ...
- iOS 几种加密方法
iOS常见的几种加密方法 普通加密方法是讲密码进行加密后保存到用户偏好设置中 钥匙串是以明文形式保存,但是不知道存放的具体位置 1.base64加密 base64 编码是现代密码学的基础 基本原理: ...
- BurpSuite+SQLmap的一种另类扫描
过年之后就忙的团团转.三月开始可以轻松一些,抽空写写最近瞎折腾的东西,本文只是描述工具的一种使用方法,无技术含量.(PS:这种做法,网上也有很多教程,本文只为记录). 由于公司使用的电脑都是win10 ...
- 精简Docker镜像的五种通用方法
http://dockone.io/article/8163 精简Docker镜像的好处很多,不仅可以节省存储空间和带宽,还能减少安全隐患.优化镜像大小的手段多种多样,因服务所使用的基础开发语言不同而 ...
- Python爬虫突破封禁的6种常见方法
转 Python爬虫突破封禁的6种常见方法 2016年08月17日 22:36:59 阅读数:37936 在互联网上进行自动数据采集(抓取)这件事和互联网存在的时间差不多一样长.今天大众好像更倾向于用 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
随机推荐
- Linux中批量添加文件和修改文件小笔记
1.#使用通配符批量创建5个文件 $ touch file{1..10}.txt 2.#批量修改这五个后缀名为.txt的文本文件名重命名为.c后缀名结尾的文件 $ rename 's/\.txt/\. ...
- FTP中MLST概要解读---解决获取ftpFile为null的另外一种方式
零.引言 之前写FTP工具库,用的是ftp4j,他使用其他非常简单方便,但是在细节上提供的可选项比较少(当然也可能是我了解不够深刻) 最新的项目重写了FTP工具类,选择了apache net中的ftp ...
- 微信小程序框架
框架 小程序开发框架的目标是通过尽可能简单.高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务. 框架提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的 ...
- Web测试到底是在测什么(资料合集)
开始今晚的主题之前 先来看一张图, 这是老徐16年10月份,线上Web主题分享时整理的大纲 图片略模糊 看得清就好 Web测试, 进行抽离拆分,基本上就如上一些内容. 不管是测什么系统,什么功能,基本 ...
- js原型链部分详细使用说明案例
1. 'index.html'文件 ```html <!DOCTYPE html> <html lang="en"> <head> <me ...
- 数值类型中JDk的编译期检查和编译期优化
byte b1 = 5;//编译期检查,判断是否在byte范围内 byte b2 = 5+4;//编译期优化,相当于b2=9 byte b3 = 127;//编译通过,在byte范围内 byte b4 ...
- Sqlla: 数据库操作从未如此简单
Sqlla 一套数据库的 ORM 微型库,提供简单高效的 API 来操作数据库. Sqlla 拥有极少的API,使用方式简单.让开发者不需要关心数据库操作的具体细节,只需专注SQL和业务逻辑.同时简单 ...
- JSP servlet的配置与使用
1. servlet 的配置文件内容如下所示 <servlet> <description>This is the description of my J2EE com ...
- 在微信小程序中学习flex布局
网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就 ...
- 刨根究底字符编码之四——EASCII及ISO 8859字符编码方案
EASCII及ISO 8859字符编码方案 1. 计算机出现之后,从美国发展到欧洲,由于欧洲很多国家中所用到的字符中,除了基本的美国也用的那128个ASCII字符之外,还有很多衍生的拉丁字母等字符 ...