Shy 发表于 2016-7-11 21:12

鼠标指针制作ArtCursors重启验证爆破+算法分析

本教程由热情洋溢的木木不哭赞助播出(“哎呀我摔倒了要漂亮姐姐亲亲才能起来{:5_187:}”)

软件逆向分解:
该程序有两个计算点,输入注册码算一部分,算完以后写入注册表,重启时再计算一部分,,本来教程早就该出了,但是写一个逆向用的工具写了将近十天,,拖到现在

先讲爆破:

爆破点其实难度不大,主要体现在两个点,一个如果注册码错误,不会把注册码写入注册表,当然第二部分的重启计算也就不存在,会被直接跳过

所以这里有两个方法,一个是修改写入注册码的点,一个是自己手动添加注册表

手动:
"Time"=hex:b6,07,e5,26,53,c8,e4,40 "这个time值没有去追过,可能是试用时间"
"Aha-soft ArtCursors 5.24 Build 2013-Nov-25"="Aha-soft ArtCursors 5.24 Build 2013-Nov-25"
"UserName"="这里写你的注册名"
"Email"="这里填邮箱,可随便填"
"Key"="3511224453"

上面那个key可用,是我无意中试出来的,具体算法我等会儿会说,,,

修改写入注册码点:

不用我多解释了吧,,
00568114|. /74 03         je short 00568119改JMP

0056828D|. /74 01         je short 00568290 改JMP


完成写入,,以后 然后我们找重启验证的点


由于是读注册表,所有用注册表断返回,可以找到这里

00704C32|.E8 3935E6FF   call 00568170这里是验证的一部分

所以下面的
00704D19|. /75 11         jnz short 00704D2C                     ; 这里要改JMP
00704D1B|. |A1 BCF07400   mov eax, dword ptr             ; 荑t
00704D20|. |8B00          mov eax, dword ptr
00704D22|. |E8 E53AE7FF   call 0057880C                            ; 这里是启动广告
00704D27|. |E8 C848E7FF   call 005795F4


然后这样修改的话只是取消了启动的广告,所以还需要找重启验证的点,

就是上面的验证的一部分的那个call 进去改

0056828D|. /74 01         je short 00568290改JMp

以上完成爆破,比较简略,因为我重点讲的是分析他的算法
--------------------------------------------------------------------------------------------------------------------------TEXT分割
算法部分:


这里我圈出来的就是算法部分,接下来我来分析

第一个字符串所在的我就不分析了,因为我猜测他不是重点,重点部分我已经说过了

两个验证点,一个是输入注册码验证一部分 另外一个就是重启验证的那部分

