飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 17892|回复: 22

[原创] ..考研词汇 1.0 InlineHook API 爆破之解文

[复制链接]

该用户从未签到

发表于 2009-12-16 20:29:04 | 显示全部楼层 |阅读模式
原来我注册过这里的号啊。。。追踪hc、大Z,来PYG逛逛。。。

原版:http://www.onlinedown.net/soft/82461.htm

破解不是本文的重点,这里简略带过。
软件会找目录下的key.bb文件,其实就是个记事本文件,里面写上16个数字就可以了,接下来关键点如下:
004EED6B    55                         push    ebp                       ; 这是关键call内部,eax返回非0就是注册成功
004EED6C    8BEC                       mov     ebp, esp
004EED6E    8B4D 0C                    mov     ecx, dword ptr [ebp+C]
004EED71    E8 B4FDFFFF                call    004EEB2A
004EED76    50                         push    eax
004EED77    8B4D 08                    mov     ecx, dword ptr [ebp+8]
004EED7A    E8 E4FDFFFF                call    004EEB63
004EED7F    F7D8                       neg     eax                       ; 爆破方式n多,我用这里的三行共5个字节写mov eax,-1
004EED81    1BC0                       sbb     eax, eax                  ; 爆破方式n多,我用这里的三行共5个字节写mov eax,-1
004EED83    40                         inc     eax                       ; 爆破方式n多,我用这里的三行共5个字节写mov eax,-1
004EED84    5D                         pop     ebp
004EED85    C2 0800                    retn    8

这个地方共被11个地方调用。

软件的壳很少见,是PEX 0.99 -> bart/CrackPl,脱壳后本机运行成功,但在虚拟机里测试发现不能跨平台,看一下,原来这个壳处理后程序调用api的方式都是:
00866780  - E9 1077FA7B                jmp     7C80DE95                  ; kernel32.7C80DE95
00866785  - E9 85C1FC7B                jmp     7C83290F                  ; kernel32.ResumeThread
0086678A  - E9 9440FA7B                jmp     7C80A823                  ; kernel32.GetThreadPriority
0086678F  - E9 045AFA7B                jmp     7C80C198                  ; kernel32.SetThreadPriority
00866794  - E9 D1AAFA7B                jmp     7C81126A                  ; kernel32.GetVersion
。。。

彻底晕倒。

放弃脱壳,可以通过多层SMC去搞定他,也可以简单地用loader、lpk,但本文讲另外一个思路:InlineHook API进行爆破。

但是找哪个api呢?
我们通过esp定律发现他在OEP之前第一次用了VirtualFree函数,那时候代码全已出现但未执行,时机很perfect!就它了!

载入程序,Ctrl+N看一下:
Address    Section    Type    Name                                    Comment
00866379              Import  KERNEL32.ExitProcess
00866371              Import  KERNEL32.GetProcAddress
00866375              Import  KERNEL32.LoadLibraryA
00866369              Import  USER32.MessageBoxA
008DB000              Export  <ModuleEntryPoint>
0086637D              Import  KERNEL32.VirtualAlloc
00866381              Import  KERNEL32.VirtualFree

已经有KERNEL32.LoadLibraryA和KERNEL32.GetProcAddress的地址了(分别在dword [00866375]和dword [00866371]),有这对搭档在足够我们干很多事了!乐啊
这里还已经有了KERNEL32.VirtualFree,在dword [00866381],可以直接拿来用(即使没有,咱们也可以通过LoadLibraryA跟GetProcAddress获取)。
强调,下面的代码里,KERNEL32.VirtualFree的地址dword [00866381]是直接拿来用的,不要看到dword [00866381]感到莫名其妙。。。

基本信息有了,咱们开工!
1、首先找个空地。
程序空地不少,但是我仍喜欢加个区段,所以我加了个区段,大小只要200个字节左右就行了,因为补丁的代码只需要大概170个字节。
我加的段VA:008DB000

