本帖最后由 ahxhs 于 2023-12-02 09:06 编辑
背景介绍网址:aHR0cHM6Ly93d3cuZG9jODguY29tLw== 某文档网站使用加密的文件格式渲染文字,清晰度极高,且可以选中,故猜测数据包中含有文字信息。 可以看到当页面渲染完毕后是一个单纯的canvas画布 
删除网络记录,进入下一个页面,查看调用的包,可以看到ebt格式的请求 
关键js为wmu.js 调试过程进入wmu.js,共5610行,给发送ebt请求的位置下一个断点 
断住后可以看到作用域里_kY即是网址位置,搜索定位该位置,可以看到发送请求函数 
可以看到,接下来请求获取的response被扔进了一个二进制object Blob,这一段在node里直接用fs库即可,_6H又被放进了_q1[0]里,追_q1即可 
可以看到new了一个FileReader对象,FileReader需要先readAsXXX才能onload,所以继续往下搜索,可以看到就是_6H而已,赋值了个寂寞。 
接下来是一段参数的赋值,但是_I8并未定义 
搜索发现是前面的_k1 == "initHeader"才会触发的一段初始代码,好吧,下断点,重新刷新页面。 
不难发现,其实这儿的代码差别不大,应该是一段初始时的代码,那我们先看这一段就可以了。 
可以看到,这里需要Module._malloc,我也不会wasm,所以前面所有生成函数都给扣到js里了,1100多行,还好。 载入wasm的地方看一下,后面全是。 那只能全扣进去了,最终还是把5000多行代码扔到了js里。不过wasm文件加载的地方肯定要换成自己的本地文件。 
下个断点,看看他是如何载入wasm的,其实都是标准的wasm引入流程,自带nodejs环境的加载,那我直接把文件地址改成wmu.wasm即可 
运行发现有一个H5的api,postMessage,随便定义一个console.log先试试,发现成功运行初始化 
那么继续扣init里的代码,先看看能不能成功生成_wC,发现没有什么问题 
涉及到postmessage地方都不管,是js间通信用的,主要初始化数据就是这两个,扣进代码 

我们来整体看看这段调用到底在做什么? 
initHeader和后续多个getPage对应的内容即为总的一个ebt后其他分页ebt 

代码编写首先,构造initHeader函数,用于初始化初始ebt

然后构造getPage函数,用于获取后续文字,其中_H0是当前页码 
然后简单的合并以下看看。 
成功获取当页文字。 总结其实没有什么混淆之内的,写的很清晰,主要是我不懂wasm这一类东西,之前几个网站涉及wasm都直接尝试找到wasm调用失败时的js加密代码(很有效)。 问题与展望1.这里面的函数都是异步,包括扣下来的createWasm,套了不少异步.then来初始化wasm。但是python execjs调用js似乎不能等待异步完成。如何解决这一问题呢?之前我写的都是在最后一个.then开一个端口,写了一个简单的网络接口来与python传递信息,虽然能用但不是什么好方法,如何做呢。 2.现在的文字有些乱,因为网页生成画布同时利用了ebt中的文字和文字位置信息,是否可以利用生成的文字和文字位置,生成可复制pdf。
注:若转载请注明大神论坛来源(本贴地址)与作者信息。
|