音乐猫 | 男人是这样炼成的.

* 温暖,是字里行间的灰,累了想读懂你的人,娱乐了路过的人。

年底真忙,CHM的破解算法及工具下载

2010年1月20日 | 分类:编程尝鲜 | 评论:1 | 引用:0 | 浏览: | Tags:编程  
1.
年底真忙。

2.
晚上忘了带钥匙回家。
手机还没电自动关机了。
于是在路边公共电话上拨打能记得住的电话号码求助,不得。
买了6个咸鸭蛋,准备回宿舍一脚踹门而入。
想想饿了,遂先去lxs食堂吃了点饭,准备吃饱才能回去飞腿。
辗转找物业撬锁的时候,得知原本有备用钥匙在lxs。
我日,看来想啥时候来偷窥都行。
于是总算是能进屋了。


3.
晚上研究网店编程,想找个chm破解工具,发现基本都收费,而且破解效果不理想。
遂研究了一下hh.exe反编译CHM的算法,逐渐得到了意外收获。

先看cmdline的判断算法

010016BE . 8038 22 cmp byte ptr [eax], 22 ; cmdline是否有“"”
010016C1 . 75 2F jnz short 010016F2 ; 不是就闪
010016C3 > 40 inc eax ; 下一位
010016C4 . 8945 E0 mov dword ptr [ebp-20], eax
010016C7 . 8A08 mov cl, byte ptr [eax]
010016C9 . 3ACB cmp cl, bl ; bl=0 检测参数是否结束
010016CB . 74 05 je short 010016D2
010016CD . 80F9 22 cmp cl, 22 ; 是否是“"”
010016D0 .^ 75 F1 jnz short 010016C3 ; 没有“"”就检测下一位
010016D2 > 8038 22 cmp byte ptr [eax], 22 ; 还是检测
010016D5 . 75 04 jnz short 010016DB
010016D7 > 40 inc eax ; 下一位
010016D8 . 8945 E0 mov dword ptr [ebp-20], eax
010016DB > 8A08 mov cl, byte ptr [eax] ; 赋给cl
010016DD . 3ACB cmp cl, bl ; 检测是否为0
010016DF . 74 05 je short 010016E6
010016E1 . 80F9 20 cmp cl, 20 ; 是否为空格
010016E4 .^ 76 F1 jbe short 010016D7 ; 小于0x20就循环
010016E6 > F645 AC 01 test byte ptr [ebp-54], 1
010016EA . 74 11 je short 010016FD
010016EC . 0FB74D B0 movzx ecx, word ptr [ebp-50]
010016F0 . EB 0E jmp short 01001700 ; 所有的判断完成 跳出
010016F2 > 8038 20 cmp byte ptr [eax], 20 ; 没有引号的直接检测空格
010016F5 .^ 76 E4 jbe short 010016DB ; 是或小于空格ASCII的就循环
010016F7 . 40 inc eax ; 下一位
010016F8 . 8945 E0 mov dword ptr [ebp-20], eax
010016FB .^ EB F5 jmp short 010016F2 ; 循环
010016FD > 6A 0A push 0A
010016FF . 59 pop ecx
01001700 > 51 push ecx ; 0x0A
01001701 . 50 push eax ; 路径
01001702 . 53 push ebx
01001703 . 68 00000001 push 01000000 ; 固定值 不知道什么
01001708 . E8 49FCFFFF call 01001356 ; F7跟进去

接下来是传递参数

01001393 |. E8 B7FEFFFF call 0100124F ; 通过CLSID获取OCX的完整路径
01001398 |. 85C0 test eax, eax
0100139A |. BB CC100001 mov ebx, 010010CC ; ASCII "hhctrl.ocx"
0100139F |. 75 0E jnz short 010013AF ; 获取成功就跳,不成功就强奸[ebp-108]
010013A1 |. 53 push ebx ; /String2 => "hhctrl.ocx"
010013A2 |. 8D85 F8FEFFFF lea eax, dword ptr [ebp-108] ; |
010013A8 |. 50 push eax ; |String1
010013A9 |. FF15 40100001 call dword ptr [<&KERNEL32.lstrcpyA>] ; \lstrcpyA
010013AF |> 8B35 34100001 mov esi, dword ptr [<&KERNEL32.LoadLibrar>; kernel32.LoadLibraryA
010013B5 |. 8D85 F8FEFFFF lea eax, dword ptr [ebp-108] ; 前面获取的OCX路径
010013BB |. 50 push eax ; /FileName
010013BC |. FFD6 call esi ; \LoadLibraryA
010013BE |. 8BF8 mov edi, eax
010013C0 |. 85FF test edi, edi ; 是否装在hhctrl成功
010013C2 |. 75 09 jnz short 010013CD ; 成功就执行doWinMain
010013C4 |. 53 push ebx ; /FileName
010013C5 |. FFD6 call esi ; \LoadLibraryA
010013C7 |. 8BF8 mov edi, eax
010013C9 |. 85FF test edi, edi
010013CB |. 74 30 je short 010013FD
010013CD |> 68 D8100001 push 010010D8 ; /ProcNameOrOrdinal = "doWinMain"
010013D2 |. 57 push edi ; |hModule
010013D3 |. FF15 38100001 call dword ptr [<&KERNEL32.GetProcAddress>>; \GetProcAddress
010013D9 |. 85C0 test eax, eax
010013DB |. A3 3C230001 mov dword ptr [100233C], eax
010013E0 |. 74 1B je short 010013FD
010013E2 |. FFB5 F0FEFFFF push dword ptr [ebp-110] ; 路径,包含参数
010013E8 |. FFB5 F4FEFFFF push dword ptr [ebp-10C] ; 固定值,0x01000000
010013EE |. FFD0 call eax ; 执行doWinMain函数
010013F0 |. 57 push edi ; /hLibModule
010013F1 |. 8BF0 mov esi, eax ; |
010013F3 |. FF15 3C100001 call dword ptr [<&KERNEL32.FreeLibrary>] ; \FreeLibrary

由此得见hh.exe调用了hhctrl.ocx把获取的参数直接传递doWinMain函数。
可见hhctrl.ocx是关键。
同时,逆向推出hhctrl.ocx的doWinMain函数还提供了800 register title decompile mapid safe参数,这些都可以直接在hh.exe上调用。

由此按照他的调用方式出台CHM反编译工具,更名为CHMcat。
大小不到1k,这比那些动则几十M还收费且效果很差的软件要简便多了。

提供下载,以飨众人。

CHMcat.rar



« 时间旅行者的妻子手机丢失,请来信来函告知你的联系方式 »
  1. Gravatar头像
    兔兔 2010-1-21 15:59:05 1

    技术猫!!!




◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。