扫描全能王文档矫正逆向记录

2023-10-23 00:50

本文主要是介绍扫描全能王文档矫正逆向记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

扫描全能王有个功能是将弯曲的文本拉直成平直的文本。在扫描全能王的app上,这个功能的入口在拍书籍的tab。同时在图片编辑页面,也有个按钮可以触发这个功能。它的效果大概如下。

在这里插入图片描述

这篇文章主要介绍如何逆向这个算法

初步定位

对扫描王apk初步逆向之后,发现破解难度有点大。大概有这几个问题

在这里插入图片描述

  • 扫描全能王apk经过爱加密加过壳,ida动态破解难度大,基本一开始挂调试就触发反调试机制
  • 文档矫正算法有两套,其中纯C++实现的算法复杂度极高

加壳的处理直接导致很多逆向手段用不了。而复杂的纯CV又导致还原算法基本不可能。

好在多次尝试之后,发现扫描全能王还有个模型矫正的算法。

模型矫正逆向

扫描全能王在6.0版本之后增加了一个矫正函数。在6.0之前的矫正函数名都是 dewarpXXX,在6.0之后多了一个dewarpXXXNew。比如这个,接受的是一个图片的指针参数。

dewarpImgPtrNew

用ida静态分析该函数之后发现,它使用的是基于MNN推理引擎的模型。
这个模型实现了端到端的图像矫正,而且效果跟传统算法的矫正结果差不多。

把逆向目标定位在这个函数上,难度会小很多。所需要做的事情大概是:

  • 梳理模型矫正的输入数据预处理和后处理
  • dump模型出来
  • 还原矫正流程

逆向模型矫正的好处之一是只要拿到了模型,就成功了一半。

dump模型

虽然扫描全能王把模型以二进制方式打包进了so库,但是没有很好地对二进制数据进行加密。在花了一些时间分析之后,就用ida将模型dump出来了
在这里插入图片描述
初步分析这个模型之后,不得不说扫描全能王的算法团队有点东西。他们用同一个分割网络实现了边缘检测,阴影检测,文档矫正。而这个模型的大小才1M不到。

分析前后处理

预处理的分析比较简单。我构造了模型矫正的上下文环境,通过hook的方式让矫正流程强制走了模型矫正。

    1. int val = initDewarpContext()//初始化引擎2. ScannerEngine.dewarpImgPtrNew(val, ptr)//处理数据3. ScannerEngine.releaseContext(val)//释放引擎

在进入了模型矫正调用之后,还需要hook一些关键函数。
比如,我需要知道输入图像缩放到什么尺寸,它的归一化参数是多少。

而这些需要对so进行静态分析后才能找到合适的hook位置。
举例来说,输入到模型的图像缩放的尺寸,我用这个frida函数实现

