以下五处调用看是否注册(入口地址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;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!