吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2221|回复: 1
收起左侧

[原创] 160 crackme 之 007

[复制链接]
Otoboku 发表于 2021-1-17 00:05

起手

  • 查壳 Borland Delphi v3.0
  • 直接用idr吧

任务

  • 让下边两个按钮不可见

这回学聪明了,先总体看看

一共三个事件,Registerz,Again(原本影藏的按钮),Canella

Registerz,Again中都有改变按钮可见的代码.只要这么走完就可以使得两按钮不可见了.

;Registerz中的
CODE:00442FC2 xor     edx, edx
CODE:00442FC4 mov     eax, [ebx+2CCh] ; 'TPrincipale.Registerz:TButton'
CODE:00442FCA call    TControl_SetVisible
CODE:00442FCF mov     dl, 1
CODE:00442FD1 mov     eax, [ebx+2E8h] ; 'TPrincipale.Again:TButton'
CODE:00442FD7 call    TControl_SetVisible
CODE:00442FDC xor     edx, edx

;Again中的
CODE:0044315B xor     edx, edx
CODE:0044315D mov     eax, [ebx+2E8h] ; 'TPrincipale.Again:TButton'
CODE:00443163 call    TControl_SetVisible
CODE:00443168 lea     edx, [ebp+var_8] ;  
CODE:0044316B mov     eax, ds:g_strangeHwnd ; this
CODE:00443170 call    TControl_GetText
CODE:00443175 lea     eax, [ebp+var_8]
CODE:00443178 call    UniqueString
CODE:0044317D mov     byte ptr [eax+5], 65h ; 'e'
CODE:00443181 lea     eax, [ebp+var_8]
CODE:00443184 call    UniqueString
CODE:00443189 mov     byte ptr [eax+6], 64h ; 'd'
CODE:0044318D lea     eax, [ebp+var_8]

总结下

code中没有字符,并且大于0 ->  00442FB9 call    sub_4429A8 返回非零值 ->Registerz不可见, again可见->  00443152 call    sub_4429A8 返回非零值->again不可见

发现两个过程对比函数一样的.但是和ds:dword_445830这个全局变量有关

CODE:00443148 mov     ecx, [ebp+var_C] ; pName
CODE:0044314B mov     edx, esi        ; Numcode
CODE:0044314D mov     eax, ds:dword_445830 ; 诡异的全局变量,初始值为0.
CODE:00443152 call    sub_4429A8

;而且对比完成后全局变量被清零了,也就是说走完后一样要想办法让他重新被赋值
CODE:00442FC2 xor     edx, edx
CODE:00442FC4 mov     eax, [ebx+2CCh] ; 'TPrincipale.Registerz:TButton'
CODE:00442FCA call    TControl_SetVisible
CODE:00442FCF mov     dl, 1
CODE:00442FD1 mov     eax, [ebx+2E8h] ; 'TPrincipale.Again:TButton'
CODE:00442FD7 call    TControl_SetVisible
CODE:00442FDC xor     edx, edx
CODE:00442FDE mov     eax, [ebx+2D8h] ; 'TPrincipale.Nome:TEdit'
CODE:00442FE4 mov     ecx, [eax]
CODE:00442FE6 call    dword ptr [ecx+60h] ; 'TControl.SetEnabled'
CODE:00442FE9 xor     eax, eax
CODE:00442FEB mov     ds:dword_445830, eax    ; 又被变成零了
CODE:00442FF0 jmp     short loc_44300C

Registerz,again事件中,当数字中混有字母,转换出问题的时后,会有一个函数会改变全局变量的值而且都指向sub_442A8C,而且是赋值全局变量的

CODE:00442F70 lea     edx, [ebp+var_TmpStr]
CODE:00442F73 mov     eax, [ebx+2DCh] ; 'TPrincipale.Codice:TEdit'
CODE:00442F79 call    TControl_GetText
CODE:00442F7E mov     eax, [ebp+var_TmpStr] ; this
CODE:00442F81 call    sub_442A8C
CODE:00442F86 mov     ds:dword_445830, eax

