目录
aida64 记录
最近换了电脑,微星主板带了aida64程序,结果只能试用60天 0.0
aida64.exe程序信息
32位程序,编译器: Borland Delphi(7)[-]
IDR
Delphi程序直接祭出大杀器IDR
定位注册窗口和注册事件
object Form_EnterProductKey: TForm_EnterProductKey
Left = 285
Top = 314
BorderStyle = bsDialog
Caption = 'Enter Product Key'
ClientHeight = 265
ClientWidth = 355
Color = clBtnFace
ParentFont = True
OldCreateOrder = False
Position = poOwnerFormCenter
OnCreate = FormCreate
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object TabControl_EnterProductKey: TTabControl
Left = 7
Top = 7
Width = 341
Height = 222
TabOrder = 0
TabStop = False
object Label_EnterCommandLine: TLabel
Left = 64
Top = 25
Width = 144
Height = 13
Caption = 'Please enter your product key:'
Transparent = True
end
object Image_Simple: TImage
Left = 16
Top = 16
Width = 32
Height = 32
Transparent = True
end
object Label_InvalidKey: TLabel
Left = 64
Top = 99
Width = 52
Height = 13
Cursor = crHandPoint
Caption = 'Invalid Key'
ParentShowHint = False
ShowHint = True
Transparent = True
Visible = False
OnClick = Label_InvalidKeyClick
end
object Label_Expired: TLabel
Left = 64
Top = 80
Width = 87
Height = 13
Caption = 'License is expired!'
Transparent = True
Visible = False
end
object Edit_ProductKey: TEdit
Left = 64
Top = 48
Width = 261
Height = 21
TabOrder = 0
OnChange = UpdateScreen
end
end
object Button_Cancel: TButton
Left = 273
Top = 235
Width = 75
Height = 23
Cancel = True
Caption = 'Cancel'
ModalResult = 2
TabOrder = 2
end
object Button_OK: TButton
Left = 192
Top = 235
Width = 75
Height = 23
Caption = 'OK'
Default = True
ModalResult = 1
TabOrder = 1
end
end
可定位输入框事件TForm_EnterProductKey.UpdateScreen
TForm_EnterProductKey_UpdateScreen
结合IDA 进行注册分析
ida 相关设置请参考Delphi程序逆向反汇编技巧小记 | Lyon's blog (youngroe.com)
TForm_EnterProductKey_UpdateScreen 对输入进行‘-’,‘_’,' '字符的去除后,校验长度是否为0x19 (25),之后调用check_F85B98进行关键判断
check_F85B98
相关函数checksum_F85B0C、KGEncode3_F8593C、Power_F85A58可参考后面的python代码
// &maintenance_period, // 维护期限
// &authorization_period, // 授权期限
// &purchase_date, // 购买日期
// &number_of_licenses); // 授权数
bool __userpurge check_F85B98@<al>(
char *serial@<eax>,
int *version_id@<edx>,
__int32 a3@<ecx>,
double st7_0@<st0>,
_BYTE *out_error_ROGtype,
_BYTE *out_error_revoked,
_BYTE *out_error_black,
_BYTE *check_checksum,
int *maintenance_period,
int *authorization_period,
double *purchase_date,
int *number_of_licenses)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
part3__1 = (int *)_InterlockedExchange((volatile __int32 *)&serial1, a3);
version_id1 = version_id;
serial1 = serial;
LStrAddRef_Pointer((int)serial);
v45 = &savedregs;
v44[1] = (unsigned int)&loc_F8633C;
v44[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v44);
check_success = 0;
*version_id1 = 0;
*part3__1 = 0;
*number_of_licenses = 0;
*purchase_date = 0.0;
*authorization_period = 0;
*maintenance_period = 0;
*check_checksum = 0;
*out_error_black = 0;
*out_error_revoked = 0;
*out_error_ROGtype = 0;
Trim_AnsiString(serial1, (char *)&temp);
while ( LStrPos_Integer(&str___1339[1], temp) )
{
v12 = LStrPos_Integer(&str___1339[1], temp);
System::__linkproc__ LStrDelete(&temp, v12, 1);
}
// _
while ( LStrPos_Integer(&str___1340[1], temp) )
{
v13 = LStrPos_Integer(&str___1340[1], temp);
System::__linkproc__ LStrDelete(&temp, v13, 1);
}
while ( LStrPos_Integer(&str___1341[1], temp) )
{
v14 = LStrPos_Integer(&str___1341[1], temp);
System::__linkproc__ LStrDelete(&temp, v14, 1);
}
while ( LStrPos_Integer(&str___1342[1], temp) )
{
v15 = LStrPos_Integer(&str___1342[1], temp);
System::__linkproc__ LStrDelete(&temp, v15, 1);
}
while ( LStrPos_Integer(&str___1343[1], temp) )
{
v16 = LStrPos_Integer(&str___1343[1], temp);
System::__linkproc__ LStrDelete(&temp, v16, 1);
}
Trim_AnsiString(temp, (char *)&v62);
UpperCase_AnsiString(v62, &src);
Delphi_Copy_4059C4(src, 1, 0x19, (char *)&temp);
if ( temp )
{
// delphi字符串 index从1开始??
// 取前0x18位
Delphi_Copy_4059C4(temp, 1, 24, dest);
hash = checksum_F85B0C(*(char **)dest);
KGEncode3_F8593C((unsigned __int16)hash % 0x9987u, (int)&v60);
Delphi_Copy_4059C4(v60, 2, 1, v61);
v43 = *(int **)v61;
Delphi_Copy_4059C4(temp, 25, 1, v58);
// 最后一位作为校验位,
Delphi_CompareCall_4058B0((int)v43, *(int **)v58);
*check_checksum = v18;
if ( *check_checksum )
{
// revoked
v19 = 0x262;
v20 = (int *)&revoked_keys_119C054;
do
{
Delphi_CompareCall_4058B0(*v20, (int *)temp);//校验是否为被撤销的注册码
if ( v18 )
{
*out_error_revoked = 1;
goto LABEL_92;
}
++v20;
--v19;
}
while ( v19 );
UpperCase_AnsiString(temp, &v83);
LStrInsert(&str___1339[1], &v83);
LStrInsert(&str___1339[1], &v83);
LStrInsert(&str___1339[1], &v83);
LStrInsert(&str___1339[1], &v83);
LStrLAsg(&v80, v83);//重新拼接成 XXXXX-XXXXX-XXXXX-XXXXX-XXXXX的格式
v43 = (int *)LStrLen_Integer(v80);
v21 = (char *)LStrToPChar_PChar(v80);
//计算md5
md5_A41434(v21, (int)v43, (char *)&md5lowerstr);
if ( LStrLen_Integer((int)md5lowerstr) == 0x20 )
{
v22 = 0;
v23 = &v64;
do
{
Delphi_Copy_4059C4(md5lowerstr, 2 * v22 + 1, 2, v57);
*v23 = strTdig_A35498(*(int *)v57);
++v22;
++v23;
}
while ( v22 != 0x10 );
v24 = 0x75C;
v25 = &revoked_15D6ECC;
//检验md5值是否为被禁数据中
while ( *v25 != v64
|| v25[1] != v65
|| v25[2] != v66
|| v25[3] != v67
|| v25[4] != v68
|| v25[5] != v69
|| v25[6] != v70
|| v25[7] != v71
|| v25[8] != v72
|| v25[9] != v73
|| v25[0xA] != v74
|| v25[0xB] != v75
|| v25[0xC] != v76
|| v25[0xD] != v77
|| v25[0xE] != v78
|| v25[0xF] != v79 )
{
v25 += 0x10;
if ( !--v24 )
goto LABEL_44;
}
*out_error_revoked = 1;
}
else
{
LABEL_44:
v26 = 0x1470;
v27 = black_117ACF4;
do
{
LStrFromString(&v56, v27);
Delphi_CompareCall_4058B0(v56, (int *)temp);
if ( v18 )
{
*out_error_black = 1;
goto LABEL_92;
}
v27 = (char ***)((char *)v27 + 0x1A);
--v26;
}
while ( v26 );
if ( LStrLen_Integer((int)md5lowerstr) == 0x20 )
{
v28 = 0;
v29 = &v64;
do
{
Delphi_Copy_4059C4(md5lowerstr, 2 * v28 + 1, 2, v55);
*v29 = strTdig_A35498(*(int *)v55);
++v28;
++v29;
}
while ( v28 != 0x10 );
v30 = 0x43A4F;
v31 = (char *)&black_119C9DC;
while ( *v31 != v64
|| v31[1] != v65
|| v31[2] != v66
|| v31[3] != v67
|| v31[4] != v68
|| v31[5] != v69
|| v31[6] != v70
|| v31[7] != v71
|| v31[8] != v72
|| v31[9] != v73
|| v31[0xA] != v74
|| v31[0xB] != v75
|| v31[0xC] != v76
|| v31[0xD] != v77
|| v31[0xE] != v78
|| v31[0xF] != v79 )
{
v31 += 0x10;
if ( !--v30 )
goto LABEL_70;
}
*out_error_black = 1;
}
else
{
LABEL_70:
//下面开始注册解析
Delphi_Copy_4059C4(temp, 23, 2, v54);
xordata = Power_F85A58(*(int *)v54);
Delphi_Copy_4059C4(temp, 1, 2, v53);
part1_ = Power_F85A58(*(int *)v53);
*version_id1 = (unsigned __int8)xordata ^ part1_ ^ 0xBF;
Delphi_Copy_4059C4(temp, 3, 2, v52);
part3_tmp = Power_F85A58(*(int *)v52);
*part3__1 = (unsigned __int8)xordata ^ part3_tmp ^ 0xED;
Delphi_Copy_4059C4(temp, 5, 2, v51);
part5_ = (unsigned __int8)xordata ^ (unsigned __int16)Power_F85A58(*(int *)v51) ^ 0x77;
Delphi_Copy_4059C4(temp, 7, 2, v50);
part7_ = (unsigned __int8)xordata ^ (unsigned __int16)Power_F85A58(*(int *)v50) ^ 0xDF;
Delphi_Copy_4059C4(temp, 9, 4, v49);
*number_of_licenses = xordata ^ Power_F85A58(*(int *)v49) ^ 0x4755;
Delphi_Copy_4059C4(temp, 13, 4, v48);
purchase_date_ = xordata ^ Power_F85A58(*(int *)v48) ^ 0x7CC1;
Delphi_Copy_4059C4(temp, 17, 3, v47);
*authorization_period = (unsigned __int8)xordata ^ Power_F85A58(*(int *)v47) ^ 0x3FD;
Delphi_Copy_4059C4(temp, 20, 3, v46);
*maintenance_period = (unsigned __int8)xordata ^ Power_F85A58(*(int *)v46) ^ 0x935;
if ( *part3__1 != 999
&& part5_ <= 100u
&& part7_ <= 100u
&& *number_of_licenses != 0xFFFF
&& *authorization_period < 3653
&& *maintenance_period < 3653 )
{
year = ((purchase_date_ >> 9) & 0x1F) + 0x7D3;
month = (purchase_date_ >> 5) & 0xF;// month
day = purchase_date_ & 0x1F;
if ( year >= 0x7D4u && year <= 0x833u && month && (unsigned __int16)month <= 0xCu && day )
{
v43 = &savedregs;
v42[1] = (unsigned int)&loc_F862B1;
v42[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v42);
*purchase_date = Sysutils::EncodeDate(year, month, day);
__writefsdword(0, v42[0]);
}
check_success_1 = *version_id1 == 2
&& *part3__1 >= 100
&& *part3__1 < 990
&& *number_of_licenses
&& *number_of_licenses < 798
&& *purchase_date != 0.0
&& *maintenance_period;
check_success = check_success_1;
}
}
}
}
}
LABEL_92:
__writefsdword(0, v44[0]);
v45 = (int *)&loc_F86343;
LStrArrayClr((int *)v46, 0x12);
LStrArrayClr(&v80, 4);
LStrClr(&serial1);
return check_success;
}
py
from datetime import datetime, timedelta
from typing import Union
import random
import hashlib
def Checksum_F85B0C(buf: Union[str | bytes])->int:
if isinstance(buf, str):
buf = buf.encode()
hash_val = 0
len_val = len(buf)
for i in range(len_val):
hash_val ^= (buf[i] << 8)
for j in range(8):
if (hash_val & 0x8000) == 0:
hash_val *= 2
else:
hash_val = (2*hash_val) ^ 0x8201
hash_val &= 0xffff
return hash_val
def KGEncode3_F8593C(hash_val)->str:
table_117ACD0 = "DY14UF3RHWCXLQB6IKJT9N5AGS2PM8VZ7E" #
out = ''
if hash_val <= 0x9987:
v2 = hash_val % 0x484 // 0x22
v3 = hash_val % 0x484 % 0x22
if hash_val // 0x484 <= 0x21 and v2 <= 0x21 and v3 <= 0x21:
out = table_117ACD0[hash_val // 0x484] + \
table_117ACD0[v2]+table_117ACD0[v3]
else:
# KGEncode3: Invalid Argument!
out = "Invalid Argument!"
return out
def Power_F85A58(data: bytes)->int:
table_117ACD0 = b"DY14UF3RHWCXLQB6IKJT9N5AGS2PM8VZ7E"
ret = 0
sz = len(data)
for i in range(sz):
for j in range(34):
if data[i] == table_117ACD0[j]:
tmp = 34**(sz-i-1)
ret += int(j*tmp)
return ret
def Inverse_Power_F85A58(num: int, data_length: int)->bytes:
if isinstance(num, bytes):
num = int.from_bytes(num, 'little')
table_117ACD0 = b"DY14UF3RHWCXLQB6IKJT9N5AGS2PM8VZ7E"
result = []
while num > 0:
remainder = num % 34
result.insert(0, table_117ACD0[remainder])
num = num // 34
# 补齐位数
while len(result) < data_length:
result.insert(0, table_117ACD0[0]) # 假设缺失的位数用表中的第一个字符填充
return bytes(result)
def GenDate(year, month, day)->int:
date = day
date |= month << 5
date |= (year-2003) << 9
return date
def ParseDate(date: int):
year = ((date >> 9) & 0x1f)+2003
month = (date >> 5) & 0xf
day = date & 0x1f
info = '[+]year:%d,month:%d,day:%d' % (year, month, day)
return (info, year, month, day)
def keygen(version_id: int, year: int, month: int, day: int, xordata: int = random.randint(0, 0xff), part3_=random.randint(100, 998), part5_=random.randint(0, 100), part7_=random.randint(0, 100), number_of_licenses=797, authorization_period=3650, maintenance_period=3650):
serial = bytearray()
# xordata=0x66#random.randint(0,0xff)
print('[+]xordata:', hex(xordata))
# version_id=2
tmp = Inverse_Power_F85A58(version_id ^ xordata ^ 0xbf, 2)
serial[:2] = tmp
# part3_=random.randint(100,998)
print('[+]random part3_:', part3_)
# !=999 >=100
tmp = Inverse_Power_F85A58(part3_ ^ xordata ^ 0xed, 2)
serial[2:4] = tmp
# part5_=random.randint(0,100)
# <=100
print('[+]random part5_:', part5_)
tmp = Inverse_Power_F85A58(part5_ ^ xordata ^ 0x77, 2)
serial[4:6] = tmp
# part7_=random.randint(0,100)
# <=100
tmp = Inverse_Power_F85A58(part7_ ^ xordata ^ 0xdf, 2)
print('[+]random part7_:', part7_)
serial[6:8] = tmp
# number_of_licenses=797
# 授权数 !=0xffff <0x31e 798d
tmp = Inverse_Power_F85A58(number_of_licenses ^ xordata ^ 0x4755, 4)
serial[8:12] = tmp
purchase_date = GenDate(year, month, day)
# 购买日期
tmp = Inverse_Power_F85A58(purchase_date ^ xordata ^ 0x7CC1, 4)
serial[12:16] = tmp
# <0xe45 3653d
# authorization_period=3650
# 授权期限
tmp = Inverse_Power_F85A58(authorization_period ^ xordata ^ 0x3FD, 3)
serial[16:19] = tmp
# maintenance_period=3651
# 维护期限
tmp = Inverse_Power_F85A58(maintenance_period ^ xordata ^ 0x935, 3)
serial[19:22] = tmp
tmp = Inverse_Power_F85A58(xordata, 2)
serial[22:24] = tmp
sum = Checksum_F85B0C(serial[:0x18])
checksum = KGEncode3_F8593C(sum % 0X9987)
serial[24:25] = checksum[1].encode()
# print('[#]serial:',serial.decode())
return serial
def check(serial: Union[bytes | str]):
if isinstance(serial, str):
serial = serial.encode()
serial = serial.replace(b'-', b'')
result = False
sum = Checksum_F85B0C(serial[:0x18])
checksum = KGEncode3_F8593C(sum % 0X9987)
if serial[0x18] != ord(checksum[1]):
print('[!]serial checksum error')
return result
xordata = Power_F85A58(serial[22:24])
print('\t[-]xordata:', hex(xordata))
tmp = Power_F85A58(serial[:2])
version_id = (xordata ^ tmp ^ 0xbf) & 0xffffffff
# version_id 2
print('\t[-]version_id:', (version_id))
tmp = Power_F85A58(serial[2:4])
part3_ = (xordata ^ tmp ^ 0xed) & 0xffffffff
# >=0x64 100d <0x3de 990d
print('\t[-]part3_:', (part3_))
tmp = Power_F85A58(serial[4:6])
part5_ = (xordata ^ tmp ^ 0x77) & 0xffffffff
# <=0x64 100d
print('\t[-]part5_:', (part5_))
tmp = Power_F85A58(serial[6:8])
part7_ = (xordata ^ tmp ^ 0xdf) & 0xffffffff
# <=0x64 100d
print('\t[-]part7_:', (part7_))
tmp = Power_F85A58(serial[8:12])
number_of_licenses = (xordata ^ tmp ^ 0x4755) & 0xffffffff
# !=0xffff <0x31e
print('\t[-]number_of_licenses:', (number_of_licenses))
tmp = Power_F85A58(serial[12:16])
purchase_date = (xordata ^ tmp ^ 0x7CC1) & 0xffffffff
info, year, month, day = ParseDate(purchase_date)
print('\t[-]purchase_date_:', hex(purchase_date), info)
start_date = datetime(year, month, day)
tmp = Power_F85A58(serial[16:19])
authorization_period = (xordata ^ tmp ^ 0x3fd) & 0xffffffff
# <0xe45 3653d
print('\t[-]authorization_period:', (authorization_period),
start_date + timedelta(days=authorization_period))
tmp = Power_F85A58(serial[19:22])
maintenance_period = (xordata ^ tmp ^ 0x935) & 0xffffffff
# <3653
print('\t[-]maintenance_period:', (maintenance_period),
start_date + timedelta(days=maintenance_period))
while True:
if number_of_licenses == 0xffff:
print("[!]error-->number_of_licenses!=0xffff")
break
if part3_ != 999 and part5_ <= 0x64 and part7_ <= 0x64 and authorization_period < 3653 and maintenance_period < 3653:
if version_id != 2:
print('[!]version error:', version_id)
break
if part3_ < 100 or part3_ > 990:
print('[!]part3 error:', part3_)
break
if number_of_licenses == 0 or number_of_licenses >= 798:
print('[!]number_of_licenses error:', number_of_licenses)
break
result = True
print('[#]success!')
else:
print('[!]error-->part3/5/7_')
break
break
return result
if __name__ == '__main__':
# serial=keygen(2,2024,3,24,0x66,100,100,100,0x123,3650,3650)
now = datetime.now()
current_year = now.year
current_month = now.month
current_day = now.day
serial = keygen(2, current_year, current_month, current_day)
print('\n[#]serial:', serial.decode())
print('\n\n###############################CHECK###############################')
check(serial)
标签:__,v31,aida64,temp,v25,int,Delphi
From: https://www.cnblogs.com/DirWang/p/18093190