2、用LordPE修改程序的入口为新段的地址008DB000,OD载入,开始写代码:
PS:008DB026这里call eax ; VirtualProtect是为了使VirtualFree函数前6个字节可写可读,防止api地址不可写导致我们挂钩失败。不清楚的自己去查下api手册。
008DB000 > $  68 92B08D00              push    8DB092                    ; /ASCII "kernel32.dll"   8DB092这里你自己去写下ASCII "kernel32.dll"
008DB005   .  FF15 75638600            call    dword ptr [866375]        ; \kernel32.LoadLibraryA  返回基址到eax
008DB00B   .  68 A2B08D00              push    8DB0A2                    ; /ASCII "VirtualProtect"   8DB0A2这里你自己去写下ASCII "VirtualProtect"
008DB010   .  50                       push    eax                       ; |这里是刚得到的kernel32.dll的基址
008DB011   .  FF15 71638600            call    dword ptr [866371]        ; \kernel32.GetProcAddress   返回VirtualProtect的函数的地址到eax
008DB017   .  68 B2B08D00              push    8DB0B2                    ;  原来的属性暂放空地8DB0B2
008DB01C   .  6A 40                    push    40                        ;  可读可写属性40
008DB01E   .  6A 06                    push    6                         ;  size = 6
008DB020   .  FF35 81638600            push    dword ptr [866381]        ;  程序初始化后dword ptr [866381]里面就是VirtualFree函数的地址了
008DB026   .  FFD0                     call    eax                       ;  call刚得到的VirtualProtect的函数,使VirtualFree函数前6个字节可写可读,以便挂钩
008DB028   .  A1 81638600              mov     eax, dword ptr [866381]   ;  VirtualFree函数的地址给eax(开始保存api VirtualFree的前6个字节)
008DB02D   .  8B08                     mov     ecx, dword ptr [eax]      ;  VirtualFree函数的前4个字节给ecx
008DB02F   .  66:8B58 04               mov     bx, word ptr [eax+4]      ;  VirtualFree函数的第5-第6个字节给bx
008DB033   .  890D B6B08D00            mov     dword ptr [8DB0B6], ecx   ;  把得到的前6个字节保存起来,前4个字节保存到空地8DB0B6
008DB039   .  66:891D BAB08D00         mov     word ptr [8DB0BA], bx     ;  把得到的前6个字节保存起来,第5-第6个字节保存到空地8DB0BA(保存前6个字节完毕)
008DB040   .  C600 68                  mov     byte ptr [eax], 68        ;  写下钩子,68是push的机器码(开始写钩子)
008DB043   .  40                       inc     eax                       ;  上面刚写完1个byte,所以要加1,继续写下面的
008DB044   .  C700 55B08D00            mov     dword ptr [eax], 8DB055   ;  写上8DB055,让VirtualFree函数执行的时候返回到8DB055
008DB04A   .  83C0 04                  add     eax, 4                    ;  上面刚写完4个byte,所以要加4,继续写下面的
008DB04D   .  C600 C3                  mov     byte ptr [eax], 0C3       ;  写上0C3,配合上面写入的push 8DB055就会回到8DB055,patch时机就到了(钩子写完毕)
008DB050   .- E9 A5B0F8FF              jmp     008660FA                  ;  程序原来入口就是跳到008660FA开始执行的,我们照搬
;-------------------------钩子到了之后就会来到下面-----------------------
008DB055   .  C705 7FED4E00 B8FFFFFF   mov     dword ptr [4EED7F], -48   ;  VirtualFree函数执行的时候由于我们的钩子所以会来到这里,开始写入爆破的代码
008DB05F   .  C605 83ED4E00 FF         mov     byte ptr [4EED83], 0FF    ;  继续写入第5个,mov eax,-1总共是5个字节
008DB066   .  8B0D B6B08D00            mov     ecx, dword ptr [8DB0B6]   ;  把我们前面保存起来的VirtualFree函数的前4个字节给ecx(开始还原钩子)
008DB06C   .  66:8B1D BAB08D00         mov     bx, word ptr [8DB0BA]     ;  VirtualFree函数的第5-第6个字节给bx
008DB073   .  A1 81638600              mov     eax, dword ptr [866381]   ;  dword ptr [866381]里面是VirtualFree函数的头部地址
008DB078   .  8908                     mov     dword ptr [eax], ecx      ;  把ecx里的VirtualFree函数的前4个字节给写回去
008DB07A   .  83C0 04                  add     eax, 4                    ;  上面写完4个字节,所以加4继续写下面的
008DB07D   .  66:8918                  mov     word ptr [eax], bx        ;  把bx里的VirtualFree函数的第5-第6个字节给写回去(还原钩子完毕)
008DB080   .  83E8 04                  sub     eax, 4                    ;  回到VirtualFree函数头部准备执行VirtualFree
008DB083   .  83C4 04                  add     esp, 4                    ;  平栈
008DB086   .  FFD0                     call    eax                       ;  这里call的就是VirtualFree函数了等于回到程序原路了
008DB088   .  68 07608600              push    866007                    ;  原文件call VirtualFree之后就是回到866007的,我们照搬
008DB08D   .  C3                       retn                              ;  push+retn 都知道干嘛的吧
008DB08E      00                       db      00
008DB08F      00                       db      00
008DB090      00                       db      00
008DB091      00                       db      00
008DB092   .  6B 65 72 6E 65 6C 33 32 >ascii   "kernel32.dll",0          ;  这个是自己写的
008DB09F      00                       db      00
008DB0A0      00                       db      00
008DB0A1      00                       db      00
008DB0A2   .  56 69 72 74 75 61 6C 50 >ascii   "VirtualProtect",0        ;  这个是自己写的
008DB0B1      00                       db      00
008DB0B2      00                       db      00
008DB0B3      00                       db      00
008DB0B4      00                       db      00
008DB0B5      00                       db      00
008DB0B6   .  00000000                 dd      00000000
008DB0BA   .  0000                     dw      0000
008DB0BC      00                       db      00
008DB0BD      00                       db      00

