飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

楼主: 野猫III

[原创] KeyMakeMe 20091021

[复制链接]

该用户从未签到

发表于 2009-10-21 22:21:13 | 显示全部楼层
占楼,分析看看
PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-2-2 10:20
  • 签到天数: 38 天

    [LV.5]常住居民I

    发表于 2009-10-21 22:44:06 | 显示全部楼层
    用户名:hhwsljb
    注册码:52C92
    没学过编程,不会写注册机。。。/:L /:L /:L
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-6-18 08:20
  • 签到天数: 279 天

    [LV.8]以坛为家I

    发表于 2009-10-21 23:48:32 | 显示全部楼层
    诶。。现在的技术只能爆破。。算法位置知道,只是算法分析不会。。抽空补习补习。。
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-10-22 00:08:51 | 显示全部楼层
    好热闹啊,支持猫兄!/:good
    name:pptppt
    code:1=7>6   也不知道这个是什么算法?应该是1=7-6吧,呵呵,开个玩笑!

    算法:F1(x)=F2(y),这样就可以做到内存中不出现明码了,但函数可逆的话,逆推就可以得到注册码了。/:017

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?加入我们

    x

    评分

    参与人数 1飘云币 +40 收起 理由
    野猫III + 40 意料之外的注册码~~~

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2017-10-25 13:07
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2009-10-22 00:14:55 | 显示全部楼层
    楼上 就是是高手啊呵呵
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-10-22 00:32:12 | 显示全部楼层
    code:1=7>6   也不知道这个是什么算法?应该是1=7-6吧,呵呵,开个玩笑!



    1=7>6 等式是成立的  7本来就大于6 /:017  逆推需要技巧,目前在研究中。。。。/:L

    先贴个伪代码给大家看看(加了点注释,凑合着看吧)

    对话框的回调函数伪代码如下:

    signed int __stdcall DialogFunc(HWND a1, UINT a2, WPARAM a3, LPARAM a4)
    {
      int v4; // eax@6
      signed int result; // eax@8
      int v6; // eax@22
      __int16 v7; // ST0E_2@22
      HICON v8; // eax@4
      HWND v9; // eax@4
      LONG v10; // eax@4
      HWND v11; // eax@4
      LONG v12; // eax@4
      LRESULT v13; // eax@8
      HFONT v14; // eax@8
      DWORD v15; // eax@8
      HWND hWnd; // [sp+4Ch] [bp-4h]@4
      HANDLE ho; // [sp+48h] [bp-8h]@8
      char pv; // [sp+Ch] [bp-44h]@8
      char v19; // [sp+21h] [bp-2Fh]@8
      int  s; // [sp+50h] [bp+0h]@21
      int v21; // [sp+44h] [bp-Ch]@22
      __int16 v22; // [sp+40h] [bp-10h]@24

      if ( a2 == 16 )
      {
        EndDialog(a1, 0);
        return 1;
      }
      if ( a2 == 272 )
      {
        v8 = LoadIconA(hInstance, (LPCSTR)0x3E8);
        SendMessageA(a1, 0x80u, 1u, (LPARAM)v8);
        hCursor = LoadCursorA(hInstance, (LPCSTR)0x7D0);
        v9 = GetDlgItem(a1, 110);
        hWnd = v9;
        v10 = SetWindowLongA(v9, -4, (LONG)sub_40135B);
        SetWindowLongA(hWnd, -21, v10);
        v11 = GetDlgItem(a1, 111);
        hWnd = v11;
        v12 = SetWindowLongA(v11, -4, (LONG)sub_40135B);
        SetWindowLongA(hWnd, -21, v12);
        return 1;
      }
      if ( a2 == 312 )
      {
        v4 = GetDlgCtrlID((HWND)a4);
        if ( v4 != 110 && v4 != 111 )
        {
          result = 0;
        }
        else
        {
          v13 = SendMessageA((HWND)a4, 0x31u, 0, 0);
          ho = (HANDLE)v13;
          GetObjectA((HANDLE)v13, 60, &pv);
          v19 = 0;
          v14 = CreateFontIndirectA((const LOGFONTA *)&pv);
          ho = v14;
          SelectObject((HDC)a3, v14);
          SetTextColor((HDC)a3, 0xFF0000u);
          v15 = GetSysColor(15);
          SetBkColor((HDC)a3, v15);
          DeleteObject(ho);
          result = (signed int)GetStockObject(5);
        }
        return result;
      }
      if ( a2 != 273 )
        return 0;
      if ( a3 != 1 )
      {
        if ( a3 == 2 )
          EndDialog(a1, 0);
        return 1;
      }
      if ( !GetDlgItemTextA(a1, 101, &String, 200) )         //以上都是跟窗口消息有关的,从这里开始就是算法部份了
      {
    LABEL_29:
        SetDlgItemTextA(a1, 104, "输入的序列号不正确");
        return 1;
      }
      if ( byte_403000 != 2 && byte_403000 != 3 )   //byte_403000存放的值是用来判断程序是使用keymark注册机三种对话框样式的其中一种
      {
        if ( byte_403000 == 3 && !GetDlgItemTextA(a1, 103, byte_403350, 200) )
          goto LABEL_29;
      }
      else
      {
        if ( !GetDlgItemTextA(a1, 102, byte_403288, 200) )
          goto LABEL_29;
      }
      dword_4031BC = (int)& s;
      if ( (char)((unsigned int)lstrlenA(byte_403288) >> 2) > 2 )  //注册码长度不能大于11(汗,我猜是不能大于8吧 codelen / 4 < 2)
        goto LABEL_36;
      v21 = sub_401494((unsigned __int8 *)byte_403288) + 2009;     //调用sub_401494 CALL 将注册码计算得到某个值再+2009 记为 h1
      ho = 0;
      v6 = lstrlenA(&String);
      v7 = v6;
      do
      {
        LOWORD(ho) = *(_BYTE *)(v6 + 4207039) + (_WORD)ho;   //这个循环是依次将用户名各位上的字符ASCII值进行累加记sun
        LOBYTE(v6) = (_BYTE)v6 - 1;
      }
      while ( (_BYTE)v6 );
      LOWORD(hWnd) = v7;                                   //v7=用户名长度
      v22 = (unsigned __int8)String;
      __asm
      {
        finit
        fild    word ptr [ebp+ho]                          
        fidiv   word ptr [ebp+hWnd]                        // sun / 用户名长度
        frndint                                            // 取整(sun) (四舍五入)
        fiadd   word ptr [ebp+hWnd]                        // 取整(sun)+用户名长度
        fild    word ptr [ebp+ho]
        fild    [ebp+var_10]
        fxch    st(1)                              
        fprem                                              // sun mod 用户名第一个字符的ASCII值
        fmulp   st(1), st                                  // 上面的求的的余数 * 用户名第一个字符的ASCII值
        faddp   st(1), st                                  // 上面的积 + (取整(sun)+用户名长度)
        fld     flt_403042                                 // 403042 存放个浮点数 121.0
        fmulp   st(1), st                                  // 121.0 * (上面的积 + (取整(sun)+用户名长度)) 记为h2
        fisub   [ebp+var_C]                                // h1=h2-h1  看是否为0
        fist    [ebp+var_C]                              
      }
      if ( v21 )                                           //为0则注册成功
    LABEL_36:
        ExitProcess(0);
      sub_4014E4((int)"Q29uZ3JhdHVsYXRl", (int)Text);     //调用解密字符串的CALL
      sub_4014E4((int)"R29vZCBKb2Ih", (int)Caption);
      MessageBoxA(0, Text, Caption, 0x40u);
      while ( & s != (int *)dword_4031BC )
        ;
      SetDlgItemTextA(a1, 104, "BY WildCatIII 091021");
      return 1;
    }

    sub_401494的伪代码如下:

    int sub_401494(unsigned __int8 *a1)  //*a1  传入的参数就是存放注册码的首地址
    {
      unsigned __int8 *v1; // edi@1
      char v2; // dl@3
      int v3; // ebx@3
      unsigned __int8 *v4; // edi@3
      signed int v5; // esi@3
      unsigned __int8 v6; // al@4
      char v7; // al@5
      char v9; // al@2
      int v10; // esi@3

      v1 = a1;
      do
        v9 = *v1++;
      while ( v9 );
      v10 = a1 - v1;
      v3 = 0;
      v4 = a1;
      v2 = 0;
      v5 = ~v10;  //v5就是注册码的长度
      while ( v5 )
      {
        v6 = *v4;
        if ( *v4 < 0x41u )   //0x41 就是字符"A"的ASCII值  
        {
          v7 = v6 - 48;      //小于0x41 就将字符的ASCII值减去0x30(字符"0"的ASCII值)
        }
        else
        {
          v2 = 32 * ((v6 < 0x57u) + v2);    //0x57 就是字符"W"的ASCII值,这里用v6和0x57比较,作用是如果v6小于0x57 用1和v2相加,如果不小于就用0和v2相加
          v7 = v2 + v6 - 87;
        }
         (v7 & 0xF) << 4 * ((_BYTE)v5 - 1);  //这里相当于v3 += (v7 mod 16)^(4*(注码长度-1))
        ++v4;
        --v5;
      }
      return v3;

    }


    最后告诉大家一个秘密就是:
    F8到下面这条指令时
    004012BA   .  DA65 F4       fisub   dword ptr [ebp-0xC]

    看下St(0)的值 或看下"提示信息"窗口(就是反汇编窗口与数据窗口之间那个地方)中"st=" 后面的数值
    用这个数值减下2009 然后转成十六进制就是注册码了(那个sub_401494的CALL有点心猥琐/:017)


    [ 本帖最后由 hflywolf 于 2009-10-25 10:07 编辑 ]

    评分

    参与人数 2威望 +80 飘云币 +240 收起 理由
    HDd1145 + 40 + 40 写得很好
    野猫III + 40 + 200 基础真扎实,用的什么工具分析的?我的代码 ...

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2017-10-25 13:07
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2009-10-22 01:24:34 | 显示全部楼层
    楼上都不知道该有什么来称呼你/:good /:good /:good
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2023-10-11 19:12
  • 签到天数: 64 天

    [LV.6]常住居民II

    发表于 2009-10-22 01:50:15 | 显示全部楼层
    明天尝试下看看能否逆出一样的KeyMakeMe不
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-10-22 08:09:00 | 显示全部楼层
    来晚了哈

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?加入我们

    x
    PYG19周年生日快乐!
  • TA的每日心情

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

    [LV.3]偶尔看看II

    发表于 2009-10-22 09:02:26 | 显示全部楼层
    楼上的狼好猛,全逆出来了~
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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