• 逆向工程初步160个crackme-------6


    工具:1. 按钮事件地址转换器E2A
    2. PEID
    3. Ollydbg
    同样我们先来运行一下这个程序,
    在这里插入图片描述
    ok按钮是被禁用的,有一个help按钮点击后弹出一个消息框:消息框显示提示信息为。本程序需要输入正确的姓名的序列号,把OK按钮和Cancella按钮隐藏显示出其后面的RingZero的LOGO
    在这里插入图片描述我们随便输入姓名和序列号
    在这里插入图片描述
    发现OK还是禁用的,那我们就点击Canella试试,发现没用并且序列号被清零在这里插入图片描述
    我们熟悉完程序后,正式开始分析。
    我们还是先用PEID看看其文件信息,
    在这里插入图片描述发现其是用Delphi编写的32位程序,我们打开OD载入程序。
    运行程序随便输入用户名和序列号
    在这里插入图片描述
    随后我们需要分析其对应的各个按钮事件,用E2A打开程序文件查看各个按钮事件对应的地址,因为OK按键被禁用所以我们先分析Cancela按钮消息,用E2A程序打开查看Cancella按钮事件的地址
    在这里插入图片描述然后在OD中搜索此地址并下段,然后单击CancellaClick按钮程序会停在此地址处
    在这里插入图片描述然后单步向下并且注意跳转指令(因为我们输入的是错误的注册码,所以程序走的肯定是不正确的分支,所以我们就和程序反着来,显式改变eip,逆其道而为之),先看看这样后能不能满足条件(如果能满足在回头来分析如何让其实现跳转)。
    在这里插入图片描述F8向下分析遇见一个跳转指令,按此程序其是要跳转(那么我们就逆其道而为之),显式改变eip为00442EF0,然后执行程序
    在这里插入图片描述
    发现CancellaClick按钮没了,而且OK被启用了(那么正好我们再来分析一下OK按钮),用E2A查找OK按钮的地址
    在这里插入图片描述在OD中搜索地址并下断点后点击OK按钮,点击后程序将停在此地址处
    在这里插入图片描述F8单步运行,直到遇见判断跳转指令在这里插入图片描述其程序要跳转(我们就逆其道而为之),显式改变eip为00442dca后,运行程序在这里插入图片描述运行程序后,程序的OK按钮也去除了(哈哈!完成任务)
    在这里插入图片描述
    下面我们就看如何能让程序实现这两个跳转,
    下面我们我们先来分析一下第一处跳转(即在按CancellaClick按钮处的跳转)
    重新加载程序然后运行并输入用户名和序列号,
    在这里插入图片描述
    然后点击Cancella按钮程序停在其按钮事件处理处,我们向下分析看见测试指令前面的关键函数,我们需要分析这个关键函数,F8向下运行并F7进入关键函数
    在这里插入图片描述分析关键函数

    00442AF4  /$  55            push ebp
    00442AF5  |.  8BEC          mov ebp,esp
    00442AF7  |.  83C4 F8       add esp,-0x8
    00442AFA  |.  53            push ebx
    00442AFB  |.  56            push esi
    00442AFC  |.  8955 F8       mov [local.2],edx
    00442AFF  |.  8945 FC       mov [local.1],eax
    00442B02  |.  8B45 FC       mov eax,[local.1]
    00442B05  |.  E8 DE10FCFF   call aLoNg3x_.00403BE8
    00442B0A  |.  33C0          xor eax,eax
    00442B0C  |.  55            push ebp
    00442B0D  |.  68 902B4400   push aLoNg3x_.00442B90
    00442B12  |.  64:FF30       push dword ptr fs:[eax]
    00442B15  |.  64:8920       mov dword ptr fs:[eax],esp
    00442B18  |.  8B45 FC       mov eax,[local.1]
    00442B1B  |.  E8 140FFCFF   call aLoNg3x_.00403A34                   ;  求用户名长度
    00442B20  |.  83F8 05       cmp eax,0x5                              ;  用户名长度不能小于5
    00442B23  |.  7E 53         jle XaLoNg3x_.00442B78
    00442B25  |.  8B45 FC       mov eax,[local.1]
    00442B28  |.  0FB640 04     movzx eax,byte ptr ds:[eax+0x4]          ;  eax = 用户名的第五个字符
    00442B2C  |.  B9 07000000   mov ecx,0x7
    00442B31  |.  33D2          xor edx,edx
    00442B33  |.  F7F1          div ecx
    00442B35  |.  8BC2          mov eax,edx
    00442B37  |.  83C0 02       add eax,0x2                              ;  eax = eax % 7 +2
    00442B3A  |.  E8 E1FEFFFF   call aLoNg3x_.00442A20                   ;  计算eax的阶乘
    00442B3F  |.  8BF0          mov esi,eax
    00442B41  |.  33DB          xor ebx,ebx
    00442B43  |.  8B45 FC       mov eax,[local.1]
    00442B46  |.  E8 E90EFCFF   call aLoNg3x_.00403A34                   ;  计算用户名的长度
    00442B4B  |.  85C0          test eax,eax
    00442B4D  |.  7E 16         jle XaLoNg3x_.00442B65
    00442B4F  |.  BA 01000000   mov edx,0x1
    00442B54  |>  8B4D FC       /mov ecx,[local.1]                       ;  此循环用用户名的每一个字符乘以esi(esi为eax的阶乘),结果存在ebx中
    00442B57  |.  0FB64C11 FF   |movzx ecx,byte ptr ds:[ecx+edx-0x1]
    00442B5C  |.  0FAFCE        |imul ecx,esi
    00442B5F  |.  03D9          |add ebx,ecx
    00442B61  |.  42            |inc edx
    00442B62  |.  48            |dec eax
    00442B63  |.^ 75 EF         jnz XaLoNg3x_.00442B54
    00442B65  |>  2B5D F8       sub ebx,[local.2]                        ;  用 ebx - 局部变量2
    00442B68  |.  81FB 697A0000 cmp ebx,0x7A69
    00442B6E  |.  75 04         jnz XaLoNg3x_.00442B74                   ;  if(ebx == 0x7a69)   ebx=1;  else  ebx=0
    00442B70  |.  B3 01         mov bl,0x1
    00442B72  |.  EB 06         jmp XaLoNg3x_.00442B7A
    00442B74  |>  33DB          xor ebx,ebx
    00442B76  |.  EB 02         jmp XaLoNg3x_.00442B7A
    00442B78  |>  33DB          xor ebx,ebx
    00442B7A  |>  33C0          xor eax,eax
    00442B7C  |.  5A            pop edx
    00442B7D  |.  59            pop ecx
    00442B7E  |.  59            pop ecx
    00442B7F  |.  64:8910       mov dword ptr fs:[eax],edx
    00442B82  |.  68 972B4400   push aLoNg3x_.00442B97
    00442B87  |>  8D45 FC       lea eax,[local.1]
    00442B8A  |.  E8 290CFCFF   call aLoNg3x_.004037B8
    00442B8F  .  C3            retn
    00442B90   .^ E9 E306FCFF   jmp aLoNg3x_.00403278
    00442B95   .^ EB F0         jmp XaLoNg3x_.00442B87
    00442B97   .  8BC3          mov eax,ebx                              ;  ebx =eax,因为要想不跳转 al不为0,即ebx不能为0
    00442B99   .  5E            pop esi
    00442B9A   .  5B            pop ebx
    00442B9B   .  59            pop ecx
    00442B9C   .  59            pop ecx
    00442B9D   .  5D            pop ebp
    00442B9E   .  C3            retn
    
    
    

    if((ebx-局部变量2 )== 0x7a69) 则会使al=1从而达到目的不跳转。
    而ebx是由 用户名的每一位分别乘以 ((用户名第五个字符%7+2)的阶乘)的累加
    而我们需要分析局部变量2怎么来的,
    mov [local.2],edx可得其是由edx得到的,再往关键函数上分析看edx是怎么得到的

    在这里插入图片描述

    00442ECC  |.  8B45 FC       mov eax,[local.1]                        ;  eax = 填写的注册码
    00442ECF  |.  E8 9C47FCFF   call aLoNg3x_.00407670                   ;  将注册码变为10进制形式
    00442ED4  |.  50            push eax                                 ;  返回值入栈
    00442ED5  |.  8D55 FC       lea edx,[local.1]
    00442ED8  |.  8B83 DC020000 mov eax,dword ptr ds:[ebx+0x2DC]
    00442EDE  |.  E8 DD03FEFF   call aLoNg3x_.004232C0
    00442EE3  |.  8B45 FC       mov eax,[local.1]
    00442EE6  |.  5A            pop edx                                  ;  栈中值出栈到edx
    00442EE7  |.  E8 08FCFFFF   call aLoNg3x_.00442AF4
    00442EEC  |.  84C0          test al,al
    
    
    

    所以要想去掉cancella按钮,并启用OK按钮就用户名和注册码应该满足条件为
    用户名的每一位分别乘以 ((用户名第五个字符%7+2)的阶乘)的累加 减去 注册码 等于0x7a69

    如果用户名为987654,则注册码为204103我们重新填写并点击Cancella按钮后程序如我们所愿,在这里插入图片描述
    然后我们分析OK按钮事件处理的第二处判断跳转
    用E2A查看OK按钮事件地址
    在这里插入图片描述在OD中搜索并下断点后,单击OK按钮程序会停在此地址处
    在这里插入图片描述F8向下运行并进入测试转移指令前的关键函数,并分析此关键函数的代码

    00442BA0  /$  55            push ebp
    00442BA1  |.  8BEC          mov ebp,esp
    00442BA3  |.  6A 00         push 0x0
    00442BA5  |.  6A 00         push 0x0
    00442BA7  |.  6A 00         push 0x0
    00442BA9  |.  53            push ebx
    00442BAA  |.  56            push esi
    00442BAB  |.  8BF2          mov esi,edx
    00442BAD  |.  8945 FC       mov [local.1],eax
    00442BB0  |.  8B45 FC       mov eax,[local.1]
    00442BB3  |.  E8 3010FCFF   call aLoNg3x_.00403BE8
    00442BB8  |.  33C0          xor eax,eax
    00442BBA  |.  55            push ebp
    00442BBB  |.  68 672C4400   push aLoNg3x_.00442C67
    00442BC0  |.  64:FF30       push dword ptr fs:[eax]
    00442BC3  |.  64:8920       mov dword ptr fs:[eax],esp
    00442BC6  |.  33DB          xor ebx,ebx
    00442BC8  |.  8D55 F8       lea edx,[local.2]
    00442BCB  |.  8BC6          mov eax,esi
    00442BCD  |.  E8 6E4AFCFF   call aLoNg3x_.00407640
    00442BD2  |.  8D45 F4       lea eax,[local.3]
    00442BD5  |.  8B55 F8       mov edx,[local.2]
    00442BD8  |.  E8 730CFCFF   call aLoNg3x_.00403850
    00442BDD  |.  8B45 F8       mov eax,[local.2]
    00442BE0  |.  E8 4F0EFCFF   call aLoNg3x_.00403A34                   ;  求长度
    00442BE5  |.  83F8 05       cmp eax,0x5
    00442BE8  |.  7E 60         jle XaLoNg3x_.00442C4A
    00442BEA  |.  8B45 F8       mov eax,[local.2]
    00442BED  |.  E8 420EFCFF   call aLoNg3x_.00403A34                   ;  求注册码长度
    00442BF2  |.  8BF0          mov esi,eax
    00442BF4  |.  83FE 01       cmp esi,0x1
    00442BF7  |.  7C 2F         jl XaLoNg3x_.00442C28
    00442BF9  |>  8D45 F4       /lea eax,[local.3]                       ;  此循环将  (注册码的每一个字符乘以本身后)* 注册码长度 % 19 + 0x41
    00442BFC  |.  E8 0310FCFF   |call aLoNg3x_.00403C04                  ;  得到的字符与原字符替代保存到局部变量3中
    00442C01  |.  8D4430 FF     |lea eax,dword ptr ds:[eax+esi-0x1]
    00442C05  |.  50            |push eax
    00442C06  |.  8B45 F8       |mov eax,[local.2]
    00442C09  |.  0FB64430 FF   |movzx eax,byte ptr ds:[eax+esi-0x1]
    00442C0E  |.  F7E8          |imul eax
    00442C10  |.  0FBFC0        |movsx eax,ax
    00442C13  |.  F7EE          |imul esi
    00442C15  |.  B9 19000000   |mov ecx,0x19
    00442C1A  |.  99            |cdq
    00442C1B  |.  F7F9          |idiv ecx
    00442C1D  |.  83C2 41       |add edx,0x41
    00442C20  |.  58            |pop eax
    00442C21  |.  8810          |mov byte ptr ds:[eax],dl
    00442C23  |.  4E            |dec esi
    00442C24  |.  85F6          |test esi,esi
    00442C26  |.^ 75 D1         jnz XaLoNg3x_.00442BF9
    00442C28  |>  8B45 F4       mov eax,[local.3]
    00442C2B  |.  8B55 FC       mov edx,[local.1]
    00442C2E  |.  E8 110FFCFF   call aLoNg3x_.00403B44                   ;  比较eax 和 edx所指的字符串是否相等
    00442C33  |.  75 17         jnz XaLoNg3x_.00442C4C                   ;  if(eax == ecx)     ebx = 1;   else    ebx = 0
    00442C35  |.  8B45 FC       mov eax,[local.1]
    00442C38  |.  8B55 F4       mov edx,[local.3]
    00442C3B  |.  E8 040FFCFF   call aLoNg3x_.00403B44
    00442C40  |.  75 04         jnz XaLoNg3x_.00442C46
    00442C42  |.  B3 01         mov bl,0x1
    00442C44  |.  EB 06         jmp XaLoNg3x_.00442C4C
    00442C46  |>  33DB          xor ebx,ebx
    00442C48  |.  EB 02         jmp XaLoNg3x_.00442C4C
    00442C4A  |>  33DB          xor ebx,ebx
    00442C4C  |>  33C0          xor eax,eax
    00442C4E  |.  5A            pop edx
    00442C4F  |.  59            pop ecx
    00442C50  |.  59            pop ecx
    00442C51  |.  64:8910       mov dword ptr fs:[eax],edx
    00442C54  |.  68 6E2C4400   push aLoNg3x_.00442C6E
    00442C59  |>  8D45 F4       lea eax,[local.3]
    00442C5C  |.  BA 03000000   mov edx,0x3
    00442C61  |.  E8 760BFCFF   call aLoNg3x_.004037DC
    00442C66  .  C3            retn
    00442C67   .^ E9 0C06FCFF   jmp aLoNg3x_.00403278
    00442C6C   .^ EB EB         jmp XaLoNg3x_.00442C59
    00442C6E   .  8BC3          mov eax,ebx                              ;  eax  = ebx,  要想让al不等于0,则ebx不能为0
    00442C70   .  5E            pop esi
    00442C71   .  5B            pop ebx
    00442C72   .  8BE5          mov esp,ebp
    00442C74   .  5D            pop ebp
    00442C75   .  C3            retn
    
    
    

    eax所指的字符串是 (注册码的每一个字符乘以本身后)* 注册码长度 % 19 + 0x41得到的新字符串
    ebx所指的字符串为用户名。

    if(eax所指的字符串 == ebx所指的字符串)
     ebx=1;
    else
     ebx=0;
    

    当ebx==1时,则eax也为1,不发生跳转从而使OK按钮隐藏

    所以用户名等于(注册码的每一个字符乘以本身后)* 注册码长度 % 19 + 0x41得到的字符串
    此时注册码为204103,其对应的用户名为 : AIMEUG
    重新输入用户名点击OK后,程序如我们所愿显示出RingZero的logo
    在这里插入图片描述
    总结:程序逆向可以先采用 “逆其道而为之”的思想,显示改变eip试探程序是否能如我们所愿,如果如我们所愿就返回分析如何满足条件让其自主执行正确的分支。另外有关delphi程序注意使用E2A按钮事件地址转换器从而在OD中追踪相应的按钮事件

  • 相关阅读:
    DJANGO
    前端--BootStrap
    前端--JQuery
    前端--JavaScript
    前端--CSS
    前端--HTML
    python中面试题积累
    python中一些小的知识点
    python中字典的增删改查及相关知识点
    python中列表的增删改查以及其它相关方法
  • 原文地址:https://www.cnblogs.com/revercc/p/13287082.html
Copyright © 2020-2023  润新知