重启验证那部分比较简单,就是验证注册码的第二位是不是为5,如果不为5就失败,,,所以记住这个注册码第二位一定要为5
00568182|.8B45 FC       mov eax,
00568185|.E8 B2C1E9FF   call 0040433C                            ; 出现原注册码
0056818A|.8B45 F8       mov eax,                      ; 出现ArtCursors
0056818D|.E8 AAC1E9FF   call 0040433C
00568192|.33C0          xor eax, eax
00568194|.55            push ebp
00568195|.68 AB825600   push 005682AB
0056819A|.64:FF30       push dword ptr fs:
0056819D|.64:8920       mov dword ptr fs:, esp
005681A0|.33F6          xor esi, esi
005681A2|.8D55 F0       lea edx,
005681A5|.8B45 FC       mov eax,                      ; 原注册码
005681A8|.E8 07FEFFFF   call 00567FB4
005681AD|.8B55 F0       mov edx,                      ; 去除后的注册码
005681B0|.8D45 FC       lea eax,                      ; 原注册码在数据窗口
005681B3|.E8 D8BDE9FF   call 00403F90
005681B8|.8B45 FC       mov eax,
005681BB|.E8 C8BFE9FF   call 00404188
005681C0|.83F8 07       cmp eax, 0x7                           ; 去除后注册码的位数
005681C3|.7D 0A         jge short 005681CF
005681C5|.BE 0B000000   mov esi, 0xB
005681CA|.E9 C1000000   jmp 00568290
005681CF|>837D F8 00    cmp , 0x0                     ; 出现这个程序的名字
005681D3|.0F84 B7000000 je 00568290
005681D9|.33DB          xor ebx, ebx
005681DB|.8B45 F8       mov eax,                      ; 程序名字给eax
005681DE|.E8 A5BFE9FF   call 00404188                            ; 计算出这个程序名的位数
005681E3|.48            dec eax                                  ; -1
005681E4|.85C0          test eax, eax
005681E6|.7E 13         jle short 005681FB
005681E8|.BA 01000000   mov edx, 0x1                           ; edx=1
005681ED|>8B4D F8       /mov ecx,                       ; 程序名
005681F0|.0FB64C11 FF   |movzx ecx, byte ptr
005681F5|.03D9          |add ebx, ecx
005681F7|.42            |inc edx
005681F8|.48            |dec eax
005681F9|.^ 75 F2         \jnz short 005681ED
005681FB|>8BC3          mov eax, ebx
005681FD|.B9 1E000000   mov ecx, 0x1E
00568202|.99            cdq
00568203|.F7F9          idiv ecx
00568205|.42            inc edx
00568206|.B8 C4825600   mov eax, 005682C4                        ; 2345679qwertyupadfghjkzxcvbnms
0056820B|.8A4410 FF   mov al, byte ptr
0056820F|.8B55 FC       mov edx,                      ; 出现注册码
00568212|.3A42 01       cmp al, byte ptr                ; 判断第二位是否为5,一定要为5
00568215|.74 01         je short 00568218
00568217|.46            inc esi
00568218|>8D55 F4       lea edx,
0056821B|.8B45 F8       mov eax,                      ; 出现程序名
0056821E|.E8 9110EAFF   call 004092B4
00568223|.8D45 EC       lea eax,
00568226|.8B55 F4       mov edx,                      ; edx=小写的程序名
00568229|.8A12          mov dl, byte ptr
0056822B|.E8 70BEE9FF   call 004040A0
00568230|.8B45 EC       mov eax,                      ; eax=小写程序名的第一位a
00568233|.BA C4825600   mov edx, 005682C4                        ; 2345679qwertyupadfghjkzxcvbnms
00568238|.E8 37C2E9FF   call 00404474
0056823D|.85C0          test eax, eax
0056823F|.7E 11         jle short 00568252
00568241|.8D45 FC       lea eax,                      ; eax数据窗口值为去除后的注册码
00568244|.E8 0FC1E9FF   call 00404358
00568249|.8B55 F4       mov edx,
0056824C|.8A12          mov dl, byte ptr
0056824E|.8810          mov byte ptr , dl
00568250|.EB 3E         jmp short 00568290
00568252|>33DB          xor ebx, ebx
00568254|.8B45 F8       mov eax,
00568257|.E8 2CBFE9FF   call 00404188
0056825C|.48            dec eax
0056825D|.85C0          test eax, eax
0056825F|.7E 13         jle short 00568274
00568261|.BA 01000000   mov edx, 0x1
00568266|>8B4D F8       /mov ecx,
00568269|.0FB64C11 FF   |movzx ecx, byte ptr
0056826E|.33D9          |xor ebx, ecx
00568270|.42            |inc edx
00568271|.48            |dec eax
00568272|.^ 75 F2         \jnz short 00568266
00568274|>8BC3          mov eax, ebx
00568276|.B9 1E000000   mov ecx, 0x1E
0056827B|.99            cdq
0056827C|.F7F9          idiv ecx
0056827E|.42            inc edx
0056827F|.B8 C4825600   mov eax, 005682C4                        ; 2345679qwertyupadfghjkzxcvbnms
00568284|.8A4410 FF   mov al, byte ptr
00568288|.8B55 FC       mov edx,
0056828B|.3A02          cmp al, byte ptr
0056828D|.74 01         je short 00568290
0056828F|.46            inc esi
00568290|>33C0          xor eax, eax
00568292|.5A            pop edx
00568293|.59            pop ecx
00568294|.59            pop ecx
00568295|.64:8910       mov dword ptr fs:, edx
上面这个点是重启验证的部分,,,简单略过,,因为只是对比第二位是否为5而已

005680AD|.E8 02FFFFFF   call 00567FB4                            ; 逐字分割
005680B2|.8B55 F4       mov edx,
005680B5|.8D45 FC       lea eax,
005680B8|.E8 D3BEE9FF   call 00403F90
005680BD|.8B45 FC       mov eax,
005680C0|.E8 C3C0E9FF   call 00404188                            ; 判断注册码是否存在0218ioL,有则删除
005680C5|.8BF0          mov esi, eax
005680C7|.83FE 07       cmp esi, 0x7
005680CA|.7D 09         jge short 005680D5
005680CC|.C745 F8 0B000>mov , 0xB
005680D3|.EB 44         jmp short 00568119
005680D5|>33DB          xor ebx, ebx                           ; 原本是10位,然后清0
005680D7|.8B45 FC       mov eax,                      ; 若存在0128ioL,则出现删除后的注册码
005680DA|.E8 A9C0E9FF   call 00404188                            ; 取删除后的注册码位数
005680DF|.48            dec eax                                  ; -1
005680E0|.83E8 02       sub eax, 0x2                           ; -2
005680E3|.7C 14         jl short 005680F9                        ; eax=次数,为10-1-2=7
005680E5|.40            inc eax                                  ; 7+1=8次
005680E6|.BA 02000000   mov edx, 0x2
005680EB|>8B4D FC       /mov ecx,                       ; ecx为注册码
005680EE|.0FB64C11 FF   |movzx ecx, byte ptr        ; 从注册码的第二位开始,到倒数第二位结束
005680F3|.33D9          |xor ebx, ecx
005680F5|.42            |inc edx
005680F6|.48            |dec eax
005680F7|.^ 75 F2         \jnz short 005680EB                      ; 开始循环异或操作,eax=0则跳出循环
005680F9|>8BC3          mov eax, ebx
005680FB|.B9 1E000000   mov ecx, 0x1E
00568100|.99            cdq
00568101|.F7F9          idiv ecx
00568103|.42            inc edx
00568104|.B8 50815600   mov eax, 00568150                        ; 2345679qwertyupadfghjkzxcvbnms
00568109|.8A4410 FF   mov al, byte ptr
0056810D|.8B55 FC       mov edx,
00568110|.3A4432 FF   cmp al, byte ptr          ; 判断最后一位是否等于所在异或值的字符串
00568114|.74 03         je short 00568119
00568116|.FF45 F8       inc
00568119|>33C0          xor eax, eax
0056811B|.5A            pop edx
0056811C|.59            pop ecx
0056811D|.59            pop ecx
0056811E|.64:8910       mov dword ptr fs:, edx
00568121|.68 3E815600   push 0056813E
00568126|>8D45 F4       lea eax,
00568129|.E8 CABDE9FF   call 00403EF8
0056812E|.8D45 FC       lea eax,
00568131|.E8 C2BDE9FF   call 00403EF8
00568136\.C3            retn


