Необходимые инструменты:
* Possible StringData Ref from Data Obj ->"TCSECURE.DLL" | |
|
|
|
:0044812A B8EC7B4900 :0044812F 50 :00448130 B8A0020000 :00448135 50 |
mov eax, 00497BEC push eax mov eax, 000002A0 push eax |
* Reference To: ISARUN.PrepCreateInstance, Ord:0000h | |
|
|
|
:00448136 E8CD250400 :0044813B 0BC0 :0044813D 0F851B000000 |
Call 0048A708 or eax, eax jne 0044815E |
И чуть дальше, уже после джампа:
* Reference To: CAVORT20.Send, Ord:023Eh | |
|
|
|
:004481D0 E86B1E0400 :004481D5 81C408000000 |
Call 0048A040 add esp, 00000008 |
* Reference To: CAVORT20._P2Logic, Ord:03EFh | |
|
|
|
:004481DB E8581E0400 :004481E0 0BC0 :004481E2 7505 :004481E4 E91B000000 |
Call 0048A038 or eax, eax jne 004481E9 jmp 00448204 |
:010316B9 FF5354 :010316BC 0BC0 :010316BE 0F8538000000 |
call [ebx+54] or eax, eax jne 010316FC |
* Reference To: CAVORT20.uiLineNum_RT, Ord:0561h | |
|
|
|
:010316C4 8B1DF8760D01 :010316CA C70324000000 |
mov ebx, dword ptr [010D76F8] mov dword ptr [ebx], 00000024 |
* Possible StringData Ref from Data Obj ->"Invalid evaluation license key." |
:01021011 FF5354 :01021014 0BC0 :01021016 0F8556010000 |
call [ebx+54] or eax, eax jne 01021172 |
:01031BE7 8B4618 :01031BEA 0BC0 :01031BEC 7505 :01031BEE E91C020000 |
mov eax, dword ptr [esi+18] or eax, eax jne 01031BF3 jmp 01031E0F |
* Reference To: CAVORT20.Today, Ord:0298h | |
|
|
|
:01031B2A E8F90D0700 :01031B2F 8945DC :01031B32 8B7508 :01031B35 8B4610 :01031B38 2B45DC :01031B3B 7105 |
Call 010A2928 mov dword ptr [ebp-24], eax mov esi, dword ptr [ebp+08] mov eax, dword ptr [esi+10] sub eax, dword ptr [ebp-24] jno 01031B42 |
:01031B42 3DB9000000 :01031B47 7E05 :01031B49 E90A000000 |
cmp eax, 000000B9 jle 01031B4E jmp 01031B58 |
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:01031B47(C) | |
|
:01031B4E B801000000 :01031B53 E905000000 |
mov eax, 00000001 jmp 01031B5D |
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:01031B49(U) | |
|
:01031B58 B800000000 | mov eax, 00000000 |
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:01031B53(U) | |
|
:01031B5D 0BC0 :01031B5F 7505 :01031B61 E966000000 |
or eax, eax jne 01031B66 jmp 01031BCC |
* Reference To: TCSECURE.StrDecompress | |
: 0102E668 E8CF0E0000 :0102E66D 81C404000000 :0102E673 8945F8 |
| call 0102F53C add esp, 00000004 mov dword ptr [ebp-08], eax |
* Reference To: CAVORT20.uiLineNum_RT, Ord:0561h | |
:0102E676 8B1DF8760D01 :0102E67C C7031D000000 |
| mov ebx, dword ptr [010D76F8] mov dword ptr [ebx], 0000001D |
* Possible StringData Ref from Data Obj ->"TeleCountSecurityLicenseProfile" | |
: 0102E682 B810D70A01 :0102E687 50 :0102E688 8B45F8 :0102E68B 50 |
| mov eax, 010AD710 push eax mov eax, dword ptr [ebp-08] push eax |
* Reference To: TCSECURE.Decrypt | |
:0102E68C E8730F0000 :0102E691 81C408000000 :0102E697 8945F8 |
| call 0102F604 add esp, 00000008 mov dword ptr [ebp-08], eax |
Все! Можно напрямую вызывать функцию MemDecompress из FUNCky60.dll. Теперь залазим в Decrypt... Опять вызывается функция из FUNCky 6 -- _decrypt. Читаем документацию... И что же? Оказывается это простой побайтный xor, только у каждого байта ключа предварительно включается старший бит. Все!
Теперь рассмотрим тот вызов, где создается tc.spv. Аналогично с точностью
до наоборот: MemCompress и _encrypt из FUNCky 6. Про _encrypt мы уже все
знаем - xor - он и в Африке xor, при исследовании при помощи TRW параметров
функции MemCompress выяснилось следующее:
Первый - адрес памяти, "что упаковывать", второй - длина, третий
- буфер, куда складывать сжатую информация, четвертый - 0x138h (Хоть убейте,
не знаю зачем), пятый - буфер, куда записывается кол-во байт после упаковки.
И все! Я написал маленькую программку на Делфях, показывающую полный процес
записи\восстановления tc.spv: (Сорри за отсутствие форматирования, имхо,
и так понятно).
program test;
Uses SysUtils,WIndows;
{$APPTYPE CONSOLE}var
f,f1,f2:file of byte;
i:integer;
b,b1:byte;
len:dword;
p,p1,p2:pointer;
pass:string='TeleCountSecurityLicenseProfile';procedure FDecompress (adr1,adr2,adr3,adr4,adr5:DWORD);stdcall;external 'funcky60.dll' name 'MemDecompress';
procedure FCompress (adr1,adr2,adr3,adr4,adr5:DWORD);stdcall;external 'funcky60.dll' name 'MemCompress';begin
for i:=1 to length(pass) do pass[i]:=chr(ord(pass[i]) or $80);
if paramstr(1)='-in' then begin
AssignFile(f,'tc.spv');
AssignFile(f1,'tc.in.spv');
ReWrite(f1);
ReSet(f);
GetMem(p,FileSize(f));
GetMem(p1,FileSize(f));
GetMem(p2,FileSize(f));
BlockRead(f,p^,FileSize(f));
FDecompress(DWORD(p),FileSize(f),0,0,DWORD(p2));
len:=DWORD(p2^);
FDecompress(DWORD(p),FileSize(f),DWORD(p2),len,DWORD(p1));
for i:=1 to len do begin
b:=Byte(pointer(Integer(p2)+i-1)^);
b1:=i mod 31;
if b1=0 then b1:=31;
b:=b xor ord(pass[b1]);
Byte(pointer(Integer(p2)+i-1)^):=b;
end;
BlockWrite(f1,p2^,len);
CloseFile(f);
CloseFile(f1);
end
else if paramstr(1)='-out' then begin
AssignFile(f1,'tc.in.spv');
AssignFile(f2,'tc.out.spv');
ReSet(f1);
ReWrite(f2);
GetMem(p,FileSize(f1)+1024);
GetMem(p1,FileSize(f1)+1024);
GetMem(p2,FileSize(f1)+1024);
BlockRead(f1,p2^,FileSize(f1));
len:=FileSize(f1);
for i:=1 to len do begin
b:=Byte(pointer(Integer(p2)+i-1)^);
b1:=i mod 31;
if b1=0 then b1:=31;
b:=b xor ord(pass[b1]);
Byte(pointer(Integer(p2)+i-1)^):=b;
end;
FCompress(DWORD(p2),len,DWORD(p),$138,DWORD(p1));
BlockWrite(f2,p^,DWORD(p1^));
CloseFile(f1);
CloseFile(f2);
end;
end.
Ну что же. Скармливаем ей tc.spv и получаем такое на выходе:
001=33858
002=1
003=33858
004=33825
005=CA,TF,FM,AR
006=0050
007=3382533825
008=1
009=1
010=65535
011=0
012=0
013=33825
014=33825
015=25508096
:0102F355 3DB3030000 :0102F35A 0F8578000000 |
cmp eax, 000003B3 jne 0102F3D8 |
Теперь мы можем самостоятельно изменять параметры и модифицировать keyfile. Итак, методом научного тыка выяснились все параметры в KeyFile (я приведу их в виду схемы):
Перепечатано с разрешения www.uofg.com.ua
Материалы находятся на сайте http://cracklab.narod.ru/doc/