4429A8

注册机RegCode2的代码就是还原的4429A8 ,明显,当全局变量 gVal=0的时候 v4永远等于0.这个函数永远返回0

希望寄托于442A8C

442A8C

注册机RegCode2的代码就是还原的442A8C, 他可以返回值赋值给全局变量.全局变量有值了,4429A8才会正常工作

总结2

那么流程修正为

  • 在注册码框输入一个有字母的注册码1,长度大于5.

  • 点注册,会提示错误.

  • 然后输入注册名,注册码2点注册,注册按钮消失

  • 在注册码框输入一个有字母的注册码1,长度大于5.

  • 点Again,提示错误

  • 注册码点注册2,Again按钮消失.任务完成

最后看看4429A8比较处的函数

也就是这个.

    nRet = abs32(v4) % 666666;
    Numcode = Numcode % 80 + Numcode / 89 + 1;
    if ( nRet == Numcode )
      LOBYTE(nRet) = 1;
    else
      return 0;

改写下 y=  x % 80 + x / 89 + 1 变成一个大家都懂的函数
1610685517119.png

  • 这是一个类周期函数(姑且叫周期吧).函数图像是一个越来越高的锯齿.
    • 每一个锯齿长度是80,每89函数锯齿会上移一个单位
    • 那么每一个周期80最低点为nRet最多出现在89*(nRet-1)之前
    • 每一个周期80最高点为nRet,至少出现在89*(nRet-1-80)之后.
    • 那么明显满足条件的解不唯一.在区间全部整数算一遍,就可以得到所有的解.
    • 本来可以用直线方程只要计算80次就可以得到全部解了,但是,我的头已经晕了.还是给PC自己去试6000+次算了.

注册机

#include <iostream>
#include <math.h>

#define LStrLen strlen
#define abs32 abs

int RegCode1(const char* pCodeString)
{
    int nRet, v2, v3;

    if (LStrLen(pCodeString) <= 5)
    {
        nRet = 0;
    }
    else
    {
        nRet = 891;
        v2 = LStrLen(pCodeString) - 1;
        if (v2 > 0)
        {
            v3 = 1;
            do
            {
                nRet += pCodeString[v3 - 1] * (pCodeString[v3] % 0x11u + 1);
                ++v3;
                --v2;
            } while (v2);
        }
    }
    return abs32(nRet % 29000);
}

int RegCode2(const char* pName, int gVal)
{
    int nRet=0, v4, v5, v15, v7, v6;
    if (LStrLen(pName) <= 4)
    {
        ;
    }
    else
    {
        v4 = 0;
        v5 = LStrLen(pName);
        if (v5 > 0)
        {
            v15 = v5;
            v6 = 1;
            do
            {
                v7 = LStrLen(pName);
                if (v7 >= 1)
                {
                    do
                        v4 += gVal * *(pName + v7-- - 1) * *(pName + v6 - 1);
                    while (v7);
                }
                ++v6;
                --v15;
            } while (v15);
        }
        int nStr = abs32(v4) % 666666;
        std::cout << "寻找可能Code:" << std::endl;
        for (int Numcode = 89 * (nStr - 1 - 80); Numcode < 89 * (nStr - 1); Numcode++)
        {
            if (nStr == Numcode % 80 + Numcode / 89 + 1)
            {
                std::cout << "  " << Numcode << std::endl;
                nRet= Numcode;
            }
        }
    }
    return nRet;
}

int main()
{
    const char* pCodeInt = "Hello World!";
    //注册码1=Wow!so_cool
   int gVal=  RegCode1("Wow!so_cool");
   //用户名=Otoboku 注册码2=Code
   int Code = RegCode2("Otoboku", gVal);

   std::cout << gVal << " " << Code << std::endl;
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wsf5201314 发表于 2021-1-17 15:56
学习一下 感谢楼主分享经验
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 20:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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