首页
论坛
课程
招聘
[原创]CAJViewer7.0中OCR功能的提取
2008-5-16 12:01 21171

[原创]CAJViewer7.0中OCR功能的提取

2008-5-16 12:01
21171
【文章标题】: CAJViewer7.0中OCR功能的提取
【文章作者】: yfliu
【作者邮箱】: 80600414@qq.com
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  CAJViewer7.0中的文字识别功能相当强大,识别准确率很高,但该功能只局限在CAJViewer7.0能打开的有限的几种格式(nh,kdh,ceb,pdf)中,并不能直接用于识别图片。本文描述了一种方法,将OCR功能从CAJViewer7.0中剥离出来,独成一体。
  工具:ida,syser debug,filemon, CAJViewer 7.0.1.sfx

  一.为什么开始动手做
  一直认为caj的ocr功能很强大,以前一直没做这件事是因为我以为他是同方自己开发的系统,和caj融为一体,提取难度较大。
  今天偶然发现在caj的目录下有个ocr目录,里面有一个exe和若干dll文件,便猜想ocr功能只是caj的一个插件,既然是插件,难度就小多了。

  二.首先想到的:ocr以dll的方式向caj提供服务。
  用ida检查导入表,有LoadLibraryA,查看对该函数的引用,从加载的文件名和代码来看,并不是在加载ocr相关的代码,全是加载caj的文件。排除了这种可能

  三.ocr以单独的进程完成识别,然后将识别结果以某种方式传回caj。
  观察到:每当我使用ocr功能时,在任务管理器中总会多出一个THOCRecog的进程,然后很快地又消失了。

  四.
  既然是通过单独的进程来处理,完成后进程消失,那么程序得调用CreateProcess了。
  打开ida发现了很多对CreateProcessA的调用
  对于在ida中的每一个对CreateProcessA的调用:1.如果根据lpCommandLine或lpApplicationName不能判断出在创建ocr相关的进程。则2.记下它的虚拟地址,在syser中下断点。如:
  .text:004295FC                 add     esp, 28h
  .text:004295FF                 lea     eax, [ebp+3DCh+hObject]
  .text:00429602                 push    eax             ; lpProcessInformation
  .text:00429603                 lea     eax, [ebp+3DCh+StartupInfo]
  .text:00429606                 push    eax             ; lpStartupInfo
  .text:00429607                 push    esi             ; lpCurrentDirectory
  .text:00429608                 push    esi             ; lpEnvironment
  .text:00429609                 push    8000000h        ; dwCreationFlags
  .text:0042960E                 push    esi             ; bInheritHandles
  .text:0042960F                 push    esi             ; lpThreadAttributes
  .text:00429610                 push    esi             ; lpProcessAttributes
  .text:00429611                 lea     eax, [ebp+3DCh+CommandLine]
  .text:00429614                 push    eax             ; lpCommandLine
  .text:00429615                 push    esi             ; lpApplicationName
  .text:00429616                 call    ds:CreateProcessA ; 
  根据上下文是不能判断是否在创建ocr相关进程的。
  在syser中切换到caj的空间,对429616下断点,然后查看lpCommandLine,即eax
   
  在最上面就是内存窗口,在右上面显示就是lpCommandLine的值,可以看出这个CreateProcess函数在创建ocr相关进程。
  还可以知道,caj根据用户选择的区域,临时生成了一张bmp图像,然后传给ocr处理。
  .text:00429615                 push    esi             ; lpApplicationName
  .text:00429616                 call    ds:CreateProcessA ; 
  .text:0042961C                 test    eax, eax
  .text:0042961E                 jnz     short loc_42962F
  .text:0042961E
  .text:00429620                 push    offset ValueName
  .text:00429625                 mov     ecx, edi
  .text:00429627                 call    ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(char const *)
  .text:0042962D                 jmp     short loc_42965E
  .text:0042962D
  .text:0042962F ; ---------------------------------------------------------------------------
  .text:0042962F
  .text:0042962F loc_42962F:                             ; CODE XREF: sub_429581+9D j
  .text:0042962F                 push    0FFFFFFFFh      ; dwMilliseconds
  .text:00429631                 push    [ebp+3DCh+hObject] ; hHandle
  .text:00429634                 call    ds:WaitForSingleObject
  .text:0042963A                 lea     eax, [ebp+3DCh+ExitCode]
  .text:0042963D                 push    eax             ; lpExitCode
  .text:0042963E                 push    [ebp+3DCh+hObject] ; hProcess
  .text:00429641                 call    ds:GetExitCodeProcess
  .text:00429647                 push    [ebp+3DCh+hObject] ; hObject
  .text:0042964A                 mov     esi, ds:CloseHandle
  .text:00429650                 call    esi ; CloseHandle
  .text:00429652                 push    dword ptr [ebp-38h] ; hObject
  .text:00429655                 call    esi ; CloseHandle
  .text:00429657                 push    edi
  .text:00429658                 call    sub_4294E6
  继续观察CreateProcess后的操作:程序将新创建的句柄传递给WaitForSingleObject,这个函数等待新创建的进程结束;然后程序调用一个过程sub_4294E6。
  这个过程主要是对系统的剪切板操作:
  .text:004294E6 sub_4294E6      proc near               ; CODE XREF: sub_429581+D7 p
  .text:004294E6                 mov     eax, offset loc_450FAF
  .text:004294EB                 call    __EH_prolog
  .text:004294EB
  .text:004294F0                 push    ecx
  .text:004294F1                 and     dword ptr [ebp-10h], 0
  .text:004294F5                 push    esi
  .text:004294F6                 lea     ecx, [ebp-10h]
  .text:004294F9                 call    ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
  .text:004294FF                 and     dword ptr [ebp-4], 0
  .text:00429503                 push    offset szFormat ; "THOCR_FMT"
  .text:00429508                 call    ds:RegisterClipboardFormatA
  .text:0042950E                 push    0               ; hWndNewOwner
  .text:00429510                 mov     esi, eax
  .text:00429512                 call    ds:OpenClipboard
  .text:00429518                 test    eax, eax
  .text:0042951A                 jnz     short loc_42952C
  .text:0042951A
  .text:0042951C                 mov     ecx, [ebp+8]
  .text:0042951F                 push    offset ValueName
  .text:00429524                 call    ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(char const *)
  .text:0042952A                 jmp     short loc_429568
  .text:0042952A
  .text:0042952C ; ---------------------------------------------------------------------------
  .text:0042952C
  .text:0042952C loc_42952C:                             ; CODE XREF: sub_4294E6+34 j
  .text:0042952C                 push    esi             ; uFormat
  .text:0042952D                 call    ds:GetClipboardData
  .text:00429533                 mov     esi, eax
  .text:00429535                 test    esi, esi
  .text:00429537                 jz      short loc_429555
  .text:00429537
  .text:00429539                 push    esi             ; hMem
  .text:0042953A                 call    ds:GlobalLock
  .text:00429540                 test    eax, eax
  .text:00429542                 jz      short loc_429555
  .text:00429542
  .text:00429544                 push    eax
  .text:00429545                 lea     ecx, [ebp-10h]
  .text:00429548                 call    ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::operator=(char const *)
  .text:0042954E                 push    esi             ; hMem
  .text:0042954F                 call    ds:GlobalUnlock
  .text:0042954F
  .text:00429555
  .text:00429555 loc_429555:                             ; CODE XREF: sub_4294E6+51 j
  .text:00429555                                         ; sub_4294E6+5C j
  .text:00429555                 call    ds:CloseClipboard
  小结一下caj的处理过程:
  1.caj通过CreateProcessA创建一个进程,THOCRecog
  2.caj调用WaitForSingleObject,等待THOCRecog处理完成,THOCRecog将处理结果放在系统剪切板中
  3.caj调用GetClipboardData从系统剪切板获得数据
  4.caj通过一些mfc的字符串函数解析第3步取得的数据

  五.明白了caj的处理过程,怎么利用?
  1.给THOCRecog传递一个图片的路径
  2.待THOCRecog处理完后从系统剪切板取回数据。
  还有两个问题:
  1. THOCRecog会判断它的父进程是否为caj吗?如果不是caj调用它,它还能工作吗?
  2.系统剪切板中数据的格式的解析方式是什么?

  六 .解决上面两个问题------ THOCRecog的运行流程
  在命令行方式下直接启动THOCRecog,后跟一个图片文件路径,通过filemon发现THOCRecog同样会在图片路径创建一些文件,但是很快又删除了,怀疑这就是THOCRecog处理的结果。
  如果我跳开THOCRecog中的删除文件的函数,就可以查看这些文件的内容。
  找到THOCRecog中对DeleteFileA引用的部分。
  .text:00401313 loc_401313:                             ; CODE XREF: sub_4010B0+1FD j
  .text:00401313                                         ; sub_4010B0+207 j
  .text:00401313                 mov     edx, [ebp+lpFileName]
  .text:00401316                 mov     esi, ds:DeleteFileA
  .text:0040131C                 push    edx             ; lpFileName
  .text:0040131D                 call    esi ; DeleteFileA
  将00401313处的代码改为retn。
  观察图片目录,多了4个文件,其中一个和图片同名的txt中存放了识别的结果。
  上面的处理达到了效果,但是显得很暴力。
  分析该DeleteFileA 所在的函数,可以推测THOCRecog大概的过程:
  1.根据传入bmp文件路径,THOCRecog分析该文件,将分析结果存在图片目录,与图片文件同名的txt文件中。
  2. THOCRecog读取该txt文件并把读取的内存规格为与caj约定的格式。
  3. THOCRecog将已经规格化的内容存在系统剪切板中。
  4. THOCRecog删除txt等图片目录下的4个文件。结束进程。

  七.怎么利用
  我对mfc不熟悉,没法逆向解析剪切板数据的相关过程,所以采取下面方法
  .text:00401207                 test    eax, eax
  .text:00401209                 jz      short loc_401214
  .text:00401209
  .text:0040120B                 mov     byte ptr [ebp+var_4], 9
  .text:0040120F                 jmp     loc_40135C
  .text:0040120F
  .text:00401214 ; ---------------------------------------------------------------------------
  .text:00401214
  .text:00401214 loc_401214:                             ; CODE XREF: sub_4010B0+159 j
  .text:00401214                 call    sub_401710
  将.text:00401209                 jz      short loc_401214改为nop可以直接跳过上面的4个过程
  然后用自己的程序读取数据,删除文件…
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年05月16日 11:50:48