Interceptor.attach(resize, {onEnter: function(args) {if(dewarpProcessDone != 1) return;if(Process.getCurrentThreadId() != threadId) return;console.log('\n[-] resize, thread: ', Process.getCurrentThreadId());console.log("[-] resize args[0] - args[4]: ", args[0], args[1], args[2], args[3], args[4]);console.log("[-] resize src size: ", ptr(args[0]).add(4).readPointer(), " \n    src size:", ptr(args[0]).add(4).readPointer().add(8).readInt(), "-", ptr(args[0]).add(4).readPointer().add(12).readInt());console.log("[-] resize dst size: ", ptr(args[2]), " \n    dst size:", ptr(args[2]).readInt(), "-", ptr(args[2]).add(4).readInt());console.log('    args[2]:\n', Memory.readByteArray(ptr(args[2]), 16));console.log('    flag:\n', Memory.readByteArray(ptr(args[0]).add(0x4).readPointer(), 16));

这里涉及到二进制分析,还有对数据结构的了解。展开讲比较复杂,都可以单独开一篇了。总之在分析后知道,模型的输入是240x240。

有些人可能会问,啊模型输入不是看模型文件就知道吗?这个不行,它的MNN文件看不到输入尺寸信息。

预处理的流程不多,解决了输入尺寸,就完成了一大半。

真正难的是后处理的分析

看后处理的代码,至少包含几个步骤。

  1. 输出数据高斯模糊
  2. 平滑处理
  3. 放大插值
  4. 原图映射

光是这几个流程的还原,就花了我小一个月时间。

还原矫正流程

最后还原出来的结果大概是这样:
在这里插入图片描述
扫描全能王的模型矫正,其实是一种位移场矫正算法。
这里我在中间的图用绿色的网格将位移场表示出来,会比较直观。

  • 左边是原图,首先将模型缩放到240x240的尺寸,送进模型
  • 模型会检测图像的曲率,得到一系列离散的曲率值。将这些曲率值连起来,就是中间图的绿色网格
  • 在得到了曲率值之后,将原图的像素一一映射到新的图片,得到最右边的图

位移场矫正的思路大概是这样:

  • 假设有一张平直的图像文档,像最右边的
  • 将它以某种程度扭曲,这种扭曲必须是连续的,不是离散的。那么描述这种扭曲的就是一种位移场
  • 将原图的所有像素,按照这个位移场进行映射,就能得到一张扭曲后的图

可以看到位移场矫正算法,它是一种自然位移的逆运算。能想到这个方案的算法师有点东西,而且这个方案值钱的地方在于需要大量接近真实的数据标注。
目前还不知道这些数据是怎么标注的,如果用Blender造数据,会和真实样张有出入。用真实样张进行标注,又是天量的工作时间。

最后

整个逆向大概花了两三个月时间。最后我用C++还原了这个位移场矫正算法。上面的绿色网格图,就是在还原出来的算法代码上添加的。它其实是逆运算。

简单讲,矫正模型输出的是扭曲->原图的位移数据,我称之为逆位移场。如果将这些数据可视化的话,会不好理解。

我在逆向出来的代码上,将模型的输出数据反向计算,得到一个正的位移场,再将这个位移场套到一个标准的网格上,就能看出来原图是经过怎样的一个扭曲空间,变成一张扭曲过的图的。

这篇关于扫描全能王文档矫正逆向记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/264666

相关文章

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事

Maven项目中集成数据库文档生成工具的操作步骤

《Maven项目中集成数据库文档生成工具的操作步骤》在Maven项目中,可以通过集成数据库文档生成工具来自动生成数据库文档,本文为大家整理了使用screw-maven-plugin(推荐)的完... 目录1. 添加插件配置到 pom.XML2. 配置数据库信息3. 执行生成命令4. 高级配置选项5. 注意事

SpringBoot实现文件记录日志及日志文件自动归档和压缩

《SpringBoot实现文件记录日志及日志文件自动归档和压缩》Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logbac... 目录1、什么是Logback2、SpringBoot实现文件记录日志,日志文件自动归档和压缩2.1、

qtcreater配置opencv遇到的坑及实践记录

《qtcreater配置opencv遇到的坑及实践记录》我配置opencv不管是按照网上的教程还是deepseek发现都有些问题,下面是我的配置方法以及实践成功的心得,感兴趣的朋友跟随小编一起看看吧... 目录电脑环境下载环境变量配置qmake加入外部库测试配置我配置opencv不管是按照网上的教程还是de

Python使用python-docx实现自动化处理Word文档

《Python使用python-docx实现自动化处理Word文档》这篇文章主要为大家展示了Python如何通过代码实现段落样式复制,HTML表格转Word表格以及动态生成可定制化模板的功能,感兴趣的... 目录一、引言二、核心功能模块解析1. 段落样式与图片复制2. html表格转Word表格3. 模板生

使用nohup和--remove-source-files在后台运行rsync并记录日志方式

《使用nohup和--remove-source-files在后台运行rsync并记录日志方式》:本文主要介绍使用nohup和--remove-source-files在后台运行rsync并记录日... 目录一、什么是 --remove-source-files?二、示例命令三、命令详解1. nohup2.

MyBatisX逆向工程的实现示例

《MyBatisX逆向工程的实现示例》本文主要介绍了MyBatisX逆向工程的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录逆向工程准备好数据库、表安装MyBATisX插件项目连接数据库引入依赖pom.XML生成实体类、

浅谈Redis Key 命名规范文档

《浅谈RedisKey命名规范文档》本文介绍了Redis键名命名规范,包括命名格式、具体规范、数据类型扩展命名、时间敏感型键名、规范总结以及实际应用示例,感兴趣的可以了解一下... 目录1. 命名格式格式模板:示例:2. 具体规范2.1 小写命名2.2 使用冒号分隔层级2.3 标识符命名3. 数据类型扩展命

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl