首页
社区
课程
招聘
[原创]XXX软件的五处验证和联网验证的破解方法
发表于: 2012-7-23 09:42 11535

[原创]XXX软件的五处验证和联网验证的破解方法

2012-7-23 09:42
11535

以下五处调用看是否注册(入口地址4093A0)
* Referenced by a CALL at Addresses:
0040904B:登录密码
0040916E:邮箱设置
004092BC:
004094AF:启动时的第二次验证
0040BFB1:启动时的第一次验证
|:0040904B   , :0040916E   , :004092BC   , :004094AF   , :0040BFB1   
|
:004093A0 6AFF                    push FFFFFFFF
:004093A2 6850AE4A00              push 004AAE50
:004093A7 64A100000000            mov eax, dword ptr fs:[00000000]
:004093AD 50                      push eax
:004093AE 64892500000000          mov dword ptr fs:[00000000], esp
:004093B5 83EC10                  sub esp, 00000010
:004093B8 56                      push esi
:004093B9 6A01                    push 00000001
:004093BB 51                      push ecx
:004093BC 8BCC                    mov ecx, esp
:004093BE 89642410                mov dword ptr [esp+10], esp

* Possible StringData Ref from Data Obj ->"00"
                                  |
:004093C2 687C3D4C00              push 004C3D7C
:004093C7 E83C690800              call 0048FD08
:004093CC 51                      push ecx
:004093CD C744242800000000        mov [esp+28], 00000000
:004093D5 8BCC                    mov ecx, esp
:004093D7 89642418                mov dword ptr [esp+18], esp

* Possible StringData Ref from Data Obj ->"Power"
                                  |
:004093DB 68743D4C00              push 004C3D74
:004093E0 E823690800              call 0048FD08
:004093E5 51                      push ecx
:004093E6 C644242C01              mov [esp+2C], 01
:004093EB 8BCC                    mov ecx, esp
:004093ED 89642420                mov dword ptr [esp+20], esp

* Possible StringData Ref from Data Obj ->"TTSet"
                                  |
:004093F1 68803D4C00              push 004C3D80
:004093F6 E80D690800              call 0048FD08
:004093FB 8D442414                lea eax, dword ptr [esp+14]
:004093FF C744242CFFFFFFFF        mov [esp+2C], FFFFFFFF
:00409407 50                      push eax
:00409408 E8A3DCFFFF              call 004070B0
:0040940D 8BC8                    mov ecx, eax
:0040940F 81C1C0000000            add ecx, 000000C0
:00409415 E8D6E3FFFF              call 004077F0
:0040941A 8B542404                mov edx, dword ptr [esp+04]
:0040941E 33C9                    xor ecx, ecx
:00409420 8B72F8                  mov esi, dword ptr [edx-08]
:00409423 85F6                    test esi, esi
:00409425 7E10                    jle 00409437

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409435(C)
|
:00409427 8A0411                  mov al, byte ptr [ecx+edx]
:0040942A 3C30                    cmp al, 30
:0040942C 7C37                    jl 00409465
:0040942E 3C39                    cmp al, 39
:00409430 7F33                    jg 00409465
:00409432 41                      inc ecx
:00409433 3BCE                    cmp ecx, esi
:00409435 7CF0                    jl 00409427

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409425(C)
|
:00409437 52                      push edx
:00409438 E81ABE0000              call 00415257
:0040943D 83C404                  add esp, 00000004
:00409440 8D4C2404                lea ecx, dword ptr [esp+04]
:00409444 8BF0                    mov esi, eax
:00409446 C744241CFFFFFFFF        mov [esp+1C], FFFFFFFF
:0040944E E847680800              call 0048FC9A
:00409453 8BC6                    mov eax, esi =========>返回前最后一次动eax
:00409455 8B4C2414                mov ecx, dword ptr [esp+14]
:00409459 64890D00000000          mov dword ptr fs:[00000000], ecx
:00409460 5E                      pop esi
:00409461 83C41C                  add esp, 0000001C
:00409464 C3                      ret
把mov eax, esi改成mov al,1上程序无论如何走,eax都为1就可以了
(因为只有这个是两字节变eax为1的汇编指令)

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040942C(C), :00409430(C)
|
:00409465 8D4C2404                lea ecx, dword ptr [esp+04]
:00409469 C744241CFFFFFFFF        mov [esp+1C], FFFFFFFF
:00409471 E824680800              call 0048FC9A
:00409476 8B4C2414                mov ecx, dword ptr [esp+14]
:0040947A 33C0                    xor eax, eax =========>返回前最后一次动eax
:0040947C 64890D00000000          mov dword ptr fs:[00000000], ecx
:00409483 5E                      pop esi
:00409484 83C41C                  add esp, 0000001C
:00409487 C3                      ret
同样把xor eax, eax改成mov al,1上程序无论如何走,eax都为1就可以了
以下是IDA分析的代码和上面程序的VC++伪代码
text:00409446                 mov     [esp+20h+var_4], 0FFFFFFFFh
.text:0040944E                 call    sub_48FC9A
.text:00409453                 mov     eax, esi
.text:00409455                 mov     ecx, [esp+20h+var_C]
.text:00409459                 mov     large fs:0, ecx
.text:00409460                 pop     esi
.text:00409461                 add     esp, 1Ch
.text:00409464                 retn
.text:00409465 ; ---------------------------------------------------------------------------
.text:00409465
.text:00409465 loc_409465:                             ; CODE XREF: sub_4093A0+8Cj
.text:00409465                                         ; sub_4093A0+90j
.text:00409465                 lea     ecx, [esp+20h+Str]
.text:00409469                 mov     [esp+20h+var_4], 0FFFFFFFFh
.text:00409471                 call    sub_48FC9A
.text:00409476                 mov     ecx, [esp+20h+var_C]
.text:0040947A                 xor     eax, eax
.text:0040947C                 mov     large fs:0, ecx
.text:00409483                 pop     esi
.text:00409484                 add     esp, 1Ch
.text:00409487                 retn
.text:00409487 sub_4093A0      endp