所有的代码我都写了注释,不要嫌我罗嗦,写的很土,可能还有错误的地方,请多多海涵,偶是文盲。

保存代码,在本机xp,虚拟机xp、win7都测试完毕,破解成功。

1.gif

2.gif

3.gif

[ 本帖最后由 GUC 于 2009-12-16 20:30 编辑 ]

dup_skin_花鸟.rar

109.03 KB, 下载次数: 21, 下载积分: 飘云币 -2 枚

评分

参与人数 1威望 +60 飘云币 +60 收起 理由
Nisy + 60 + 60 您发布的主题属于精品!

查看全部评分

PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-8-23 23:49
  • 签到天数: 27 天

    [LV.4]偶尔看看III

    发表于 2009-12-16 20:37:55 | 显示全部楼层
    呵呵,学习一下了!
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-12-16 21:11:45 | 显示全部楼层
    不错 补区段来Patch关键点 VirtualFree利用的很好 /:good
    PYG19周年生日快乐!
  • TA的每日心情

    2016-6-2 20:34
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2009-12-16 21:33:44 | 显示全部楼层
    热心团~~~希望多发好文多多来指点我等学习啊
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-8-30 19:17
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2009-12-16 21:54:20 | 显示全部楼层
    好文章啊,学习了。
    PYG19周年生日快乐!

    该用户从未签到

     楼主| 发表于 2009-12-16 22:03:16 | 显示全部楼层
    原帖由 Nisy 于 2009-12-16 21:11 发表
    不错 补区段来Patch关键点 VirtualFree利用的很好 /:good

    多谢nisy鼓励。

    原帖由 wan 于 2009-12-16 21:33 发表
    热心团~~~希望多发好文多多来指点我等学习啊

    你太谦虚了,我是来学习你们的。

    1级修复后看着应该可以跨平台了,但2000跟win7都运行失败,不知道哪里问题,不跟了,不会解决跨平台问题。。。/:L

    感觉应该差不多可以写一个Inline Patching PEX Tool了,整合点改入口和加区段的代码。
    008DB088   .  68 07608600              push    866007

    这个返回的地址866007其实在钩子返回的时候可以在堆栈得到,mov r32,dword [esp]再保存到buffer,结尾写push dword [buffer], retn,这样可以通用了。
    想想觉得可行,但太菜没实力着手实现,而且PEX这壳实在太少见了,开发这个PEX通用补丁工具似乎没啥大的用武之地。

    [ 本帖最后由 GUC 于 2009-12-16 22:37 编辑 ]
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2020-7-16 11:27
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2009-12-16 22:07:40 | 显示全部楼层
    学习了,/:good
    PYG19周年生日快乐!
  • TA的每日心情

    2019-3-20 17:55
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2009-12-16 23:10:16 | 显示全部楼层
    加区段是不是还要重建PE,修改区段属性?这个新加的区段怎样让他在运行之前读取内存?
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-4-29 07:52
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2009-12-17 02:43:32 | 显示全部楼层
    非常需要学习
    PYG19周年生日快乐!
  • TA的每日心情

    2017-7-19 15:45
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2009-12-17 08:33:47 | 显示全部楼层
    很强大/:good
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表