• 我的第一次算法分析笔记


     
     

    005DA39C . 55 push ebp

    005DA39D . 8BEC mov ebp,esp

    005DA39F . B9 05000000 mov ecx,0x5

    005DA3A4 > 6A 00 push 0x0

    005DA3A6 . 6A 00 push 0x0

    005DA3A8 . 49 dec ecx

    005DA3A9 .^ 75 F9 jnz short dump.005DA3A4

    005DA3AB . 51 push ecx

    005DA3AC . 53 push ebx

    005DA3AD . 56 push esi

    005DA3AE . 57 push edi

    005DA3AF . 8945 FC mov dword ptr ss:[ebp-0x4],eax

    005DA3B2 . 33C0 xor eax,eax

    005DA3B4 . 55 push ebp

    005DA3B5 . 68 FDA55D00 push dump.005DA5FD

    005DA3BA . 64:FF30 push dword ptr fs:[eax]

    005DA3BD . 64:8920 mov dword ptr fs:[eax],esp

    005DA3C0 . A1 D0435E00 mov eax,dword ptr ds:[0x5E43D0]

    005DA3C5 . 8038 00 cmp byte ptr ds:[eax],0x0

    005DA3C8 . 0F85 F1010000 jnz dump.005DA5BF

    005DA3CE . C645 F7 00 mov byte ptr ss:[ebp-0x9],0x0

    005DA3D2 . A1 AC495E00 mov eax,dword ptr ds:[0x5E49AC] ; ld^

    005DA3D7 . 8338 00 cmp dword ptr ds:[eax],0x0

    005DA3DA . 0F85 DF010000 jnz dump.005DA5BF

    这段就是点注册按钮的按钮事件地方,我们单步跟踪下去看看。。。

    005DA511 > 8D4D F7 lea ecx,dword ptr ss:[ebp-0x9]

    005DA514 . 8D55 F8 lea edx,dword ptr ss:[ebp-0x8]

    005DA517 . A1 08475E00 mov eax,dword ptr ds:[0x5E4708] ; dc^

    005DA51C . 8B00 mov eax,dword ptr ds:[eax]

    005DA51E . E8 75EEF3FF call dump.00519398 ; 算法call

    005DA523 . 8B45 F8 mov eax,dword ptr ss:[ebp-0x8]

    005DA526 . BA 84A65D00 mov edx,dump.005DA684 ; YesIKnow

    005DA52B . E8 ACABE2FF call dump.004050DC

    005DA530 . 74 04 je short dump.005DA536

    005DA532 . C645 F7 00 mov byte ptr ss:[ebp-0x9],0x0

    005DA536 > 807D F7 00 cmp byte ptr ss:[ebp-0x9],0x0

    005DA53A . 75 62 jnz short dump.005DA59E

    005DA53C . 33C9 xor ecx,ecx

    005DA53E . B2 01 mov dl,0x1

    005DA540 . A1 7C355800 mov eax,dword ptr ds:[0x58357C] ; F

    005DA545 . E8 C27EEAFF call dump.0048240C

    005DA54A . 8B15 AC495E00 mov edx,dword ptr ds:[0x5E49AC] ; ld^

    005DA550 . 8902 mov dword ptr ds:[edx],eax

    005DA552 . 33C0 xor eax,eax

    005DA554 . 55 push ebp

    005DA555 . 68 97A55D00 push dump.005DA597

    005DA55A . 64:FF30 push dword ptr fs:[eax]

    005DA55D . 64:8920 mov dword ptr fs:[eax],esp

    005DA560 . A1 D0435E00 mov eax,dword ptr ds:[0x5E43D0]

    005DA565 . C600 01 mov byte ptr ds:[eax],0x1

    005DA568 . A1 AC495E00 mov eax,dword ptr ds:[0x5E49AC] ; ld^

    005DA56D . 8B00 mov eax,dword ptr ds:[eax]

    005DA56F . 8B10 mov edx,dword ptr ds:[eax]

    005DA571 . FF92 EC000000 call dword ptr ds:[edx+0xEC]

    005DA577 . 33C0 xor eax,eax

    005DA579 . 5A pop edx ; 0012F8F4

    005DA57A . 59 pop ecx ; 0012F8F4

    005DA57B . 59 pop ecx ; 0012F8F4

    005DA57C . 64:8910 mov dword ptr fs:[eax],edx

    005DA57F . 68 A8A55D00 push dump.005DA5A8

    005DA584 > A1 AC495E00 mov eax,dword ptr ds:[0x5E49AC] ; ld^

    005DA589 . E8 C65CE3FF call dump.00410254

    005DA58E . A1 D0435E00 mov eax,dword ptr ds:[0x5E43D0]

    005DA593 . C600 00 mov byte ptr ds:[eax],0x0

    005DA596 . C3 retn

    005DA597 .^ E9 8C9FE2FF jmp dump.00404528

    005DA59C .^ EB E6 jmp short dump.005DA584

    005DA59E > B8 98A65D00 mov eax,dump.005DA698 ; 您已经注册了本软件!

    005DA5A3 . E8 2441F2FF call dump.004FE6CC

    005DA5A8 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]

    大家看到我标记的红色跳转地址,这个是判断是否注册成功的关键,所以说在这个跳转的上面肯定有个call是关键的算法call 经过分析 005DA51E 这个地址就是算法call 所以我们跟进去看看 这个记为算法call 1

    分别判断注册码和用户名是否输入为空

    005193EE |. E8 C53AFEFF call dump.004FCEB8 ; 获得硬盘序列号 S2ATTJKG

    005193F3 |. 8B45 F0 mov eax,[local.4]

    005193F6 |. 8D55 F4 lea edx,[local.3]

    这个是获取我电脑的硬盘序列号 S2ATTJKG 这串东西很重要,因为作者拿这个序列号来进行计算注册码

    00519408 |. 8D45 EC lea eax,[local.5]

    0051940B |. 50 push eax

    0051940C |. 8B03 mov eax,dword ptr ds:[ebx]

    0051940E |. B1 61 mov cl,0x61

    00519410 |. 66:BA 5904 mov dx,0x459

    00519414 |. E8 9347FEFF call dump.004FDBAC ; 计算出软件显示出来的机器码 XV8OCxJDauE

    00519419 |. 8B55 EC mov edx,[local.5]

    0051941C |. 8BC3 mov eax,ebx

    这个call是计算得出软件所显示出来的机器码

    00519423 |. 8B45 FC mov eax,[local.1] ; 假码

    00519426 |. 50 push eax

    00519427 |. 57 push edi

    00519428 |. 8BD3 mov edx,ebx

    0051942A |. 8B4D F8 mov ecx,[local.2] ; 用户名

    0051942D |. 8BC6 mov eax,esi

    0051942F |. E8 64000000 call dump.00519498 ; 算法

    00519434 |. 84C0 test al,al

    00519436 74 0C je short dump.00519444

    00519438 |. 8BC3 mov eax,ebx

    0051943A |. BA 8C945100 mov edx,dump.0051948C ; YesIKnow

    标记红色的地址为算法call 这个记为算法call 2

    所以不用我多说了,直接F7跟进去看看

    005194B0 |. 8BF2 mov esi,edx

    005194B2 |. 8945 FC mov [local.1],eax ; dump.005E62FE

    005194B5 |. 8B45 F8 mov eax,[local.2] ; 用户名

    005194B8 |. E8 C3BCEEFF call dump.00405180

    005194BD |. 8B45 0C mov eax,[arg.2] ; 假码

    005194C0 |. E8 BBBCEEFF call dump.00405180

    005194C5 |. 33C0 xor eax,eax ; dump.005E62FE

    005194C7 |. 55 push ebp

    005194C8 |. 68 90975100 push dump.00519790

    005194CD |. 64:FF30 push dword ptr fs:[eax]

    005194D0 |. 64:8920 mov dword ptr fs:[eax],esp

    005194D3 |. 33DB xor ebx,ebx

    005194D5 |. A1 54455E00 mov eax,dword ptr ds:[0x5E4554]

    005194DA |. 8038 00 cmp byte ptr ds:[eax],0x0

    005194DD |. 0F85 8A020000 jnz dump.0051976D

    005194E3 |. 8D55 E0 lea edx,[local.8]

    005194E6 |. B8 AC975100 mov eax,dump.005197AC ; SOFTAAENG

    005194EB |. E8 C839FEFF call dump.004FCEB8

    005194F0 |. 8B45 E0 mov eax,[local.8] ; 硬盘序列号

    005194F3 |. 8D55 F4 lea edx,[local.3]

    005194F6 |. E8 5906EFFF call dump.00409B54

    005194FB |. 8D45 DC lea eax,[local.9]

    005194FE |. 50 push eax ; dump.005E62FE

    005194FF |. 8B06 mov eax,dword ptr ds:[esi] ; 生成机器码

    00519501 |. B1 78 mov cl,0x78

    00519503 |. 66:BA 5904 mov dx,0x459

    00519507 |. E8 A046FEFF call dump.004FDBAC

    0051950C |. 8B55 DC mov edx,[local.9] ; 序列号

    0051950F |. 8B45 F4 mov eax,[local.3] ; 机器码

    00519512 |. E8 C5BBEEFF call dump.004050DC

    00519517 |. 0F85 50020000 jnz dump.0051976D

    0051951D |. 8B45 0C mov eax,[arg.2] ; 假码

    00519520 |. E8 6BBAEEFF call dump.00404F90

    00519525 |. 8BF0 mov esi,eax ; 获得假码长度

    00519527 |. 8D45 EC lea eax,[local.5]

    0051952A |. 50 push eax ; dump.005E62FE

    0051952B |. 8D45 D8 lea eax,[local.10]

    0051952E |. 8B4D F8 mov ecx,[local.2] ; 用户名

    00519531 |. 8B55 F4 mov edx,[local.3] ; 机器码

    00519534 |. E8 A3BAEEFF call dump.00404FDC ; 合并字符串

    00519539 |. 8B4D D8 mov ecx,[local.10] ; S2ATTJKGSendige

    0051953C |. 8B45 FC mov eax,[local.1]

    0051953F |. 8B40 60 mov eax,dword ptr ds:[eax+0x60]

    00519542 |. BA C8010000 mov edx,0x1C8 ; 常量1c8

    00519547 |. E8 FCE9FFFF call dump.00517F48 ; 注册码生成call

    全部都是关键的东西啊,所以要注意了。

    标记红色的为算法call 3 就是这个call才是我们要跟的地方,因为这个地方会出现真正的注册码

    我们先不要进入这个call 继续单步调试下去看看

     
     

    上图为第一个过渡注册码,就是说这个注册码是没用的

    然后一路单步下去会发现全部都是一样的过程

    1.获取机器码,生成硬盘系列号

    2.获取用户名和机器码后,这2个进行合并

    3.然后push 一个常量(用来进行计算的)分别为:1C82E1640xFC

    过渡注册码1 100937-12343464-2223981

    过渡注册码2 94787-1245174-2223571

    过渡注册码3 99437-9636564-2223881

    真正注册码 97877-6821388-2223777

    所以一直跟下去会发现这些信息,我们得知最后一个是真正的注册码后,所以我们只关注出真正的注册码的call就可以知道算法了

    00517F48 /$ 55 push ebp ; 最终核心算法call

    00517F49 |. 8BEC mov ebp,esp

    00517F4B |. 6A 00 push 0x0

    00517F4D |. 6A 00 push 0x0

    00517F4F |. 6A 00 push 0x0

    00517F51 |. 6A 00 push 0x0

    00517F53 |. 6A 00 push 0x0

    00517F55 |. 6A 00 push 0x0

    00517F57 |. 6A 00 push 0x0

    00517F59 |. 53 push ebx

    00517F5A |. 56 push esi

    00517F5B |. 894D F8 mov [local.2],ecx ; S2ATTJKGSendige

    00517F5E |. 8955 FC mov [local.1],edx ; 0xFC

    00517F61 |. 8B45 F8 mov eax,[local.2] ; S2ATTJKGSendige

    0xFC是在进入call之前就压入堆栈的,这个数据是参与注册码计算

    00517F84 |. 33DB xor ebx,ebx

    00517F86 |. 837D FC 00 cmp [local.1],0x0 ; 对比常量是否为0

    00517F8A |. 0F84 B3000000 je dump.00518043

    00517F90 |. 837D F8 00 cmp [local.2],0x0 ; 对比这个是否为0 S2ATTJKGSendige

    00517F94 |. 0F84 A9000000 je dump.00518043

    00517F9A |. 8B45 F8 mov eax,[local.2]

    00517F9D |. E8 EECFEEFF call dump.00404F90 ; S2ATTJKGSendige 获取这个的长度

    00517FA2 |. 8945 F0 mov [local.4],eax ; strlen F为长度

    00517FA5 |. 8B45 F0 mov eax,[local.4]

    00517FA8 |. 85C0 test eax,eax ; 对比长度

    我这里声明一些东西

    str=S2ATTJKGSendige

    constant=0xFC

    strlen=S2ATTJKGSendige的长度(我这里的长度为0xF

    Str之和=addstrlen=509

    00517FAC |. BA 01000000 mov edx,0x1

    00517FB1 |> 8B4D F8 /mov ecx,[local.2]

    00517FB4 |. 0FB64C11 FF |movzx ecx,byte ptr ds:[ecx+edx-0x1] ; 拆解字符串

    00517FB9 |. 03D9 |add ebx,ecx

    00517FBB |. 42 |inc edx

    00517FBC |. 48 |dec eax

    00517FBD |.^ 75 F2 jnz short dump.00517FB1

    00517FBF |> 81FB 204E0000 cmp ebx,0x4E20 ; ebxS2ATTJKGSendige 字符串的16进制相加的结果 509

    这个00517FB4 地址 是进行拆分str 大家可以跟下看看 然后把拆分的每个字符串转换为16进制进行相加

    标记为红色的2个地址已经说明的很清楚了。。。

    所以得出ebx=509

    就是上面所说的addstrlen 因为这个后面也是用来进行运算的

    整个程序最关键的地方来了 整个程序最关键的地方来了 整个程序最关键的地方来了 重要的事情说三次

    算法1

    00517FD3 |> 8B75 FC mov esi,[local.1] ; 把常量0xFCesi

    00517FD6 |. 0FAF75 F0 imul esi,[local.4] ; [local.4]=strlen 常量和长度F相乘 结果存到esi

    00517FDA |. 6BC3 49 imul eax,ebx,0x49 ; 上面说了ebx=509 addstrlen49相乘 结果存到eax

    00517FDD |. 03F0 add esi,eax ; 两个结果相加

    00517FDF |. 8D55 EC lea edx,[local.5]

    00517FE2 |. 8BC6 mov eax,esi

    00517FE4 |. E8 DB20EFFF call dump.0040A0C4 ; 将相加的结果转换为10进制

    00517FE9 |. 8B55 EC mov edx,[local.5] ; 97877

     

    两个数据相加的结果是00017E55 所以转换为10进制就是 97877

    绿色这个call 是一个转换进制的函数而已

    好了,我们接下来继续分析

    00517FE9 |. 8B55 EC mov edx,[local.5] ; 97877

    00517FEC |. 8D45 F4 lea eax,[local.3]

    00517FEF |. B9 A0805100 mov ecx,dump.005180A0 ; -

    00517FF4 |. E8 E3CFEEFF call dump.00404FDC

    走到这里后,我们可以看到堆栈出现 0012F850 014276E4 ASCII "97877-"

    所以可以看到这个是用来加“-”这个字符串和所得到的数字进行连接

    算法2

    00517FF9 |. 8B45 FC mov eax,[local.1] ; constanteax

    00517FFC |. F7EB imul ebx ; ebx=509=addstrlen 这句汇编的意思是将eax * ebx 得到的结果存在eax

    00517FFE |. 6BF0 15 imul esi,eax,0x15 ;eax*15 结果存在esi

    00518001 |. FF75 F4 push [local.3]

    00518004 |. 8D55 E8 lea edx,[local.6]

    00518007 |. 8BC6 mov eax,esi

    00518009 |. E8 B620EFFF call dump.0040A0C4 ; 将相加的结果转换为10进制

    得出 6821388

    算法3

    00518023 |. 8B45 F0 mov eax,[local.4] ; strleneax

    00518026 |. F7EB imul ebx ; ebx=509=addstrlen eax*ebx 结果存在eax

    00518028 |. 6BF0 73 imul esi,eax,0x73 ; eax*73 结果放在esi

    0051802B |. 0375 FC add esi,[local.1]

    0051802E |. 8D55 E4 lea edx,[local.7]

    00518031 |. 8BC6 mov eax,esi ; dump.0068160C

    00518033 |. E8 8C20EFFF call dump.0040A0C4 ; 将相加的结果转换为10进制

    得出 2223777

    最后连接注册码得出 0012F850 0142CDE4 ASCII "97877-6821388-2223777"

    算法总结

    算法1constant*strlen+addstrlen*49=A

    算法2constant*addstrlen*15=B

    算法3strlen*addstrlen*73+constant=C

    最终注册码: A-B-C

    易语言源码展示

    代码写的很挫 大家见谅 为了防止注册码泛滥,所以这里就不放上源码,只贴出图片,这个仅供大家参考,请勿用于非法用途,尊重作者的劳动成果!!!

     
     
     
     
     
     
    注册码放在注册表这个路径,如果你注册成果,删除里面的键值就可以变为未注册版

    HKEY_LOCAL_MACHINESOFTWARElsjsoftdct

    By ↖星空·之上↗

    个人博客:http://xingkongpj.blog.163.com/

    16:39 2016/6/29

    高清文档下载地址:http://www.vdisk.cn/down/index/19538883
  • 相关阅读:
    一个帖子掌握android所有控件、ProgressBar 、Android 动画效果、SQLite、四大组件、Android多媒体(转
    Android开发交流群
    我的程序里 《我的歌声里》程序员版
    《老罗Android开发视频教程安卓巴士》(Android 开发)
    #百度360大战# 我为什么要支持360
    安卓巴士移动开发者周刊第九期
    水杯题的非常好的解释
    [LeetCode] Jump Game
    [LeetCode] Longest Common Prefix
    [CareerCup][Google Interview] 寻找动态的中位数
  • 原文地址:https://www.cnblogs.com/Sendige/p/9600815.html
Copyright © 2020-2023  润新知