__int32 __thiscall sub_4093A0(void *lpDefault)
{
  int v1; // ecx@1
  int v2; // esi@1
  const CHAR *v3; // ecx@1
  const CHAR *v4; // ecx@1
  char v5; // al@2
  __int32 result; // eax@5
  __int32 v7; // esi@5
  const CHAR *v8; // [sp-10h] [bp-30h]@1
  const CHAR *v9; // [sp-Ch] [bp-2Ch]@1
  const CHAR *v10; // [sp-8h] [bp-28h]@1
  signed int v11; // [sp-4h] [bp-24h]@1
  char *Str; // [sp+4h] [bp-1Ch]@1
  const CHAR **v13; // [sp+8h] [bp-18h]@1
  const CHAR **v14; // [sp+Ch] [bp-14h]@1
  const CHAR **v15; // [sp+10h] [bp-10h]@1
  int v16; // [sp+1Ch] [bp-4h]@1

  v11 = 1;
  v10 = (const CHAR *)lpDefault;
  v13 = &v10;
  sub_48FD08(L"0");
  v9 = v3;
  v16 = 0;
  v14 = &v9;
  sub_48FD08("Power");
  v8 = v4;
  LOBYTE(v16) = 1;
  v15 = &v8;
  sub_48FD08("TTSet");
  v16 = -1;
  AfxGetApp();
  sub_4077F0((int)&Str, v8, v9, v10, v11);
  v1 = 0;
  v2 = *((_DWORD *)Str - 2);
  if ( v2 <= 0 )
  {
LABEL_5:
    v7 = atol(Str);
    v16 = -1;
    sub_48FC9A(&Str);
    result = v7;==============>这里改变了返回值
  }
  else
  {
    while ( 1 )
    {
      v5 = Str[v1];
      if ( v5 < 48 )
        break;
      if ( v5 > 57 )
        break;
      ++v1;
      if ( v1 >= v2 )
        goto LABEL_5;
    }
    v16 = -1;
    sub_48FC9A(&Str);
    result = 0;===============>这里改变了返回值
  }
  return result;
}
这样密码就可以显示全了,登录密码也可以设置了,但邮箱还不可用,提示单机版

查找附近的代码:
|:00409175(C)
|
:004091A0 83F801                  cmp eax, 00000001 ===>这是一个致命的比较
把cmp eax, 1改成eax,0就可以了
:004091A3 6A00                    push 00000000
:004091A5 7522                    jne 004091C9
:004091A7 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"你购买的是单机版,不能设置邮箱接收"
                                  |
:004091A9 6808424C00              push 004C4208
:004091AE E82F230900              call 0049B4E2
:004091B3 5E                      pop esi
:004091B4 8B8C24C0000000          mov ecx, dword ptr [esp+000000C0]
:004091BB 64890D00000000          mov dword ptr fs:[00000000], ecx
:004091C2 81C4CC000000            add esp, 000000CC
:004091C8 C3                      ret

经过这样修改,所有功能限制搞定,完美收工!!!

经过跟踪发现:
启动时第一次在0040BFB1处验证,跟进关键验证CALL发现它在找如下文件:
"C:\Documents and Settings\All Users\Documents\tw2\ttmsg.ini"
如果找不到就认为没有注册
004077F0  此处用于取TTMsg.INI里的数据,以下为VC++伪代码
void *__thiscall sub_4077F0(int this, void *a2, LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, char a6)
{
  const CHAR *v6; // ST14_4@1
  void *v7; // esi@3
  const CHAR *v8; // eax@3
  CHAR Src; // [sp+Ch] [bp-10Ch]@1
  int v11; // [sp+114h] [bp-4h]@1

  v6 = *(const CHAR **)(this + 8);
  v11 = 3;
  GetPrivateProfileStringA(lpAppName, lpKeyName, lpDefault, &Src, 0x100u, v6);
  if ( a6 && strcmp(&Src, (const char *)sub_4900CA(0)) )
  {
    v8 = (const CHAR *)sub_407E00(&Src);
    v7 = a2;
    sub_48FD08(a2, v8);
  }
  else
  {
    v7 = a2;
    sub_48FD08(a2, &Src);
  }
  LOBYTE(v11) = 2;
  sub_48FC9A(&lpAppName);
  LOBYTE(v11) = 1;
  sub_48FC9A(&lpKeyName);
  LOBYTE(v11) = 0;
  sub_48FC9A(&lpDefault);
  return v7;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 6
支持
分享
最新回复 (4)
雪    币: 31
活跃值: (48)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
沙发。
潜力贴留名。
2012-7-23 12:05
0
雪    币: 118
活跃值: (106)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
好帖好帖!
您输入的信息太短,您发布的信息至少为 6 个字符
2012-7-23 12:32
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大牛,膜拜,求教
2012-7-23 12:57
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
除了几个变态的壳,其实软件破解挺简单的,最新的一些平台都是脚本语言,没有破解可言,动手就是明码,而更多软件越来越多卖的就是思路,就是服务,所以,从本质上讲,破解是会最终走向消亡的,而编程也会成为地摊,这就是我们不愿看到的未来,但事实是的确如此.
2012-7-30 14:38
0
游客
登录 | 注册 方可回帖
返回
//