这里才是关键,,,自己看我的注释即可

分析总结:
    首先判断注册码是否为10位,接着文本逐字分割,对比每一位注册码,如果注册码里面出现0,1,2,8,字母i,字母o,字母l,则会删除两位

005680DF|.48            dec eax                                  ; -1
005680E0|.83E8 02       sub eax, 0x2                           ; -2


然后这里eax的值为注册码的位数,如果不存在以上我说的,则进行上面两句代码以后 eax=7,否则 如果是3511224453这组正确注册码的话,他会把11给删除,变成35224453,然后执行完以后eax的值为5,


005680E5|.40            inc eax                                  ; 7+1=8次


然后再经过这一句的话,eax=7就会+1,变成8,也就是去掉首尾,只运行这8八位,eax=5的话,+1就会变成6,同样的也是去掉首尾,如:35224453将计算522445部分


接下来剖析522445部分的算法


也就是这段
005680EB|> /8B4D FC       /mov ecx,                       ; ecx为注册码
005680EE|. |0FB64C11 FF   |movzx ecx, byte ptr        ; 从注册码的第二位开始,到倒数第二位结束
005680F3|. |33D9          |xor ebx, ecx
005680F5|. |42            |inc edx
005680F6|. |48            |dec eax
005680F7|.^\75 F2         \jnz short 005680EB                      ; 开始循环异或操作,eax=0则跳出循环

这里是逐位进行xor操作,

522445中,取5的16进制 35,与0进行xor,结果再与2的十六进制"32"进行xor,与2xor以后的结果再与下一位2的十六"32"进行xor,直到与最后一位5 xor完,结果




此时,eax=0,意思是一共循环了4次,每次eax-2,所以跟之前的8对应,8是8位注册码,也就是去掉了首尾两个字符,edx是已循环次数,初始就为2,每次+1

接下来这4句
005680F9|> \8BC3          mov eax, ebx
005680FB|.B9 1E000000   mov ecx, 0x1E
00568100|.99            cdq
00568101|.F7F9          idiv ecx这里是做除法,eax的值除以ecx,ecx的值始终为1E,然后余数保存在edx
00568103|.42            inc edx ---------------edx+1

00568104|.B8 50815600   mov eax, 00568150                        ; 2345679qwertyupadfghjkzxcvbnms
00568109|.8A4410 FF   mov al, byte ptr          如果edx=1,那么他就取2的十六进制32,如果是2就取3的16进制32,
0056810D|.8B55 FC       mov edx,     这里是你的注册码
00568110|.3A4432 FF   cmp al, byte ptr          这里就是判断你最后那位是不是等于上面的那个取的值

比如如果edx=1,他取的2就是32,然后你注册码的第十位 如果等于2,那么就验证成功,否则就xx

看不懂没关系,你们自己去体验一下就知道,,,说再多不动手也白看,,我今天写这个程序的注册机写了一天我也没写完

主要是没理解cdq跟idiv ecx,,,没学过汇编,,此贴做个记录吧,分析算法真是个脑力活,烧脑细胞!






Shy 发表于 2016-7-11 21:15

本帖最后由 Shy 于 2016-7-11 22:46 编辑

网上有相应的Keygen,

菜鸟中的菜鸟 发表于 2016-7-12 19:35

本帖最后由 菜鸟中的菜鸟 于 2016-7-12 19:42 编辑

分析算法就是费劲!

money赫 发表于 2016-7-20 17:11

很到位,学到东西了。

ggyayamm 发表于 2016-7-27 16:33


谢谢分享啊

fcguo800 发表于 2018-1-19 13:44

感谢楼主的分享,学习一下。

小笨pojie 发表于 2018-6-4 20:06

找了好久,学习一下哈{:5_116:}

别管我了行 发表于 2022-4-6 04:31

ldljlzw 发表于 2022-4-6 10:03

af521 发表于 2022-11-24 14:28

感谢版主的分享
页: [1] 2
查看完整版本: 鼠标指针制作ArtCursors重启验证爆破+算法分析