NESmaker 4.5.9 记录
NESmaker_4_5_9_note
第一部分:c# 主程序pj
NESMaker.exe c#程序,没有保护
PE32
操作系统: Windows(95)[I386, 32 位, GUI]
链接程序: Microsoft linker(48.00)
编译器: Visual C#
语言: C#
库: .NET(v4.0.30319)
dnspy启动
MysticSearchToolMainDialog
MysticSearchesTool.MysticSearchToolMainDialog.MysticSearchToolMainDialog() : void @06000C6E
public MysticSearchToolMainDialog()
{
string cultureOveride = this.GetCultureOveride();
bool flag = !string.IsNullOrEmpty(cultureOveride);
if (flag)
{
try
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureOveride);
}
catch (Exception)
{
}
}
List<byte> list = new List<byte>();
list.Add(90);
list.Add(48);
list.Add(76);
list.Add(20);
list.Add(127);
list.Add(202);
list.Add(143);
list.Add(217);
list.Add(125);
list.Add(65);
list.Add(207);
list.Add(221);
list.Add(20);
list.Add(155);
list.Add(146);
list.Add(199);
string text = "";
foreach (byte b in list)
{
text += string.Format("{0:X2}", b);
}
this.SecDNAHash = text;
list = new List<byte>();
list.Add(162);
list.Add(82);
list.Add(86);
list.Add(102);
list.Add(25);
list.Add(105);
list.Add(230);
list.Add(161);
list.Add(53);
list.Add(153);
list.Add(89);
list.Add(127);
list.Add(160);
list.Add(4);
list.Add(54);
list.Add(227);
string text2 = "";
foreach (byte b2 in list)
{
text2 += string.Format("{0:X2}", b2);
}
this.SecDNA32Hash = text2;
this.ProductKey = "P0003024-QAB:D2fhogQkHWOB0jVkEtrS3lr6hgNe";
this.ProductKey += "/";
this.ProductKey += "O7pAkxsv2OVHTT6AHyWdPJv1KIwLpUoPh";
this.ProductKey += "/";
this.ProductKey += "D1N+BVQ5jGQ1a+nJpptW0SX";
MysticSearchToolMainDialog.ScreenBorderGhostTiles = 1;
MysticSearchToolMainDialog.DefaultGraphicBank = 1;
MysticSearchToolMainDialog.MainTileBag = new Dictionary<Tuple<int, int>, Dictionary<int, GraphicAsset>>();
MysticSearchToolMainDialog.ScreenTileBag = new Dictionary<Tuple<int, int>, Dictionary<int, GraphicAsset>>();
MysticSearchToolMainDialog.MainHighResTileBag = new Dictionary<Tuple<int, int>, Dictionary<int, GraphicAsset>>();
MysticSearchToolMainDialog.ScreenHighResTileBag = new Dictionary<Tuple<int, int>, Dictionary<int, GraphicAsset>>();
MysticSearchToolMainDialog.PathTileBag = new Dictionary<Tuple<int, int>, Dictionary<int, GraphicAsset>>();
MysticSearchToolMainDialog.MonsterTileBag = new Dictionary<Tuple<int, int>, Dictionary<int, GraphicAsset>>();
MysticSearchToolMainDialog.PathInfoGroupGuidBag = new Dictionary<Tuple<int, int>, List<Guid>>();
MysticSearchToolMainDialog.SpecialTileBag = new Dictionary<int, Dictionary<int, GraphicAsset>>();
MysticSearchToolMainDialog.GameObjectTileBag = new Dictionary<int, GraphicAsset>();
MysticSearchToolMainDialog.HudTileBag = new Dictionary<int, GraphicAsset>();
this.InitializeComponent();
MysticSearchToolMainDialog.Singleton = this;
this.BaseTitle = this.Text;
Environment.CurrentDirectory = this.GetAppFolder();
bool flag2 = !this.VerifyDNADLL();
if (!flag2)
{
bool flag3 = !this.VerifyDNACert();
if (!flag3)
{
this.FinalInit();
this.LoadColorPickerNames();
this.PreparePlugins();
this.CheckForCommandLineLoad();
}
}
}
VerifyDNADLL
MysticSearchesTool.MysticSearchToolMainDialog.VerifyDNADLL() : bool @06000C83
private bool VerifyDNADLL()
{
string b = DNA.MD5File("dna.dll");
bool flag = this.SecDNAHash == b || this.SecDNA32Hash == b;
bool result;
if (flag)
{
result = true;
}
else
{
this.Text += " - Missing License DLL";
this.fileToolStripMenuItem.Enabled = false;
this.projectToolStripMenuItem.Enabled = false;
this.testToolStripMenuItem.Enabled = false;
result = false;
}
return result;
}
VerifyDNACert
MysticSearchesTool.MysticSearchToolMainDialog.VerifyDNACert() : bool @06000C87
// Token: 0x06000C87 RID: 3207 RVA: 0x0007C4E8 File Offset: 0x0007A6E8
private bool VerifyDNACert()
{
string path_name = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\NESMaker\\NESMaker.lic";
path_name = "C:\\Users\\Public\\NESMaker\\NESMaker.CDM";
DNA.DNA_SetCDMPathName(path_name);
int num = DNA.DNA_Validate(this.ProductKey);
bool flag = num > 0;
bool result;
if (flag)
{
string text = DNA.DNA_Error(num);
this.fileToolStripMenuItem.Enabled = false;
this.projectToolStripMenuItem.Enabled = false;
this.testToolStripMenuItem.Enabled = false;
result = false;
}
else
{
result = true;
}
return result;
}
activateNESMakerToolStripMenuItem_Click
MysticSearchesTool.MysticSearchToolMainDialog.activateNESMakerToolStripMenuItem_Click(object, EventArgs) : void @06000D7D
private void activateNESMakerToolStripMenuItem_Click(object sender, EventArgs e)
{
int num = DNA.DNA_Validate(this.ProductKey);
bool flag = num > 0;
if (flag)
{
string text = DNA.DNA_Error(num);
this.fileToolStripMenuItem.Enabled = false;
this.projectToolStripMenuItem.Enabled = false;
this.testToolStripMenuItem.Enabled = false;
ActivationDialog activationDialog = new ActivationDialog();
DialogResult dialogResult = activationDialog.ShowDialog();
bool flag2 = dialogResult == DialogResult.OK;
if (flag2)
{
int num2 = DNA.DNA_Activate(this.ProductKey, activationDialog.Code, activationDialog.Password, activationDialog.Email);
bool flag3 = num2 > 0;
if (flag3)
{
string str = DNA.DNA_Error(num2);
string text2 = "There was an error activating NESMaker: " + str;
MessageBox.Show(text2, Resources.s_ActivationError, MessageBoxButtons.OK);
}
else
{
string s_DLG_Activate = Resources.s_DLG_Activate;
MessageBox.Show(s_DLG_Activate, Resources.s_ActivationSuccess, MessageBoxButtons.OK);
bool flag4 = num > 0;
if (flag4)
{
this.FinalInit();
this.fileToolStripMenuItem.Enabled = true;
this.projectToolStripMenuItem.Enabled = true;
this.testToolStripMenuItem.Enabled = true;
StupidStartupDialog stupidStartupDialog = new StupidStartupDialog();
stupidStartupDialog.ShowDialog();
}
}
}
}
else
{
string s_DLG_alreadyActivate = Resources.s_DLG_alreadyActivate;
MessageBox.Show(s_DLG_alreadyActivate, Resources.s_ActivationSuccess, MessageBoxButtons.OK);
}
}
HackCheck
MysticSearchesTool.MysticSearchToolMainDialog.HackCheck() : bool @06000C86
private bool HackCheck()
{
string secDNAHash = this.SecDNAHash;
string secDNA32Hash = this.SecDNA32Hash;
this.SecDNAHash = "";
this.SecDNA32Hash = "";
string text = this.Text;
bool flag = this.VerifyDNADLL();
bool result;
if (flag)
{
this.IsHacked = true;
this.Text += " - Missing License DLL";
this.fileToolStripMenuItem.Enabled = false;
this.projectToolStripMenuItem.Enabled = false;
this.testToolStripMenuItem.Enabled = false;
result = false;
}
else
{
this.SecDNAHash = secDNAHash;
this.SecDNA32Hash = secDNA32Hash;
this.Text = text;
this.fileToolStripMenuItem.Enabled = true;
this.projectToolStripMenuItem.Enabled = true;
this.testToolStripMenuItem.Enabled = true;
result = true;
}
return result;
}
InitRootTree
MysticSearchesTool.MysticSearchToolMainDialog.InitRootTree() : void @06000C8F
protected void InitRootTree()
{
this.HackCheck();
TreeNode treeNode = null;
bool flag = MysticSearchToolMainDialog.RootNodes.ContainsKey("Plugins");
if (flag)
{
treeNode = MysticSearchToolMainDialog.RootNodes["Plugins"];
}
……
pj点
修改VerifyDNACert 函数直接return true,当然直接修改MysticSearchToolMainDialog()也可,方法很多,不再赘述。
不需要修改dna.dll,如果修改dna.dll会导致文件md5值改变从而使主程序VerifyDNADLL校验失败
// Token: 0x06000D8E RID: 3470 RVA: 0x00007680 File Offset: 0x00005880
private bool VerifyDNACert()
{
return true;
}
第二部分:software_DNA CDM验证分析
dna.dll DNA_Validate 使用ProductKey 传入的rsa_512公钥进行签名验证,
故想要通过.cdm过校验需要修改ProductKey (作为参数传入),使cdm使用的私钥与ProductKey 中的公钥相匹配。
所以不如直接在c#主程序上做文章。下文仅对cdm校验流程进行记录
software_DNA 有关信息可参考官网链接:
https://www.softworkz.com/support/overviews/kb_art_overviews.aspx
这里只分析DNA_Validate 函数,即cdm 许可文件的验证函数。
DNA_Validate
DNA_Validate>Validate_check_with_ProductKey_110029890>wrap_check_cdm_with_product_key_1100295E0
__int64 __fastcall DNA_Validate(_BYTE *ProductKey)
{
_QWORD *v2; // rax
__int64 v4; // [rsp+28h] [rbp-78h] BYREF
__int64 v5; // [rsp+30h] [rbp-70h]
_BYTE v6[80]; // [rsp+38h] [rbp-68h] BYREF
_BYTE v7[24]; // [rsp+88h] [rbp-18h] BYREF
v4 = 0LL;
v2 = (_QWORD *)sub_11000FC50(1, (__int64)v6, (__int64)v7);
v5 = allocate_110012650(v2);
if ( !(_DWORD)v5 )
{
str_clear_110009FC0(&v4);
v4 = 0LL;
str_11000A4F0(&v4, ProductKey);
LODWORD(ProductKey) = Validate_check_with_ProductKey_110029890(v4);
}
sub_11000FFE0();
str_clear_110009FC0(&v4);
v4 = 0LL;
if ( v5 )
sub_1100101B0();
return (unsigned int)ProductKey; // 需要<=0
}
Validate_check_with_ProductKey_110029890
// 需要<=0
__int64 __fastcall Validate_check_with_ProductKey_110029890(__int64 ProductKey)
{
unsigned int v1; // ebx
_QWORD *v2; // rax
__int64 _110012650; // [rsp+28h] [rbp-78h]
_BYTE v5[80]; // [rsp+30h] [rbp-70h] BYREF
_BYTE v6[24]; // [rsp+80h] [rbp-20h] BYREF
__int64 v7; // [rsp+98h] [rbp-8h] BYREF
v7 = ProductKey;
STR_REF_11000A020(ProductKey);
v2 = (_QWORD *)sub_11000FC50(1, (__int64)v5, (__int64)v6);
_110012650 = allocate_110012650(v2);
if ( !(_DWORD)_110012650 )
v1 = wrap_check_cdm_with_product_key_1100295E0(v7);
sub_11000FFE0();
str_clear_110009FC0(&v7);
if ( _110012650 )
sub_1100101B0();
return v1;
}
wrap_check_cdm_with_product_key_1100295E0
// 需要<=0
__int64 __fastcall wrap_check_cdm_with_product_key_1100295E0(__int64 ProductKey)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
v20 = ProductKey;
STR_REF_11000A020(ProductKey);
v18 = 0LL;
v17 = 0LL;
v16 = 0LL;
v9 = 0LL;
v1 = (_QWORD *)sub_11000FC50(1, (__int64)v14, (__int64)v15);
_110012650 = allocate_110012650(v1);
if ( !(_DWORD)_110012650 )
{
v2 = (_QWORD *)sub_11000FC50(1, (__int64)v11, (__int64)v12);
v10 = allocate_110012650(v2);
if ( !(_DWORD)v10 )
{
v19 = check_cdm_with_product_key_110029020(v20);
if ( v19 <= 0 )
{
sub_110019360(&v18, ccdm_path_1102B0500);
sub_1100196A0(&v16, ccdm_path_1102B0500);
sub_110019610((__int64 *)&v17, ccdm_path_1102B0500);
str_clear_110009FC0((__int64 *)&v9);
v9 = 0LL;
v3 = v17;
if ( v17 )
v3 = (const CHAR *)*((_QWORD *)v17 - 1);
v4 = v16;
if ( v16 )
v4 = *(_QWORD *)(v16 - 8);
str_COPY_11000A980((__int64 *)&v9, (__int64)v17, 1LL, (signed __int64)&v3[-v4]);
STR_REF_11000A020((__int64)v9);
str_clear_110009FC0((__int64 *)&v17);
v17 = v9;
str_clear_110009FC0((__int64 *)&v9);
v9 = 0LL;
v6 = v18;
v7 = v17;
v8 = ".lic";
str_cat_11000A220((__int64 *)&v9, &v6, 2LL);
if ( x_file_exist_1101A9A10((__int64)v9) )
{
str_clear_110009FC0((__int64 *)&v9);
v9 = 0LL;
v6 = v18;
v7 = v17;
v8 = ".lic";
str_cat_11000A220((__int64 *)&v9, &v6, 2LL);
x_DeleteFileA_110025C80(v9);
}
}
}
sub_11000FFE0();
if ( v10 )
sub_1100101B0();
}
sub_11000FFE0();
str_clear_110009FC0((__int64 *)&v9);
v9 = 0LL;
str_clear_110009FC0(&v18);
v18 = 0LL;
str_clear_110009FC0((__int64 *)&v17);
v17 = 0LL;
str_clear_110009FC0(&v16);
v16 = 0LL;
str_clear_110009FC0(&v20);
if ( _110012650 )
sub_1100101B0();
return (unsigned int)v19;
}
check_cdm_with_product_key_110029020
主要步骤:
-
分隔ProductKey
'-' 前面 为.dna的文件名(??与software_DNA 网络验证地址配置相关)
‘-’后面部分为 RSA_PUBKEY
-
cdm 文件解密
-
cdm内容解析、签名验证、字段验证
// 需要<=0
__int64 __fastcall check_cdm_with_product_key_110029020(__int64 ProductKey)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
ProductKey_1 = ProductKey;
STR_REF_11000A020(ProductKey);
part1 = 0LL;
part2 = 0LL;
PROTECTION_LEVEL = 0LL;
v9 = 0LL;
v1 = (_QWORD *)sub_11000FC50(1, (__int64)v14, (__int64)v15);
_110012650 = allocate_110012650(v1);
if ( !(_DWORD)_110012650 )
{
if ( (unsigned __int8)sub_1101A28F0(ProductKey_1) )
{
code = 99;
// P0003024
find_substr_1101A2230((int)&part1, ProductKey_1, 1, '-');
find_substr_1101A2230((int)&part2, ProductKey_1, 2, '-');// QAB:D2fhogQkHWOB0jVkEtrS3lr6hgNe/O7pAkxsv2OVHTT6AHyWdPJv1KIwLpUoPh/D1N+BVQ5jGQ1a+nJpptW0SX
if ( (unsigned __int8)find_and_check_dna_1101ACD70(part2, ModuleFile_dir_path_1102B04F0, (__int64)part1) )// rdx:"E:\\crack\\NESmaker_4_5_9\\NESmaker_4_5_x\\", 00000001102B04F0:&"E:\\crack\\NESmaker_4_5_9\\NESmaker_4_5_x\\"
{
// DNA disable
code = -2;
}
else
{
TCDM_obj = TCDM_1101AA940(0LL, (unsigned __int64)&TCDM_11027D5A8);
TCDM_sig_check_1101AAB60((__int64)TCDM_obj, part2, 0LL);
v16 = TCDM_check_MACHINE_ID_and_EXPIRY_DATE_1101AB9E0((__int64)TCDM_obj);// 返回错误代码,成功时返回0
if ( v16 )
{
sub_11000ED20((__int64)TCDM_obj);
code = v16;
}
else
{
v2 = (_QWORD *)sub_11000FC50(1, (__int64)v11, (__int64)v12);
v10 = allocate_110012650(v2);
if ( !(_DWORD)v10 )
{
str_clear_110009FC0(&v9);
v9 = 0LL;
// PROTECTION_LEVEL
list_get_1101AB3D0((__int64)TCDM_obj, (__int64)&v9, (__int64)"PROTECTION_LEVEL");
str_1101A2600((__int64)&PROTECTION_LEVEL, v9);
str_clear_110009FC0(&v9);
v9 = 0LL;
list_get_1101AB3D0((__int64)TCDM_obj, (__int64)&v9, (__int64)"VALIDATION_DATE");
if ( (unsigned __int8)not_printable_characters_1101A2560(v9) )
{
// 无VALIDATION_DATE 字段时
// ACTIVATION_DATE
// REACTIVATION_DATE
v3 = parse_date_1101ABC70((__int64)TCDM_obj);
if ( get_date_110020180() == v3 )
dna_net_check_1102AD8B0 = 0;
}
else
{
_1101AB430 = tcdm_get_1101AB430((__int64)TCDM_obj, (__int64)"VALIDATION_DATE");
if ( get_date_110020180() == _1101AB430 )
dna_net_check_1102AD8B0 = 0; // 当前日期匹配VALIDATION_DATE 时
}
if ( !str_cmp_11000A690(PROTECTION_LEVEL, (__int64)"1") )
dna_net_check_1102AD8B0 = 0;
if ( !str_cmp_11000A690(PROTECTION_LEVEL, (__int64)"3") )
{
str_clear_110009FC0(&v9);
v9 = 0LL;
list_get_1101AB3D0((__int64)TCDM_obj, (__int64)&v9, (__int64)"VALIDATION_WARNING");
if ( !(unsigned __int8)not_printable_characters_1101A2560(v9) )
{
date_110020180 = get_date_110020180();
if ( tcdm_get_1101AB430((__int64)TCDM_obj, (__int64)"VALIDATION_WARNING") <= date_110020180 )
dna_net_check_1102AD8B0 = 1;
}
}
if ( exist_NESMaker_dna_dna_1102AD8C0 )
dna_net_check_1102AD8B0 = 1;
if ( dna_net_check_1102AD8B0 )
{
get_date_110020180();
sub_1101AB690((__int64)TCDM_obj, (__int64)"VALIDATION_DATE");
sub_1101AB8A0((__int64)TCDM_obj, (__int64)"SIGNATURE");
if ( (unsigned __int8)sub_1101AAE10((__int64)TCDM_obj) )
{
code = net_check_110027FC0((void *)"V", part1, (__int64 *)&TCDM_obj, 1u);
if ( code <= 0 )
save_cdm_1101AB190((__int64)TCDM_obj);
}
else
{ // error
code = 18; // The directory or file for storing the License file (CDM) is write-protected. Please ensure that you have read-write permissions for this directory or file and try again
}
}
else
{
code = 0;
}
if ( (!str_cmp_11000A690(PROTECTION_LEVEL, (__int64)"1")
|| !str_cmp_11000A690(PROTECTION_LEVEL, (__int64)"2"))
&& (code == 1 || code == 2) )
{
code = 0;
}
if ( !str_cmp_11000A690(PROTECTION_LEVEL, (__int64)"3") && (unsigned int)(code - 1) < 2 )
{
str_clear_110009FC0(&v9);
v9 = 0LL;
list_get_1101AB3D0((__int64)TCDM_obj, (__int64)&v9, (__int64)"VALIDATION_LIMIT");
if ( !(unsigned __int8)not_printable_characters_1101A2560(v9) )
{
v6 = get_date_110020180();
if ( tcdm_get_1101AB430((__int64)TCDM_obj, (__int64)"VALIDATION_LIMIT") < v6 )
goto LABEL_44;
}
str_clear_110009FC0(&v9);
v9 = 0LL;
list_get_1101AB3D0((__int64)TCDM_obj, (__int64)&v9, (__int64)"VALIDATION_WARNING");
if ( !(unsigned __int8)not_printable_characters_1101A2560(v9) )
{
v7 = get_date_110020180();
if ( tcdm_get_1101AB430((__int64)TCDM_obj, (__int64)"VALIDATION_WARNING") > v7 )
{
code = 0;
}
else
{
code = -1;
str_clear_110009FC0(&v9);
v9 = 0LL;
list_get_1101AB3D0((__int64)TCDM_obj, (__int64)&v9, (__int64)"VALIDATION_LIMIT");
STR_REF_11000A020(v9);
str_clear_110009FC0(&qword_1102AD870);
qword_1102AD870 = v9;
}
}
}
}
while ( 1 )
{
sub_11000FFE0();
dna_net_check_1102AD8B0 = code > 0;
sub_11000ED20((__int64)TCDM_obj);
if ( !v10 || v10 == 2 )
break;
sub_1100101B0();
LABEL_44:
v10 = 2LL;
}
}
}
}
else
{
code = 5;
}
}
sub_11000FFE0();
str_clear_110009FC0(&v9);
v9 = 0LL;
str_clear_110009FC0((__int64 *)&part1);
part1 = 0LL;
str_clear_110009FC0((__int64 *)&part2);
part2 = 0LL;
str_clear_110009FC0(&PROTECTION_LEVEL);
PROTECTION_LEVEL = 0LL;
str_clear_110009FC0(&ProductKey_1);
if ( _110012650 )
sub_1100101B0();
return (unsigned int)code;
}
TCDM_sig_check_1101AAB60 (cdm解密+签名验证)
__int64 __fastcall TCDM_sig_check_1101AAB60(__int64 TCDM_obj, _BYTE *rsa_key, __int64 local_cdm_path)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
rsa_key_1 = rsa_key;
n1 = local_cdm_path;
STR_REF_11000A020(local_cdm_path);
part1 = 0LL;
v10 = 0LL;
text = 0LL;
v4 = (_QWORD *)sub_11000FC50(1, (__int64)v8, (__int64)v9);
_110012650 = allocate_110012650(v4);
if ( (_DWORD)_110012650 )
goto LABEL_14;
// 000000011003D7E0
(*(void (__fastcall **)(_QWORD))(**(_QWORD **)(TCDM_obj + 8) + 360LL))(*(_QWORD *)(TCDM_obj + 8));
if ( (unsigned __int8)not_printable_characters_1101A2560(n1) )
{
STR_REF_11000A020(ccdm_path_1102B0500); // 00000001102B0500:&"C:\\Users\\Public\\NESMaker\\NESMaker.CDM"
str_clear_110009FC0(&n1);
n1 = ccdm_path_1102B0500;
}
if ( !x_file_exist_1101A9A10(n1) )
{
LABEL_11:
if ( (unsigned __int8)not_printable_characters_1101A2560((__int64)rsa_key_1)
|| check_SIGNATURE_1101AB8F0(TCDM_obj, rsa_key_1) )
{
goto LABEL_14;
}
goto LABEL_13;
}
sub_1101A93C0(*(_QWORD *)(TCDM_obj + 8), n1);
// 000000011003D3B0
if ( (*(int (__fastcall **)(_QWORD))(**(_QWORD **)(TCDM_obj + 8) + 256LL))(*(_QWORD *)(TCDM_obj + 8)) < 1 )
{
(*(void (__fastcall **)(_QWORD))(**(_QWORD **)(TCDM_obj + 8) + 360LL))(*(_QWORD *)(TCDM_obj + 8));
goto LABEL_14;
}
str_clear_110009FC0(&text);
text = 0LL;
// 000000011003D320
// stringlist[0]
(*(void (__fastcall **)(_QWORD, __int64 *, _QWORD))(**(_QWORD **)(TCDM_obj + 8) + 0xF0LL))(
*(_QWORD *)(TCDM_obj + 8),
&text,
0LL);
find_substr_1101A2230((int)&part1, text, 1, '|');
str_clear_110009FC0(&text);
text = 0LL;
(*(void (__fastcall **)(_QWORD, __int64 *, _QWORD))(**(_QWORD **)(TCDM_obj + 8) + 0xF0LL))(
*(_QWORD *)(TCDM_obj + 8),
&text,
0LL);
find_substr_1101A2230((int)&v10, text, 2, '|');
if ( !str_cmp_11000A690(v10, (__int64)"1") )
{
str_clear_110009FC0(&text);
text = 0LL;
aes_cfb_dec_b64_1101ACC60(&text, (__int64)"[MQ(UL/&C:&a7eEW", part1);
// 000000011003B810
(*(void (__fastcall **)(_QWORD, __int64))(**(_QWORD **)(TCDM_obj + 8) + 0x130LL))(*(_QWORD *)(TCDM_obj + 8), text);
goto LABEL_11;
}
LABEL_13:
(*(void (__fastcall **)(_QWORD))(**(_QWORD **)(TCDM_obj + 8) + 360LL))(*(_QWORD *)(TCDM_obj + 8));
LABEL_14:
sub_11000FFE0();
str_clear_110009FC0(&text);
text = 0LL;
str_clear_110009FC0(&part1);
part1 = 0LL;
str_clear_110009FC0(&v10);
v10 = 0LL;
str_clear_110009FC0(&n1);
result = _110012650;
if ( _110012650 )
return sub_1100101B0();
return result;
}
aes_cfb_dec_b64_1101ACC60
__int64 __fastcall aes_cfb_dec_b64_1101ACC60(__int64 *out, __int64 key, __int64 data)
{
__int64 result; // rax
_QWORD *v5; // rax
__int64 _110012650; // [rsp+30h] [rbp-90h]
_BYTE v7[80]; // [rsp+38h] [rbp-88h] BYREF
_BYTE v8[24]; // [rsp+88h] [rbp-38h] BYREF
__int64 v9; // [rsp+A0h] [rbp-20h]
__int64 *v10; // [rsp+A8h] [rbp-18h]
__int64 v11; // [rsp+B0h] [rbp-10h]
__int64 v12; // [rsp+B8h] [rbp-8h]
v10 = out;
v12 = key;
v11 = data;
str_clear_110009FC0(out);
*out = 0LL;
result = not_printable_characters_1101A2560(v12);
if ( !(_BYTE)result )
{
result = not_printable_characters_1101A2560(v11);
if ( !(_BYTE)result )
{
// 00000001101B1F10
v9 = ((__int64 (__fastcall *)(_QWORD, __int64 *, _QWORD))*(&TDCP_rijndael_11027DFD0 + 49))(
0LL,
&TDCP_rijndael_11027DFD0,
0LL);
v5 = (_QWORD *)sub_11000FC50(1, (__int64)v7, (__int64)v8);
_110012650 = allocate_110012650(v5);
if ( !(_DWORD)_110012650 )
{
sub_1101B1420(v9, v12, (__int64)&TDCP_md5_11027DCC0);
// 00000001101B1CF0
(*(void (__fastcall **)(__int64, __int64 *, __int64))(*(_QWORD *)v9 + 0x200LL))(v9, v10, v11);
}
sub_11000FFE0();
sub_11000ED20(v9);
result = _110012650;
if ( _110012650 )
return sub_1100101B0();
}
}
return result;
}
check_SIGNATURE_1101AB8F0
// 失败0,成功1
_BOOL8 __fastcall check_SIGNATURE_1101AB8F0(__int64 obj, _BYTE *rsa_key)
{
bool v2; // si
_QWORD *v4; // rax
__int64 _110012650; // [rsp+38h] [rbp-88h]
_BYTE v7[80]; // [rsp+40h] [rbp-80h] BYREF
_BYTE v8[24]; // [rsp+90h] [rbp-30h] BYREF
__int64 v9; // [rsp+A8h] [rbp-18h] BYREF
__int64 v10; // [rsp+B0h] [rbp-10h] BYREF
_BYTE *rsa_key_1; // [rsp+B8h] [rbp-8h]
rsa_key_1 = rsa_key;
v10 = 0LL;
v9 = 0LL;
v4 = (_QWORD *)sub_11000FC50(1, (__int64)v7, (__int64)v8);
_110012650 = allocate_110012650(v4);
if ( !(_DWORD)_110012650 )
{
// TStringListUTF
TStringListUTF_1101A2670(*(_QWORD *)(obj + 8), &v9);
// SIGNATURE
list_get_1101AB3D0(obj, (__int64)&v10, (__int64)"SIGNATURE");
v2 = rsa_check_1101ACA90(rsa_key_1, v9, v10);
}
sub_11000FFE0();
str_clear_110009FC0(&v10);
v10 = 0LL;
str_clear_110009FC0(&v9);
v9 = 0LL;
if ( _110012650 )
sub_1100101B0();
return v2;
}
rsa_check_1101ACA90
// 验证失败返回0
_BOOL8 __fastcall rsa_check_1101ACA90(_BYTE *key, __int64 M, __int64 S_b64)
{
_QWORD *v3; // rax
__int64 _110012650; // [rsp+28h] [rbp-98h]
_BYTE v6[80]; // [rsp+30h] [rbp-90h] BYREF
_BYTE v7[24]; // [rsp+80h] [rbp-40h] BYREF
__int64 v8; // [rsp+98h] [rbp-28h]
bool v9; // [rsp+A0h] [rbp-20h]
__int64 S_b64_; // [rsp+A8h] [rbp-18h]
__int64 M_; // [rsp+B0h] [rbp-10h]
_BYTE *key_; // [rsp+B8h] [rbp-8h]
key_ = key;
M_ = M;
S_b64_ = S_b64;
v9 = 0;
if ( !(unsigned __int8)not_printable_characters_1101A2560((__int64)key)
&& !(unsigned __int8)not_printable_characters_1101A2560(S_b64_) )
{
v8 = TRSA_1101B0C40(0LL, (unsigned __int64)&TRSA_110281638);
v3 = (_QWORD *)sub_11000FC50(1, (__int64)v6, (__int64)v7);
_110012650 = allocate_110012650(v3);
if ( !(_DWORD)_110012650 )
{
load_key_1101B1000(v8, key_);
v9 = RSAVerify_b64_1101B0F20(v8, M_, S_b64_);
}
sub_11000FFE0();
sub_11000ED20(v8);
if ( _110012650 )
sub_1100101B0();
}
return v9;
}
RSAVerify_b64_1101B0F20
_BOOL8 __fastcall RSAVerify_b64_1101B0F20(__int64 obj, __int64 M, __int64 S_b64)
{
_QWORD *v4; // rax
__int64 _110012650; // [rsp+40h] [rbp-90h]
_BYTE v7[80]; // [rsp+48h] [rbp-88h] BYREF
_BYTE v8[24]; // [rsp+98h] [rbp-38h] BYREF
__int64 S_; // [rsp+B0h] [rbp-20h] BYREF
bool valid[8]; // [rsp+B8h] [rbp-18h] BYREF
__int64 S_b64_; // [rsp+C0h] [rbp-10h] BYREF
__int64 M_; // [rsp+C8h] [rbp-8h] BYREF
M_ = M;
S_b64_ = S_b64;
STR_REF_11000A020(M);
STR_REF_11000A020(S_b64_);
S_ = 0LL;
v4 = (_QWORD *)sub_11000FC50(1, (__int64)v7, (__int64)v8);
_110012650 = allocate_110012650(v4);
if ( !(_DWORD)_110012650 )
{
x_b64dec_1101A5180(&S_, S_b64_);
// Procedure RSAVerify(M, S : String; Var e, n : TFGInt; Var valid : boolean);
RSAVerify_1101B7B40(M_, S_, obj + 40, obj + 24, valid);
}
sub_11000FFE0();
str_clear_110009FC0(&S_);
S_ = 0LL;
str_clear_110009FC0(&M_);
str_clear_110009FC0(&S_b64_);
if ( _110012650 )
sub_1100101B0();
return valid[0];
}
RSAVerify_1101B7B40
// Procedure RSAVerify(M, S : String; Var e, n : TFGInt; Var valid : boolean);
// // Verify digitally signed strings with the RSA algorihthm,
// // If M = S^e mod n then ok:=true else ok:=false
__int64 __fastcall RSAVerify_1101B7B40(__int64 M, __int64 S, __int64 e, __int64 n, bool *valid)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
M1 = M;
S1 = S;
e1 = e;
n1 = n;
STR_REF_11000A020(M);
STR_REF_11000A020(S1);
TFGInt_110010F30(MGInt, &byte_110282910);
TFGInt_110010F30(SGInt, &byte_110282910);
TFGInt_110010F30(temp, &byte_110282910);
v5 = (_QWORD *)sub_11000FC50(1, (__int64)v8, (__int64)v9);
_110012650 = allocate_110012650(v5);
if ( !(_DWORD)_110012650 )
{
Base256StringToFGInt_1101B4050(S1, SGInt);
Base256StringToFGInt_1101B4050(M1, MGInt);
FGIntMod_1101B6190(MGInt, n1, temp);
FGIntCopy_1101B5120((__int64)temp, MGInt);
FGIntMontgomeryModExp_1101B6D50(SGInt, e1, n1, temp);
FGIntCopy_1101B5120((__int64)temp, SGInt);
*valid = (unsigned __int8)FGIntCompareAbs_1101B47B0(SGInt, MGInt) == 2;
FGIntDestroy_1101B4780(SGInt);
FGIntDestroy_1101B4780(MGInt);
}
sub_11000FFE0();
sub_110010FF0(MGInt, &byte_110282910);
sub_110010FF0(SGInt, &byte_110282910);
sub_110010FF0(temp, &byte_110282910);
str_clear_110009FC0(&M1);
str_clear_110009FC0(&S1);
result = _110012650;
if ( _110012650 )
return sub_1100101B0();
return result;
}
接口调用、cdm验证
通过py脚本生成.cdm文件后,可主动调用dna.dll接口 进行验证。
// NESMaker_dna.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <Windows.h>
__int64(__fastcall* DNA_ActivateOffline)(const char* product_key, const char* activation_code);
__int64(__fastcall* DNA_Validate)(const char* ProductKey);
__int64(__fastcall* DNA_Error)(unsigned int code, char* buf, int bufsz);
__int64(__fastcall* DNA_SetCDMPathName)(const char* path_name);
int main()
{
int code = 0;
//path_name = "C:\\Users\\Public\\NESMaker\\NESMaker.CDM";
//DNA.DNA_SetCDMPathName(path_name);
char buf[0x100]{ 0 };
//auto ProductKey = R"(P0003024-QAB:D2fhogQkHWOB0jVkEtrS3lr6hgNe/O7pAkxsv2OVHTT6AHyWdPJv1KIwLpUoPh/D1N+BVQ5jGQ1a+nJpptW0SX)";
//my gen rsa pub_key
auto ProductKey = R"(P0003024-QAB:DEYss/FyLOVPDC4yXMyQVYxFqE8ZlaQtkRHrxdu/wwIn6gDbxgQNj3uKd5I/YV8na5pnHZZP9j56ejPiKlzPtP)";
auto md = LoadLibraryA(R"(dna.dll)");
if (!md) {
printf("load dna.dll error");
return 1;
}
DNA_Validate = (decltype(DNA_Validate))GetProcAddress(md, "DNA_Validate");
DNA_Error = (decltype(DNA_Error))GetProcAddress(md, "DNA_Error");
DNA_SetCDMPathName = (decltype(DNA_SetCDMPathName))GetProcAddress(md, "DNA_SetCDMPathName");
//DNA_ActivateOffline = (decltype(DNA_ActivateOffline))GetProcAddress(md, "DNA_ActivateOffline");
//if (DNA_Validate && DNA_ActivateOffline)
if (DNA_Validate && DNA_Error && DNA_SetCDMPathName)
{
code = DNA_SetCDMPathName("C:\\Users\\Public\\NESMaker\\NESMaker.CDM");
if (code) {
DNA_Error(code, buf, sizeof(buf));
printf("DNA_SetCDMPathName error:[%d] %s\n", code, buf);
}
code = DNA_Validate(ProductKey);
if (code == 0) {
printf("DNA_Validate succeed!\n");
/* code = DNA_ActivateOffline(ProductKey, "BRH9EIONIOU4RWYIUOEAG");
printf("DNA_ActivateOffline code:%d\n", code);
DNA_Error(code, buf, sizeof(buf));
printf("error: %s\n", buf);*/
}
else
{
printf("DNA_Validate code:%d\n", code);
DNA_Error(code, buf, sizeof(buf));
printf("error: %s\n", buf);
}
}
return 0;
}
其他
error info
error_info_11002ACC0
__int64 __fastcall error_info_11002ACC0(__int64 *a1, int a2)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
v14 = a1;
v13 = 0LL;
v6 = 0LL;
v3 = (_QWORD *)sub_11000FC50(1, (__int64)v11, (__int64)v12);
v10 = sub_110012650(v3);
if ( (_DWORD)v10 )
goto LABEL_59;
switch ( a2 )
{
case -3:
// Banned activation code
find_error_str_1101AA7C0((__int64 *)&v13, 0x7Au);
break;
case -2:
// DNA disable
find_error_str_1101AA7C0((__int64 *)&v13, 0x65u);
break;
case -1:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Must validate by
find_error_str_1101AA7C0((__int64 *)&v6, 0x66u);
v7 = v6;
v8 = &unk_1101FB878;
v9 = qword_1102AD870;
str_cat_11000A220((__int64 *)&v13, &v7, 2LL);
break;
default:
if ( a2 )
{
switch ( a2 )
{
case 1:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Please verify your connection to the Internet or the presence of a Proxy Server
find_error_str_1101AA7C0((__int64 *)&v6, 0x67u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
break;
case 2:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Connection lost
find_error_str_1101AA7C0((__int64 *)&v6, 0x68u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
break;
case 3:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Lockout until
find_error_str_1101AA7C0((__int64 *)&v6, 0x69u);
v7 = v6;
v8 = &unk_1101FB878;
v9 = qword_1102AD870;
str_cat_11000A220((__int64 *)&v13, &v7, 2LL);
break;
case 4:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Invalid CDM
find_error_str_1101AA7C0((__int64 *)&v6, 0x6Au);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
break;
case 5:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Invalid product key
find_error_str_1101AA7C0((__int64 *)&v6, 0x6Bu);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
break;
case 6:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Invalid activation code
find_error_str_1101AA7C0((__int64 *)&v6, 0x6Cu);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
break;
case 7:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Invalid password
find_error_str_1101AA7C0((__int64 *)&v6, 0x6Du);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
break;
default:
if ( a2 != 8 )
{
switch ( a2 )
{
case 9:
LABEL_43:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Re-activation expected
find_error_str_1101AA7C0((__int64 *)&v6, 0x6Fu);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 10:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Banned activation code
find_error_str_1101AA7C0((__int64 *)&v6, 0x70u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 11:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// No email provided
find_error_str_1101AA7C0((__int64 *)&v6, 0x71u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 12:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Invalid build number
find_error_str_1101AA7C0((__int64 *)&v6, 0x72u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 13:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Evaluation code already sent
find_error_str_1101AA7C0((__int64 *)&v6, 0x73u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 14:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Evaluation code unavailable
find_error_str_1101AA7C0((__int64 *)&v6, 0x74u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 15:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// CDM has expired
find_error_str_1101AA7C0((__int64 *)&v6, 0x75u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 16:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Activation code has expired
find_error_str_1101AA7C0((__int64 *)&v6, 0x76u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 17:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// The new password has already been used. Please provide a New and Never Used password to re-activate
find_error_str_1101AA7C0((__int64 *)&v6, 0x79u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
case 18:
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// The directory or file for storing the License file (CDM) is write-protected. Please ensure that you have read-write permissions for this directory or file and try again
find_error_str_1101AA7C0((__int64 *)&v6, 0x7Bu);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
goto LABEL_58;
}
if ( a2 != 19 )
{
if ( a2 != 20 )
{
if ( a2 == 21 )
{
str_clear_110009FC0((__int64 *)&v13);
v13 = "The number of activations has been exceeded for this Activation Code.";
}
else if ( a2 == 98 )
{
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Cancelled by user
find_error_str_1101AA7C0((__int64 *)&v6, 120u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
}
else
{
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
if ( a2 == 99 )
// Please verify your Activation Code, Password and try again
find_error_str_1101AA7C0((__int64 *)&v6, 119u);
else
// Undefined error
find_error_str_1101AA7C0((__int64 *)&v6, 100u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
}
goto LABEL_58;
}
goto LABEL_43;
}
}
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
// Activation expected
find_error_str_1101AA7C0((__int64 *)&v6, 110u);
sub_11000A020((__int64)v6);
str_clear_110009FC0((__int64 *)&v13);
v13 = v6;
break;
}
}
else
{
str_clear_110009FC0((__int64 *)&v13);
v13 = 0LL;
}
break;
}
LABEL_58:
sub_11000A020((__int64)v13);
v4 = v14;
str_clear_110009FC0(v14);
*v4 = (__int64)v13;
LABEL_59:
sub_11000FFE0();
str_clear_110009FC0((__int64 *)&v6);
v6 = 0LL;
str_clear_110009FC0((__int64 *)&v13);
v13 = 0LL;
result = v10;
if ( v10 )
return sub_1100101B0();
return result;
}
.data:000000011027C810 off_11027C810 dq offset a100 ; DATA XREF: find_error_str_1101AA7C0+95↑o
.data:000000011027C810 ; find_error_str_1101AA7C0+CA↑o ...
.data:000000011027C810 ; "100"
.data:000000011027C818 dq offset aUndefinedError ; "Undefined error"
.data:000000011027C820 dq offset aErreurNonDefin ; "Erreur non définie"
.data:000000011027C828 dq offset aUnbekannterFeh ; "Unbekannter Fehler"
.data:000000011027C830 dq offset aErrorIndefinid ; "Error indefinido"
.data:000000011027C838 dq 0
.data:000000011027C840 dq offset a101 ; "101"
.data:000000011027C848 dq offset aDnaDisable ; "DNA disable"
.data:000000011027C850 dq offset aDnaNeutralise ; "DNA neutralisé"
.data:000000011027C858 dq offset aDnaDeaktiviert ; "DNA deaktiviert"
.data:000000011027C860 dq offset aDnaDeshabilita ; "DNA deshabilitado"
.data:000000011027C868 dq 0
.data:000000011027C870 dq offset a102 ; "102"
.data:000000011027C878 dq offset aMustValidateBy ; "Must validate by"
.data:000000011027C880 dq offset aValidationRequ ; "Validation requise avant le"
.data:000000011027C888 dq offset aMussValidiertW ; "Muss validiert werden durch"
.data:000000011027C890 dq offset aDebeValidarAnt ; "Debe validar antes"
.data:000000011027C898 align 20h
.data:000000011027C8A0 dq offset a103 ; "103"
.data:000000011027C8A8 dq offset aPleaseVerifyYo ; "Please verify your connection to the In"...
.data:000000011027C8B0 dq offset aSvpVerifierVot ; "SVP vérifier votre connection à l'inter"...
.data:000000011027C8B8 dq offset aBitteUberprufe ; "Bitte überprüfen Sie ihre Internetverbi"...
.data:000000011027C8C0 dq offset aPorFavorVerifi ; "Por favor, verifique su conexión a Inte"...
.data:000000011027C8C8 align 10h
.data:000000011027C8D0 dq offset a104 ; "104"
.data:000000011027C8D8 dq offset aConnectionLost ; "Connection lost"
.data:000000011027C8E0 dq offset aConnectionPerd ; "Connection perdue"
.data:000000011027C8E8 dq offset aVerbindungGetr ; "Verbindung getrennt"
.data:000000011027C8F0 dq offset aConexionPerdid ; "Conexión perdida"
.data:000000011027C8F8 align 20h
.data:000000011027C900 dq offset a105 ; "105"
.data:000000011027C908 dq offset aLockoutUntil ; "Lockout until"
.data:000000011027C910 dq offset aVerrouillageJu ; "Verrouillage jusqu'au"
.data:000000011027C918 dq offset aAusgeschlossen ; "Ausgeschlossen bis"
.data:000000011027C920 dq offset aBloqueadoHasta ; "Bloqueado hasta"
.data:000000011027C928 align 10h
.data:000000011027C930 dq offset a106 ; "106"
.data:000000011027C938 dq offset aInvalidCdm ; "Invalid CDM"
.data:000000011027C940 dq offset aCdmInadmissibl ; "CDM Inadmissible"
.data:000000011027C948 dq offset aUngultigeCdm ; "Ungültige CDM"
.data:000000011027C950 dq offset aCdmIncorrecta ; "CDM incorrecta"
.data:000000011027C958 align 20h
.data:000000011027C960 dq offset a107 ; "107"
.data:000000011027C968 dq offset aInvalidProduct ; "Invalid product key"
.data:000000011027C970 dq offset aClefDeProduitI ; "Clef de produit inadmissible"
.data:000000011027C978 dq offset aUngultigerProd ; "Ungültiger Produktschlüssel"
.data:000000011027C980 dq offset aClaveDeProduct ; "Clave de producto incorrecta"
.data:000000011027C988 align 10h
.data:000000011027C990 dq offset a108 ; "108"
.data:000000011027C998 dq offset aInvalidActivat ; "Invalid activation code"
.data:000000011027C9A0 dq offset aCodeDActivatio ; "Code d'activation inadmissible"
.data:000000011027C9A8 dq offset aUngultigerAkti ; "Ungültiger Aktivierungscode"
.data:000000011027C9B0 dq offset aCodigoDeActiva_0 ; "Código de Activación incorrecto"
.data:000000011027C9B8 align 20h
.data:000000011027C9C0 dq offset a109 ; "109"
.data:000000011027C9C8 dq offset aInvalidPasswor ; "Invalid password"
.data:000000011027C9D0 dq offset aMotDePasseInad ; "Mot de passe inadmissible"
.data:000000011027C9D8 dq offset aUngultigesPass ; "Ungültiges Passwort"
.data:000000011027C9E0 dq offset aClaveDeAccesoI ; "Clave de acceso incorrecta"
.data:000000011027C9E8 align 10h
.data:000000011027C9F0 dq offset a110 ; "110"
.data:000000011027C9F8 dq offset aActivationExpe ; "Activation expected"
.data:000000011027CA00 dq offset aActivationPrev ; "Activation prévue"
.data:000000011027CA08 dq offset aAktivierungErw ; "Aktivierung erwartet"
.data:000000011027CA10 dq offset aSeEsperaActiva ; "Se espera activación"
.data:000000011027CA18 align 20h
.data:000000011027CA20 dq offset a111 ; "111"
.data:000000011027CA28 dq offset aReActivationEx ; "Re-activation expected"
.data:000000011027CA30 dq offset aReactivationPr ; "Réactivation prévue"
.data:000000011027CA38 dq offset aReaktivierungE ; "Reaktivierung erwartet"
.data:000000011027CA40 dq offset aSeEsperaReacti ; "Se espera reactivación"
.data:000000011027CA48 align 10h
.data:000000011027CA50 dq offset a112 ; "112"
.data:000000011027CA58 dq offset aBannedActivati ; "Banned activation code"
.data:000000011027CA60 dq offset aCodeDActivatio_0 ; "Code d'activation interdit"
.data:000000011027CA68 dq offset aBlockierterAkt ; "Blockierter Aktivierungscode"
.data:000000011027CA70 dq offset aCodigoDeActiva ; "Código de Activación bloqueado"
.data:000000011027CA78 align 20h
.data:000000011027CA80 dq offset a113 ; "113"
.data:000000011027CA88 dq offset aNoEmailProvide ; "No email provided"
.data:000000011027CA90 dq offset aAucunCourrielF ; "Aucun courriel fourni"
.data:000000011027CA98 dq offset aKeineEmailAnge ; "Keine Email angegeben"
.data:000000011027CAA0 dq offset aFaltaDireccion ; "Falta dirección email"
.data:000000011027CAA8 align 10h
.data:000000011027CAB0 dq offset a114 ; "114"
.data:000000011027CAB8 dq offset aInvalidBuildNu ; "Invalid build number"
.data:000000011027CAC0 dq offset aVersionInadmis ; "Version inadmissible"
.data:000000011027CAC8 dq offset aUngultigeBuild ; "Ungültige Build-Nummer"
.data:000000011027CAD0 dq offset aVersionIncorre ; "Versión incorrecta"
.data:000000011027CAD8 align 20h
.data:000000011027CAE0 dq offset a115 ; "115"
.data:000000011027CAE8 dq offset aEvaluationCode ; "Evaluation code already sent"
.data:000000011027CAF0 dq offset aCodeDEvaluatio ; "Code d'évaluation déjà transmis"
.data:000000011027CAF8 dq offset aEvaluationscod ; "Evaluationscode bereits gesendet"
.data:000000011027CB00 dq offset aCodigoDeEvalua ; "Código de evaluación ya enviado"
.data:000000011027CB08 align 10h
.data:000000011027CB10 dq offset a116 ; "116"
.data:000000011027CB18 dq offset aEvaluationCode_0 ; "Evaluation code unavailable"
.data:000000011027CB20 dq offset aCodeDEvaluatio_0 ; "Code d'évaluation non disponible"
.data:000000011027CB28 dq offset aEvaluationscod_1 ; "Evaluationscode nicht verfügbar"
.data:000000011027CB30 dq offset aCodigoDeEvalua_0 ; "Código de Evaluación no disponible"
.data:000000011027CB38 align 20h
.data:000000011027CB40 dq offset a117 ; "117"
.data:000000011027CB48 dq offset aCdmHasExpired ; "CDM has expired"
.data:000000011027CB50 dq offset aCdmExpire ; "CDM expiré"
.data:000000011027CB58 dq offset aCdmIstAbgelauf ; "CDM ist abgelaufen"
.data:000000011027CB60 dq offset aCdmHaCaducado ; "CDM ha caducado"
.data:000000011027CB68 align 10h
.data:000000011027CB70 dq offset a118 ; "118"
.data:000000011027CB78 dq offset aActivationCode_1 ; "Activation code has expired"
.data:000000011027CB80 dq offset aCodeDActivatio_2 ; "Code d'activation expiré"
.data:000000011027CB88 dq offset aAktivierungsco ; "Aktivierungscode ist abgelaufen"
.data:000000011027CB90 dq offset aElCodigoDeActi ; "El Código de Activación ha caducado"
.data:000000011027CB98 align 20h
.data:000000011027CBA0 dq offset a119 ; "119"
.data:000000011027CBA8 dq offset aPleaseVerifyYo_0 ; "Please verify your Activation Code, Pas"...
.data:000000011027CBB0 dq offset aSvpVerifierVot_0 ; "SVP vérifier votre code d'activation, m"...
.data:000000011027CBB8 dq offset aBitteUberprufe_0 ; "Bitte überprüfen sie ihre Aktivierungsc"...
.data:000000011027CBC0 dq offset aPorFavorCompru ; "Por favor, compruebe su Código de Activ"...
.data:000000011027CBC8 align 10h
.data:000000011027CBD0 dq offset a120 ; "120"
.data:000000011027CBD8 dq offset aCancelledByUse ; "Cancelled by user"
.data:000000011027CBE0 dq offset aAnnuleParLUtil ; "Annulé par l'utilisateur"
.data:000000011027CBE8 dq offset aDurchBenutzerA ; "Durch Benutzer abgebrochen"
.data:000000011027CBF0 dq offset aCanceladoPorEl ; "Cancelado por el usuario"
.data:000000011027CBF8 align 20h
.data:000000011027CC00 dq offset a121 ; "121"
.data:000000011027CC08 dq offset aTheNewPassword ; "The new password has already been used."...
.data:000000011027CC10 dq offset aLeNouveauMotDe ; "Le nouveau mot de passe a déjà été util"...
.data:000000011027CC18 dq offset aDasNeueKennwor ; "Das Neue Kennwort ist schon benutzt wor"...
.data:000000011027CC20 dq offset aLaClaveDeAcces ; "La clave de acceso ya ha sido utilizada"...
.data:000000011027CC28 align 10h
.data:000000011027CC30 dq offset a122 ; "122"
.data:000000011027CC38 dq offset aTheNumberOfPer ; "The number of permitted activations has"...
.data:000000011027CC40 dq offset aLeNombreDActiv ; "Le nombre d'activations permises est dé"...
.data:000000011027CC48 dq offset aTheNumberOfPer_0 ; "The number of permitted activations has"...
.data:000000011027CC50 dq offset aSeHaSobrepasad ; "Se ha sobrepasado el número de activaci"...
.data:000000011027CC58 align 20h
.data:000000011027CC60 dq offset a123 ; "123"
.data:000000011027CC68 dq offset aTheDirectoryOr ; "The directory or file for storing the L"...
.data:000000011027CC70 dq offset aLeRepertoireOu ; "Le répertoire ou le fichier pour écrire"...
.data:000000011027CC78 dq offset aTheDirectoryOr_0 ; "The directory or file for storing the L"...
.data:000000011027CC80 dq offset aElDirectorioUs ; "El directorio usado para almacenar el f"...
.data:000000011027CC88 align 10h
.data:000000011027CC90 dq offset a200 ; "200"
.data:000000011027CC98 dq offset aProductActivat ; "Product Activation"
.data:000000011027CCA0 dq offset aActivation_0 ; "Activation"
.data:000000011027CCA8 dq offset aProduktAktivie ; "Produkt Aktivierung"
.data:000000011027CCB0 dq offset aActivacion ; "Activación"
.data:000000011027CCB8 align 20h
.data:000000011027CCC0 dq offset a201 ; "201"
.data:000000011027CCC8 dq offset aActivationInfo ; "Activation Information"
.data:000000011027CCD0 dq offset aInformationDAc ; "Information d'activation"
.data:000000011027CCD8 dq offset aAktivierungsin ; "Aktivierungsinformation"
.data:000000011027CCE0 dq offset aInformacionDeA ; "Información de activación"
.data:000000011027CCE8 align 10h
.data:000000011027CCF0 dq offset a202 ; "202"
.data:000000011027CCF8 dq offset aPassword_3 ; "Password :"
.data:000000011027CD00 dq offset aMotDePasse ; "Mot de passe :"
.data:000000011027CD08 dq offset aPasswort ; "Passwort :"
.data:000000011027CD10 dq offset aClaveDeAcceso ; "Clave de acceso :"
.data:000000011027CD18 align 20h
.data:000000011027CD20 dq offset a203 ; "203"
.data:000000011027CD28 dq offset aConfirm ; "Confirm :"
.data:000000011027CD30 dq offset aConfirmez ; "Confirmez :"
.data:000000011027CD38 dq offset aBestatigung ; "Bestätigung :"
.data:000000011027CD40 dq offset aConfirme ; "Confirme :"
.data:000000011027CD48 align 10h
.data:000000011027CD50 dq offset a204 ; "204"
.data:000000011027CD58 dq offset aEmail_0 ; "Email :"
.data:000000011027CD60 dq offset aCourriel ; "Courriel :"
.data:000000011027CD68 dq offset aEmail_1 ; "Email :"
.data:000000011027CD70 dq offset aEmail_2 ; "Email :"
.data:000000011027CD78 align 20h
.data:000000011027CD80 dq offset a205 ; "205"
.data:000000011027CD88 dq offset aConfirm_0 ; "Confirm :"
.data:000000011027CD90 dq offset aConfirmez_0 ; "Confirmez :"
.data:000000011027CD98 dq offset aBestatigung_0 ; "Bestätigung :"
.data:000000011027CDA0 dq offset aConfirme_0 ; "Confirme :"
.data:000000011027CDA8 align 10h
.data:000000011027CDB0 dq offset a206 ; "206"
.data:000000011027CDB8 dq offset aPleaseEnterAnd ; "Please enter and confirm a password."
.data:000000011027CDC0 dq offset aSvpEntrerEtCon ; "SVP entrer et confirmer un mot de passe"...
.data:000000011027CDC8 dq offset aBittePasswortE ; "Bitte Passwort eingeben und bestätigen."
.data:000000011027CDD0 dq offset aPorFavorIntrod ; "Por favor, introduzca y confirme una cl"...
.data:000000011027CDD8 align 20h
.data:000000011027CDE0 dq offset a207 ; "207"
.data:000000011027CDE8 dq offset aItIsRecommende ; "It is recommended that you also enter a"...
.data:000000011027CDF0 dq offset aIlEstRecommand ; "Il est recommandé d'enregistrer et conf"...
.data:000000011027CDF8 dq offset aEsWirdEmpfohle ; "Es wird empfohlen, daß Sie auch Ihre Em"...
.data:000000011027CE00 dq offset aTambienEsConve ; "También es conveniente que introduzca y"...
.data:000000011027CE08 align 10h
.data:000000011027CE10 dq offset a208 ; "208"
.data:000000011027CE18 dq offset aActivate ; "&Activate"
.data:000000011027CE20 dq offset aActiver ; "&Activer"
.data:000000011027CE28 dq offset aAktivieren ; "&Aktivieren"
.data:000000011027CE30 dq offset aActivar ; "&Activar"
.data:000000011027CE38 align 20h
.data:000000011027CE40 dq offset a209 ; "209"
.data:000000011027CE48 dq offset aCancel_1 ; "&Cancel"
.data:000000011027CE50 dq offset aAnnuler ; "&Annuler"
.data:000000011027CE58 dq offset aAbbrechen ; "&Abbrechen"
.data:000000011027CE60 dq offset aCancelar ; "&Cancelar"
.data:000000011027CE68 align 10h
.data:000000011027CE70 dq offset a210 ; "210"
.data:000000011027CE78 dq offset aPasswordsDonTM ; "Passwords don't match"
.data:000000011027CE80 dq offset aLesMotsDePasse ; "Les mots de passe ne sont pas identique"...
.data:000000011027CE88 dq offset aPassworterStim ; "Passwörter stimmen nicht überein"
.data:000000011027CE90 dq offset aLasClavesDeAcc ; "Las claves de acceso no concuerdan"
.data:000000011027CE98 align 20h
.data:000000011027CEA0 dq offset a211 ; "211"
.data:000000011027CEA8 dq offset aEmailsDonTMatc ; "Emails don't match"
.data:000000011027CEB0 dq offset aLesAdressesCou ; "Les adresses courriel ne sont pas ident"...
.data:000000011027CEB8 dq offset aEmailsStimmenN ; "Emails stimmen nicht überein"
.data:000000011027CEC0 dq offset aLasDirecciones ; "Las direcciones email no concuerdan"
.data:000000011027CEC8 align 10h
.data:000000011027CED0 dq offset a300 ; "300"
.data:000000011027CED8 dq offset aProductActivat_0 ; "Product Activation"
.data:000000011027CEE0 dq offset aActivationDuPr ; "Activation du produit"
.data:000000011027CEE8 dq offset aProduktAktivie_0 ; "Produkt Aktivierung"
.data:000000011027CEF0 dq offset aActivacionDelP ; "Activación del producto"
.data:000000011027CEF8 align 20h
.data:000000011027CF00 dq offset a301 ; "301"
.data:000000011027CF08 dq offset aPleaseEnterYou ; "Please enter your Activation Code"
.data:000000011027CF10 dq offset aSvpEntrerVotre ; "SVP entrer votre code d'activation"
.data:000000011027CF18 dq offset aBitteAktivieru ; "Bitte Aktivierungscode eingeben"
.data:000000011027CF20 dq offset aPorFavorIntrod_0 ; "Por favor, introduzca su Código de Acti"...
.data:000000011027CF28 align 10h
.data:000000011027CF30 dq offset a302 ; "302"
.data:000000011027CF38 dq offset aActivationCode_2 ; "Activation Code :"
.data:000000011027CF40 dq offset aCodeDActivatio_1 ; "Code d'activation :"
.data:000000011027CF48 dq offset aAktivierungsco_0 ; "Aktivierungscode :"
.data:000000011027CF50 dq offset aCodigoDeActiva_1 ; "Código de activación :"
.data:000000011027CF58 align 20h
.data:000000011027CF60 dq offset a303 ; "303"
.data:000000011027CF68 dq offset aRequestEvalCod ; "&Request Eval Code"
.data:000000011027CF70 dq offset aRequeteCodeDEv ; "&Requête code d'éval"
.data:000000011027CF78 dq offset aEvalCodeVerlan ; "&Eval. Code verlangen"
.data:000000011027CF80 dq offset aSolicitarCodDe ; "&Solicitar Cód. de Ev."
.data:000000011027CF88 align 10h
.data:000000011027CF90 dq offset a304 ; "304"
.data:000000011027CF98 dq offset aProxySettings ; "&Proxy Settings"
.data:000000011027CFA0 dq offset aReglagesPasser ; "&Réglages passerelle"
.data:000000011027CFA8 dq offset aProxyEinstellu ; "&Proxy Einstellungen"
.data:000000011027CFB0 dq offset aSetearProxi ; "&Setear Proxi"
.data:000000011027CFB8 align 20h
.data:000000011027CFC0 dq offset a305 ; "305"
.data:000000011027CFC8 dq offset aNext_2 ; "&Next >"
.data:000000011027CFD0 dq offset aSuivant ; "&Suivant >"
.data:000000011027CFD8 dq offset aWeiter ; "&Weiter >"
.data:000000011027CFE0 dq offset aSiguiente ; "&Siguiente >"
.data:000000011027CFE8 align 10h
.data:000000011027CFF0 dq offset a306 ; "306"
.data:000000011027CFF8 dq offset aCancel_2 ; "&Cancel"
.data:000000011027D000 dq offset aAnnuler_0 ; "&Annuler"
.data:000000011027D008 dq offset aAbbrechen_0 ; "&Abbrechen"
.data:000000011027D010 dq offset aCancelar_0 ; "&Cancelar"
.data:000000011027D018 align 20h
.data:000000011027D020 dq offset a307 ; "307"
.data:000000011027D028 dq offset aRequestEvaluat ; "Request Evaluation Code"
.data:000000011027D030 dq offset aRequeteCodeDEv_0 ; "Requête code d'évaluation"
.data:000000011027D038 dq offset aEvaluationscod_0 ; "Evaluationscode verlangen"
.data:000000011027D040 dq offset aSolicitarCodig ; "Solicitar Código de Evaluación"
.data:000000011027D048 align 10h
.data:000000011027D050 dq offset a308 ; "308"
.data:000000011027D058 dq offset aEnterAValidEma ; "Enter a valid email ?"
.data:000000011027D060 dq offset aEntrerUneAdres ; "Entrer une adresse courriel valide ?"
.data:000000011027D068 dq offset aGultigeEmailEi ; "Gültige Email eingegeben ?"
.data:000000011027D070 dq offset aEsValidaLaDire ; "Es válida la dirección email?"
.data:000000011027D078 align 20h
.data:000000011027D080 dq offset a309 ; "309"
.data:000000011027D088 dq offset aYourEvaluation ; "Your evaluation code has been sent"
.data:000000011027D090 dq offset aVotreCodeDEval ; "Votre code d'évaluation a été envoyé"
.data:000000011027D098 dq offset aIhrEvaluations ; "Ihr Evaluationscode wurde gesendet"
.data:000000011027D0A0 dq offset aSuCodigoDeEval ; "Su Código de Evaluación ha sido enviado"
.data:000000011027D0A8 align 10h
.data:000000011027D0B0 dq offset a310 ; "310"
.data:000000011027D0B8 dq offset aEvaluateNow ; "&Evaluate Now"
.data:000000011027D0C0 dq offset aEvaluerMainten ; "&Évaluer maintenant"
.data:000000011027D0C8 dq offset aJetztEvaluiere ; "&Jetzt evaluieren"
.data:000000011027D0D0 dq offset aEvaluarAhora ; "&Evaluar ahora"
.data:000000011027D0D8 align 20h
.data:000000011027D0E0 dq offset a311 ; "311"
.data:000000011027D0E8 dq offset aLicenseFileCre ; "License File created successfully"
.data:000000011027D0F0 dq offset aLeFichierDeLic ; "Le fichier de licence a été créé"
.data:000000011027D0F8 dq offset aDieLizenzdatei ; "Die Lizenzdatei wurde erfolgreich erzeu"...
.data:000000011027D100 dq offset aFicheroDeLicen ; "Fichero de Licencia creado satisfactori"...
.data:000000011027D108 align 10h
.data:000000011027D110 dq offset a312 ; "312"
.data:000000011027D118 dq offset aLicenseFileNot ; "License File not created !"
.data:000000011027D120 dq offset aLaCreationDuFi ; "La création du fichier de licence a éch"...
.data:000000011027D128 dq offset aDieLizenzdatei_0 ; "Die Lizenzdatei konnte nicht erzeugt we"...
.data:000000011027D130 dq offset aFicheroDeLicen_0 ; "Fichero de Licencia no creado !"
.data:000000011027D138 align 20h
.data:000000011027D140 dq offset a400 ; "400"
.data:000000011027D148 dq offset aProxySettings_0 ; "Proxy Settings"
.data:000000011027D150 dq offset aReglagesPasser_0 ; "Réglages passerelle"
.data:000000011027D158 dq offset aProxyEinstellu_0 ; "Proxy Einstellungen"
.data:000000011027D160 dq offset aReglajesDeProx ; "Reglajes de Proxi"
.data:000000011027D168 align 10h
.data:000000011027D170 dq offset a401 ; "401"
.data:000000011027D178 dq offset aAuthentication_1 ; "Authentication"
.data:000000011027D180 dq offset aAuthentificati ; "Authentification"
.data:000000011027D188 dq offset aAuthentifikati ; "Authentifikation"
.data:000000011027D190 dq offset aAutenticacion ; "Autenticación"
.data:000000011027D198 align 20h
.data:000000011027D1A0 dq offset a402 ; "402"
.data:000000011027D1A8 dq offset aUsername_3 ; "Username :"
.data:000000011027D1B0 dq offset aUsager ; "Usager :"
.data:000000011027D1B8 dq offset aBenutzername ; "Benutzername :"
.data:000000011027D1C0 dq offset aNombreDeUsuari ; "Nombre de usuario :"
.data:000000011027D1C8 align 10h
.data:000000011027D1D0 dq offset a403 ; "403"
.data:000000011027D1D8 dq offset aPassword_4 ; "Password :"
.data:000000011027D1E0 dq offset aMotDePasse_0 ; "Mot de passe :"
.data:000000011027D1E8 dq offset aPasswort_0 ; "Passwort :"
.data:000000011027D1F0 dq offset aClaveDeAcceso_0 ; "Clave de acceso :"
.data:000000011027D1F8 align 20h
.data:000000011027D200 dq offset a404 ; "404"
.data:000000011027D208 dq offset aOk ; "&Ok"
.data:000000011027D210 dq offset aOk_0 ; "&Ok"
.data:000000011027D218 dq offset aOk_1 ; "&Ok"
.data:000000011027D220 dq offset aOk_2 ; "&Ok"
.data:000000011027D228 align 10h
.data:000000011027D230 dq offset a405 ; "405"
.data:000000011027D238 dq offset aCancel_3 ; "&Cancel"
.data:000000011027D240 dq offset aAnnuler_1 ; "&Annuler"
.data:000000011027D248 dq offset aAbbrechen_1 ; "&Abbrechen"
.data:000000011027D250 dq offset aCancelar_1 ; "&Cancelar"
.data:000000011027D258 align 20h
.data:000000011027D260 dq offset a406 ; "406"
.data:000000011027D268 dq offset aProxy_1 ; "Proxy"
.data:000000011027D270 dq offset aPasserelle ; "Passerelle"
.data:000000011027D278 dq offset aProxy_2 ; "Proxy"
.data:000000011027D280 dq offset aProxi ; "Proxi"
.data:000000011027D288 align 10h
.data:000000011027D290 dq offset a407 ; "407"
.data:000000011027D298 dq offset aServer_2 ; "Server :"
.data:000000011027D2A0 dq offset aServeur ; "Serveur :"
.data:000000011027D2A8 dq offset aServer_3 ; "Server :"
.data:000000011027D2B0 dq offset aServidor ; "Servidor :"
.data:000000011027D2B8 align 20h
.data:000000011027D2C0 dq offset a408 ; "408"
.data:000000011027D2C8 dq offset aPort_1 ; "Port :"
.data:000000011027D2D0 dq offset aPort_2 ; "Port :"
.data:000000011027D2D8 dq offset aPort_3 ; "Port :"
.data:000000011027D2E0 dq offset aPort_4 ; "Port :"
.data:000000011027D2E8 align 10h
.data:000000011027D2F0 dq offset a409 ; "409"
.data:000000011027D2F8 dq offset aUseInternetExp ; "Use Internet Explorer Settings"
.data:000000011027D300 dq offset aUtiliserLesPar ; "Utiliser les paramètres d'Internet Expl"...
.data:000000011027D308 dq offset aBenutzeInterne ; "Benutze Internet Explorer Einstellungen"
.data:000000011027D310 dq offset aUsarParametros ; "Usar parámetros de Internet Explorer"
.data:000000011027D318 dq 0
.data:000000011027D320 dq offset a500 ; "500"
.data:000000011027D328 dq offset aProductActivat_1 ; "Product Activation"
.data:000000011027D330 dq offset aActivationDuPr_0 ; "Activation du produit"
.data:000000011027D338 dq offset aProduktAktivie_1 ; "Produkt Aktivierung"
.data:000000011027D340 dq offset aActivacionDelP_0 ; "Activación del producto"
.data:000000011027D348 align 10h
.data:000000011027D350 dq offset a501 ; "501"
.data:000000011027D358 dq offset aReActivationIn ; "Re-Activation Information"
.data:000000011027D360 dq offset aInformationDeR ; "Information de réactivation"
.data:000000011027D368 dq offset aReaktivierungs ; "Reaktivierungs Information"
.data:000000011027D370 dq offset aInformacionDeR ; "Información de reactivación"
.data:000000011027D378 align 20h
.data:000000011027D380 dq offset a502_1 ; "502"
.data:000000011027D388 dq offset aCurrentPasswor ; "Current Password :"
.data:000000011027D390 dq offset aMotDePasseCour ; "Mot de passe courant :"
.data:000000011027D398 dq offset aAktuellesPassw ; "Aktuelles Passwort :"
.data:000000011027D3A0 dq offset aClaveDeAccesoA ; "Clave de acceso actual :"
.data:000000011027D3A8 align 10h
.data:000000011027D3B0 dq offset a503 ; "503"
.data:000000011027D3B8 dq offset aNewNeverUsedPa ; "New (never-used) password :"
.data:000000011027D3C0 dq offset aNouveauJamaisU ; "Nouveau (jamais utilisé) mot de passe :"
.data:000000011027D3C8 dq offset aNeuesNieGenomm ; "Neues (Nie genommen) Passwort :"
.data:000000011027D3D0 dq offset aNuevaClaveDeAc ; "Nueva clave de acceso (no usada antes) "...
.data:000000011027D3D8 align 20h
.data:000000011027D3E0 dq offset a504 ; "504"
.data:000000011027D3E8 dq offset aConfirm_1 ; "Confirm :"
.data:000000011027D3F0 dq offset aConfirmer ; "Confirmer :"
.data:000000011027D3F8 dq offset aBestatigung_1 ; "Bestätigung :"
.data:000000011027D400 dq offset aConfirmar ; "Confirmar"
.data:000000011027D408 align 10h
.data:000000011027D410 dq offset a505 ; "505"
.data:000000011027D418 dq offset aThisCodeHasAlr ; "This code has already been activated !"
.data:000000011027D420 dq offset aCeCodeADejaEte ; "Ce code a déjà été activé !"
.data:000000011027D428 dq offset aDieserCodeWurd ; "Dieser Code wurde bereits aktiviert !"
.data:000000011027D430 dq offset aEsteCodigoHaSi ; "Este código ha sido activado anteriorme"...
.data:000000011027D438 align 20h
.data:000000011027D440 dq offset a506 ; "506"
.data:000000011027D448 dq offset aPleaseConfirmT ; "Please confirm that you wish to re-acti"...
.data:000000011027D450 dq offset aSvpConfirmerQu ; "SVP confirmer que vous souhaitez le réa"...
.data:000000011027D458 dq offset aBestatigenSieB ; "Bestätigen Sie bitte, daß Sie reaktivie"...
.data:000000011027D460 dq offset aPorFavorConfir ; "Por favor, confirme que desea reactivar"...
.data:000000011027D468 align 10h
.data:000000011027D470 dq offset a507 ; "507"
.data:000000011027D478 dq offset aForgotYourPass ; "&Forgot your Password ?"
.data:000000011027D480 dq offset aMotDePasseOubl ; "&Mot de passe oublié ?"
.data:000000011027D488 dq offset aPasswortVerges ; "&Passwort vergessen?"
.data:000000011027D490 dq offset aOlvidoSuClaveD ; "&Olvidó su Clave de acceso?"
.data:000000011027D498 align 20h
.data:000000011027D4A0 dq offset a508 ; "508"
.data:000000011027D4A8 dq offset aReActivate ; "&Re-Activate"
.data:000000011027D4B0 dq offset aReactiver ; "&Réactiver"
.data:000000011027D4B8 dq offset aReaktivierung ; "&Reaktivierung"
.data:000000011027D4C0 dq offset aReactivar ; "&Reactivar"
.data:000000011027D4C8 align 10h
.data:000000011027D4D0 dq offset a509 ; "509"
.data:000000011027D4D8 dq offset aCancel_4 ; "&Cancel"
.data:000000011027D4E0 dq offset aAnnuler_2 ; "&Annuler"
.data:000000011027D4E8 dq offset aAbbrechen_2 ; "&Abbrechen"
.data:000000011027D4F0 dq offset aCancelar_2 ; "&Cancelar"
.data:000000011027D4F8 align 20h
.data:000000011027D500 dq offset a510 ; "510"
.data:000000011027D508 dq offset aPasswordsDonTM_0 ; "Passwords don't match"
.data:000000011027D510 dq offset aLesMotsDePasse_0 ; "Les mots de passe ne sont pas identique"...
.data:000000011027D518 dq offset aPassworterStim_0 ; "Passwörter stimmen nicht überein"
.data:000000011027D520 dq offset aLasClavesDeAcc_0 ; "Las claves de acceso no concuerdan"
.data:000000011027D528 align 10h
.data:000000011027D530 dq offset a511 ; "511"
.data:000000011027D538 dq offset aYourPasswordHa ; "Your password has been sent"
.data:000000011027D540 dq offset aVotreMotDePass ; "Votre mot de passe a été envoyé"
.data:000000011027D548 dq offset aIhrPasswortWur ; "Ihr Passwort wurde gesendet"
.data:000000011027D550 dq offset aSuClaveDeAcces ; "Su clave de acceso ha sido enviada"
py
from Crypto.Math.Numbers import Integer
from Crypto.Math.Primality import generate_probable_prime
from Crypto.Cipher import AES
from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.PublicKey import RSA
from Crypto import Random
import hashlib
import base64
import ctypes
from ctypes import wintypes
import os
def get_volume_serial_number(drive_letter: str):
# 确保驱动器字母格式正确
if not drive_letter.endswith('\\'):
drive_letter += '\\'
# 定义函数参数和返回类型
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
kernel32.GetVolumeInformationW.argtypes = [
wintypes.LPCWSTR, # lpRootPathName
wintypes.LPWSTR, # lpVolumeNameBuffer
wintypes.DWORD, # nVolumeNameSize
ctypes.POINTER(wintypes.DWORD), # lpVolumeSerialNumber
ctypes.POINTER(wintypes.DWORD), # lpMaximumComponentLength
ctypes.POINTER(wintypes.DWORD), # lpFileSystemFlags
wintypes.LPWSTR, # lpFileSystemNameBuffer
wintypes.DWORD # nFileSystemNameSize
]
kernel32.GetVolumeInformationW.restype = wintypes.BOOL
# 准备参数
volume_name_buffer = ctypes.create_unicode_buffer(1024)
volume_serial_number = wintypes.DWORD()
max_component_length = wintypes.DWORD()
file_system_flags = wintypes.DWORD()
file_system_name_buffer = ctypes.create_unicode_buffer(1024)
# 调用函数
success = kernel32.GetVolumeInformationW(
drive_letter,
volume_name_buffer,
ctypes.sizeof(volume_name_buffer),
ctypes.byref(volume_serial_number),
ctypes.byref(max_component_length),
ctypes.byref(file_system_flags),
file_system_name_buffer,
ctypes.sizeof(file_system_name_buffer)
)
if not success:
error_code = ctypes.get_last_error()
raise RuntimeError(
f"GetVolumeInformationW failed with error code {error_code}")
# 格式化序列号
ser_num = volume_serial_number.value
return f'{ser_num:08X}'
high = ser_num >> 16
low = ser_num & 0xFFFF
return f"{high:04X}-{low:04X}"
def get_disk_space(drive_letter: str):
# 确保驱动器字母格式正确
if not drive_letter.endswith('\\'):
drive_letter += '\\'
# 定义函数参数和返回类型
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
kernel32.GetDiskFreeSpaceExW.argtypes = [
wintypes.LPCWSTR, # lpDirectoryName
ctypes.POINTER(ctypes.c_ulonglong), # lpFreeBytesAvailable
ctypes.POINTER(ctypes.c_ulonglong), # lpTotalNumberOfBytes
ctypes.POINTER(ctypes.c_ulonglong) # lpTotalNumberOfFreeBytes
]
kernel32.GetDiskFreeSpaceExW.restype = wintypes.BOOL
# 准备参数
free_bytes_available = ctypes.c_ulonglong()
total_number_of_bytes = ctypes.c_ulonglong()
total_number_of_free_bytes = ctypes.c_ulonglong()
# 调用函数
success = kernel32.GetDiskFreeSpaceExW(
drive_letter,
ctypes.byref(free_bytes_available),
ctypes.byref(total_number_of_bytes),
ctypes.byref(total_number_of_free_bytes)
)
if not success:
error_code = ctypes.get_last_error()
raise RuntimeError(
f"GetDiskFreeSpaceExW failed with error code {error_code}")
return {
'total_bytes': total_number_of_bytes.value,
'free_bytes': free_bytes_available.value,
'used_bytes': total_number_of_bytes.value - free_bytes_available.value
}
def get_computer_name():
return os.environ['COMPUTERNAME']
COMPUTER_NAME = get_computer_name()
def gen_MACHINE_ID(drive_letter: str = "C:") -> str:
m_id = str(586)
m_id += get_volume_serial_number(drive_letter)
m_id += str(get_disk_space(drive_letter)['total_bytes'])
m_id += COMPUTER_NAME
return hashlib.md5(m_id.encode()).hexdigest().upper()
MACHINE_ID = gen_MACHINE_ID()
B64_Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
def b64_to_value(char):
if char in B64_Table:
return B64_Table.index(char)
else:
return -1
def int2b64(n: int) -> str:
if n == 0:
return B64_Table[0]
result = []
# 不断除以64并取余数
while n > 0:
remainder = n % 64
result.append(B64_Table[remainder])
n = n // 64
base64_str = ''.join(reversed(result))
return base64_str
def b64toint(s: str) -> int:
n = 0
for i, x in enumerate(s[::-1]):
n += B64_Table.index(x)*(0x40**i)
# n+=b64_to_value(x)*(0x40**i)
# print(n)
return n
def generate(bits, randfunc=None, e=65537):
"""Create a new RSA key pair.
The algorithm closely follows NIST `FIPS 186-4`_ in its
sections B.3.1 and B.3.3. The modulus is the product of
two non-strong probable primes.
Each prime passes a suitable number of Miller-Rabin tests
with random bases and a single Lucas test.
Args:
bits (integer):
Key length, or size (in bits) of the RSA modulus.
It must be at least 1024, but **2048 is recommended.**
The FIPS standard only defines 1024, 2048 and 3072.
Keyword Args:
randfunc (callable):
Function that returns random bytes.
The default is :func:`Crypto.Random.get_random_bytes`.
e (integer):
Public RSA exponent. It must be an odd positive integer.
It is typically a small number with very few ones in its
binary representation.
The FIPS standard requires the public exponent to be
at least 65537 (the default).
Returns: an RSA key object (:class:`RsaKey`, with private key).
.. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
"""
# if bits < 1024:
# raise ValueError("RSA modulus length must be >= 1024")
if e % 2 == 0 or e < 3:
raise ValueError(
"RSA public exponent must be a positive, odd integer larger than 2.")
if randfunc is None:
randfunc = Random.get_random_bytes
d = n = Integer(1)
e = Integer(e)
while n.size_in_bits() != bits and d < (1 << (bits // 2)):
# Generate the prime factors of n: p and q.
# By construciton, their product is always
# 2^{bits-1} < p*q < 2^bits.
size_q = bits // 2
size_p = bits - size_q
min_p = min_q = (Integer(1) << (2 * size_q - 1)).sqrt()
if size_q != size_p:
min_p = (Integer(1) << (2 * size_p - 1)).sqrt()
def filter_p(candidate):
return candidate > min_p and (candidate - 1).gcd(e) == 1
p = generate_probable_prime(exact_bits=size_p,
randfunc=randfunc,
prime_filter=filter_p)
min_distance = Integer(1) << (bits // 2 - 100)
def filter_q(candidate):
return (candidate > min_q and
(candidate - 1).gcd(e) == 1 and
abs(candidate - p) > min_distance)
q = generate_probable_prime(exact_bits=size_q,
randfunc=randfunc,
prime_filter=filter_q)
n = p * q
lcm = (p - 1).lcm(q - 1)
d = e.inverse(lcm)
if p > q:
p, q = q, p
u = p.inverse(q)
return RSA.RsaKey(n=n, e=e, d=d, p=p, q=q, u=u)
def gen_rsa_key():
key = generate(512)
e = key.e
n = key.n
d = key.d
print(f'e:{e}')
print(f'd:{d}')
print(f'n:{n}')
enc_e = int2b64(e)
enc_d = int2b64(d)
enc_n = int2b64(n)
print(f'enc_e:{enc_e}')
print(f'enc_d:{enc_d}')
print(f'enc_n:{enc_n}')
'''
e:65537
d:2315142751447774213952423067949813422569754036134759105608004489422512735584755869184456019497130666058725012033222813113267097391007513555249989601567353
n:10285564891816613812819032003811607109443376623812067078211150745570499078196870907576605909732992329074468778493495219319635616763418198567059489030994767
enc_e:QAB
enc_d:sNC6af1sqxUzCGT3XaAIHln7ngLgrbHOOmnP8x0T/EkeNENLF0J1WdWd+rfxMqW2Q2pYtdPf4mJ2TeOeMgaJ5
enc_n:DEYss/FyLOVPDC4yXMyQVYxFqE8ZlaQtkRHrxdu/wwIn6gDbxgQNj3uKd5I/YV8na5pnHZZP9j56ejPiKlzPtP
QAB:DEYss/FyLOVPDC4yXMyQVYxFqE8ZlaQtkRHrxdu/wwIn6gDbxgQNj3uKd5I/YV8na5pnHZZP9j56ejPiKlzPtP
'''
E = 65537
D = 2315142751447774213952423067949813422569754036134759105608004489422512735584755869184456019497130666058725012033222813113267097391007513555249989601567353
N = 10285564891816613812819032003811607109443376623812067078211150745570499078196870907576605909732992329074468778493495219319635616763418198567059489030994767
def base256_string_to_int(s: bytes):
# bytes_to_long
if isinstance(s, str):
s = s.encode()
"""
将 Base256 字符串转换为整数
"""
result = 0
for char in s:
result = (result << 8) | char
return result
def int_to_base256_string(n: int) -> bytes:
"""
== long_to_bytes
将整数转换为 Base256 字符串
"""
if n == 0:
return chr(0)
result = b""
while n > 0:
result = (n & 0xFF).to_bytes(1, 'little') + result
n >>= 8
return result
def rsa_Sign_b64enc(msg: bytes, d: int = D, n: int = N):
# Sign strings with the RSA algorithm, M^d mod n = S
if isinstance(msg, str):
msg = msg.encode()
# m_int=int.from_bytes(msg,'little')
m_int = bytes_to_long(msg)
# print('m_int:',m_int)
# print('m_int_bs:',long_to_bytes(m_int).hex())
# m_int %= n
print('[-]m_int:', m_int)
print('[-]m_int_bs:', long_to_bytes(m_int).hex())
# m_int=base256_string_to_int(msg)
# print('m_int:',m_int)
s = pow(m_int, d, n)
print('[-]sign_int:', s)
sign = long_to_bytes(s)
print('[-]sign_bs:', sign.hex())
return base64.standard_b64encode(sign)
def rsa_Verify_b64(msg: bytes, sign_b64: bytes, e: int = E, n: int = N):
if isinstance(msg, str):
msg = msg.encode()
sign = base64.standard_b64decode(sign_b64)
s_int = bytes_to_long(sign)
m_int = pow(s_int, e, n)
print('[-]dec_sign:', m_int)
m = long_to_bytes(m_int)
print('[-]dec_sign_bs:', m)
v = m_int == (bytes_to_long(msg) % N)
print('[+]Verify:', v)
return v
def x_aes_cfb_b64enc(k: bytes, msg: bytes):
if isinstance(k, str):
k = k.encode()
if isinstance(msg, str):
msg = msg.encode()
key = hashlib.md5(k).digest()
iv = AES.new(key=key, mode=AES.MODE_ECB).encrypt(b'\x00'*16)
print(f'[-]aes_key:{key.hex()}')
print(f'[-]aes_iv:{iv.hex()}')
aes_cipher = AES.new(key=key, iv=iv, mode=AES.MODE_CFB)
ret = aes_cipher.encrypt(msg)
return base64.b64encode(ret)
# return ret
def x_aes_cfb_b64dec(k: bytes, data: bytes):
if isinstance(k, str):
k = k.encode()
data = base64.standard_b64decode(data)
key = hashlib.md5(k).digest()
iv = AES.new(key=key, mode=AES.MODE_ECB).encrypt(b'\x00'*16)
print(f'[-]aes_key:{key.hex()}')
print(f'[-]aes_iv:{iv.hex()}')
aes_cipher = AES.new(key=key, iv=iv, mode=AES.MODE_CFB)
ret = aes_cipher.decrypt(data)
return ret
def parse_rsa_pub_key(rsa_key_str='QAB:D2fhogQkHWOB0jVkEtrS3lr6hgNe/O7pAkxsv2OVHTT6AHyWdPJv1KIwLpUoPh/D1N+BVQ5jGQ1a+nJpptW0SX'):
rsa_key = rsa_key_str.split(':')
exp = b64toint(rsa_key[0])
mod = b64toint(rsa_key[1])
print('exp:', exp)
print('exp_bs:', exp.to_bytes(4, 'little').hex())
print('mod:', mod)
print('mod_bs:', mod.to_bytes(0x40, 'little').hex())
return exp, mod
def gen_CDM_text(save_path:str='',vdate: str = '09/07/2025'):
text = '\r\n'.join(
(
f'VALIDATION_DATE={vdate}',
'PROTECTION_LEVEL=1',
f'MACHINE_ID={MACHINE_ID}\r\n'
)
)
SIGNATURE = rsa_Sign_b64enc(text).decode()
text += f'SIGNATURE={SIGNATURE}\r\n'
k = r"[MQ(UL/&C:&a7eEW"
enc = x_aes_cfb_b64enc(k, text)
cdm=enc.decode()+'|1'
print('[#]CDM text==>\n%s' % cdm)
# dec=x_aes_cfb_b64dec(k,enc)
# print(dec.decode())
if save_path:
with open(save_path,'w') as f:
f.write(cdm)
print('[+]save cdm to==>',save_path)
pass
def parse_cdm(fpath:str):
data=b''
with open(fpath,'rb') as f:
data=f.read()
if data:
dec=x_aes_cfb_b64dec( r"[MQ(UL/&C:&a7eEW",data)
print(dec.decode())
return dec
def fgint_to_int(fgint_number):
"""
将 FGInt.Number 数组转换为 Python 整数
参数:
fgint_number: 列表,第一个元素是数组长度,后续元素是实际数据
返回:
Python 整数
"""
if not fgint_number:
return 0
# 第一个元素是数组长度
n = fgint_number[0]
# 处理特殊情况:空数组或长度为0
if n == 0:
return 0
result = 0
# 从最高位开始处理(数组的最后一个元素是最高位)
for i in range(n, 0, -1):
# 将当前部分左移31位,然后与结果合并
result = (result << 31) | fgint_number[i]
return result
def test_fgint():
m = fgint_to_int([0x00000018, 0x33300D0A, 0x6E848686, 0x6114E0D8, 0x3A119199, 0x73042333, 0x07068846, 0x0C0C4DCE,
0x1CA21822, 0x3D363338, 0x0ABE9288, 0x0D212539, 0x68526A0A, 0x54C3D310, 0x6988AAC8, 0x1253D397,
0x2A22A1AA, 0x0A50524F, 0x60646A1A, 0x40DCBCC8, 0x6981C979, 0x44154453, 0x29E9CBE8, 0x51105512,
0x2B20A624])
print('m:', m)
print('m_bs:', long_to_bytes(m).hex())
def test_rsa_enc():
'''
offine;
.lic use rsa_enc;
NESMaker unuse
'''
# t=int2b64(65537)
# print(t)
rsa_key_str = 'QAB:D2fhogQkHWOB0jVkEtrS3lr6hgNe/O7pAkxsv2OVHTT6AHyWdPJv1KIwLpUoPh/D1N+BVQ5jGQ1a+nJpptW0SX'
# rsa_key_str='QAB:DuYQfR+z9n79UFzMSBlXVOtjIJLuJUapcwG4s8GI9HKNdYD9gtTiG73iM9Ll4yBtao4/YN+v8BgPdctP0wvSYd'
k = b'JBCHDNSZWT44B36S'#random_key_str random_key_1102AD890
rsa_key = rsa_key_str.split(':')
exp = b64toint(rsa_key[0])
mod = b64toint(rsa_key[1])
print('exp:', exp)
print('exp_bs:', exp.to_bytes(4, 'little').hex())
print('mod:', mod)
print('mod_bs:', mod.to_bytes(0x40, 'little').hex())
# RSAEncrypt
random_key = 0b111.to_bytes(1, 'little')+k
p = int.from_bytes(random_key, 'big')
print('p:', p.to_bytes(0x40, 'little'))
Enc: int = pow(p, exp, mod)
x = Enc.to_bytes(0x40, 'big')
print('E:', x.hex())
print(base64.standard_b64encode(x))
def test_rsa_verify():
'''Verify'''
msg = b'popk'
sign_b64 = rsa_Sign_b64enc(msg)
ok = rsa_Verify_b64(msg, sign_b64)
print(ok)
pass
if __name__ == "__main__":
# gen_rsa_key()
# parse_rsa_pub_key()
# test_fgint()
# test_rsa_enc()
# test_rsa_verify()
# cdm_path='C:\\Users\\Public\\NESMaker\\NESMaker.CDM'
cdm_path='xxx.cdm'
validation_date='09/07/2025'
gen_CDM_text(cdm_path,validation_date)
print('\n\n[+]parse_cdm:')
parse_cdm(cdm_path)
pass
'''
[-]m_int: 31178946879257292080898240688144354096635147173692852980966625521388923503413672082345513126911752778805311863617272330815814095581703302651273131528539640583977426287721202654953948320197003686583134745256644711333795728650
[-]m_int_bs: 56414c49444154494f4e5f444154453d30392f30372f323032350d0a50524f54454354494f4e5f4c4556454c3d310d0a4d414348494e455f49443d36333839443044303137383834423730423337423233384538363742434333300d0a
[-]sign_int: 1333855104739181946828192935857681260161462519271575509983654792872898270838449267810765543894119693776075229040494657515955471535802349330038939333573169
[-]sign_bs: 1977bf790f3cb5accc3eb11ca853ffbb8c16a4361cbeaa82f60d48f83b8754c90a1f5c6fd39260a53a986f70245cdf51c75360853e328d80c1e7c72e609a3a31
[-]aes_key:d181d4c2f5d1db0a997db7337a7182a5
[-]aes_iv:ad63cf43f5b0b05b3f3618a0384e8fb9
[#]CDM text==>
y9R02uquDNP24sly54empJ/o3cTurrFYgwwTb1aa0ZXZSMV7C1LlX6LKRF0duy+U5dBAWcYQhaQSypyjQBZ/d0fPt6dP+mrz1dlxfda6hD0Xgg00cPoQaY0uygd96ZrnaxZ2Tq/I0VJamm9HyO4a4IiHD6NPjgHtSxwIbhg1QgBvCuC3SPuqd9ic3oMaok4sPbQAfO0NjiQAuPvaVu1eYEurXmbHRcOxu+7cL54AILOG0N+oIjxyyzDPwgDWLCHKnw==|1
[+]save cdm to==> xxx.cdm
[+]parse_cdm:
[-]aes_key:d181d4c2f5d1db0a997db7337a7182a5
[-]aes_iv:ad63cf43f5b0b05b3f3618a0384e8fb9
VALIDATION_DATE=09/07/2025
PROTECTION_LEVEL=1
MACHINE_ID=6389D0D017884B70B37B238E867BCC30
SIGNATURE=GXe/eQ88tazMPrEcqFP/u4wWpDYcvqqC9g1I+DuHVMkKH1xv05JgpTqYb3AkXN9Rx1NghT4yjYDB58cuYJo6MQ==
'''
ps


浙公网安备 33010602011771号