恭喜ID[飞翔的猫咪]获看雪安卓应用安全能力认证高级安全工程师!!

收藏
点赞0
打赏
分享
最新回复 (9)
雪    币: 243
活跃值: 活跃值 (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
amour 活跃值 2008-5-17 08:58
2
0
非常强大!学习之
雪    币: 38
活跃值: 活跃值 (363)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cd37ycs 活跃值 2008-5-17 09:35
3
0
非常强大!!!
雪    币: 522
活跃值: 活跃值 (176)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
笨笨雄 活跃值 14 2008-5-18 02:14
4
0
强悍.............
雪    币: 219
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Lancia 活跃值 2008-5-18 06:15
5
0
学习之
雪    币: 232
活跃值: 活跃值 (12)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
firefly 活跃值 4 2008-5-18 09:23
6
0
很有用的教程。
雪    币: 215
活跃值: 活跃值 (11)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
edisonH 活跃值 3 2008-5-18 18:43
7
0
很好
不过还有很多事情要做  文章只是简单的分析了 caj传入什么样命令行参数给ocr和 ocr关于txt文件删除的流程

其实这个ocr不用nop掉删除文件txt那一段 ,再跟深入一点点就可以写代码学caj怎么从剪切板中把内容考出来了
00429503    68 30F14500     push    0045F130                         ; ASCII "THOCR_FMT"
00429508    FF15 B0514500   call    dword ptr [<&USER32.RegisterClip>; USER32.RegisterWindowMessageA
......
0042952C    56              push    esi         ; 
0042952D    FF15 28524500   call    dword ptr [<&USER32.GetClipboard>; USER32.GetClipboardData



还有 这个ocr对传入的bmp文件是有要求的,否则ocr不会转换的  比如 bmp每英寸像素必须为8*8

如果不把这些东西搞清楚   就只能转转caj自己截的图   难免有鸡肋嫌疑
雪    币: 25154
活跃值: 活跃值 (3296)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
风间仁 活跃值 19 2008-5-19 01:14
8
0
好邪恶~~学习
雪    币: 241
活跃值: 活跃值 (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
xiaojiam 活跃值 2 2008-6-5 21:24
9
0
收藏起来 慢慢研究
雪    币: 326
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 活跃值 4 2008-6-6 00:13
10
0
我不得不说你太有才了
试验结果:
1.bmp,为了上传转为png


ocr后:

本书以实用统计学为出发点,全面介绍了Excel 2002在数据处理和
统计分析方而的A级应用。全书分卜下两篇,上篇Excel 21YJ2高级应用.
详细介胡了Excel 2M2的数据处理、图表、内部数据库、透视表、假设
分析工兵等高级功能;卜篇Excel 2002统计分析,在简洁规范地M述概
书统计基本理论的恭础于_,系统讲述了数字特征、概率分布、统计估值和
检!!y ,回归分析和 R测以及方差分析等实用统计学课题在Excel 20112山
的解决方法
本书的主要特点是理论阐述匀实例说Or.相结合、统计学原理与软件
应用相结介。
本书适用十各类商务、政务办公环境中从亨数拐处理和统计分析的
上作人比也可伪为各类高等i;t校和职业教育概率统计课程的参考书

上传的附件:
  • 1.PNG (28.54kb,205次下载)
游客
登录 | 注册 方可回帖
返回