使用 dnSpy 调试源代码转换工具使其具备高级版
1、关于 Tangible Software Solutions 源代码转换器
Tangible Software Solutions 出品最准确可靠的源代码转换器,C#、Java、C++、Python和VB之间的高级转换,为您节省了无数小时的艰苦工作和宝贵时间。
- 官方网站: https://www.tangiblesoftwaresolutions.com/
- 博主发布: https://blog.csdn.net/zyyujq/article/details/143314744
系统要求:
我们所有的转换器都需要 64 位 Windows 10 或更高版本。ARM 处理器需要 Windows 11 才能允许 x64 仿真。
苹果Mac或Linux:使用多引导工具(例如,苹果的“boot Camp”)或虚拟化程序来允许运行Windows。
所有代码转换软件,当前最新版本为 V24.11.X,发布于 2024年11月。
- 免费版没有输出行限制 —— 免费转换任意数量!免费版不允许保存选项以自定义转换
- 可以购买高级版许可证 —— 高级版允许保存选项以自定义转换
序号 | 程序名称 | 功能 | 版本 |
---|---|---|---|
1 | Instant C#(VB.NET to C#) | VB.NET 源代码转换为 C# 源代码 | 24.11.13 |
2 | Instant VB(C# to VB.NET) | C# 源代码转换为 VB.NET 源代码 | 24.11.13 |
3 | C++ to C# Converter | C++ 源代码转换为 C# 源代码 | 24.11.14 |
4 | C++ to Java Converter | C++ 源代码转换为 Java 源代码 | 24.11.14 |
5 | C++ to Python Converter | C++ 源代码转换为 Python 源代码 | 24.11.14 |
6 | Java to C# Converter | Java 源代码转换为 C# 源代码 | 24.11.14 |
7 | Java to C++ Converter | Java 源代码转换为 C++ 源代码 | 24.11.14 |
8 | Java to Python Converter | Java 源代码转换为 Python 源代码 | 24.11.13 |
9 | C# to Java Converter | C# 源代码转换为 Java 源代码 | 24.11.14 |
10 | C# to C++ Converter | C# 源代码转换为 C++ 源代码 | 24.11.14 |
11 | C# to Python Converter | C# 源代码转换为 Python 源代码 | 24.11.14 |
2、Tangible Software Solutions 源代码转换器高级版
Tangible Software Solutions 源代码转换器高级版权利:
- 保存选项以自定义转换 (保存选项后,以后再次使用将默认上次保存的选项)
- 命令行转换
3、使用 dnSpy 调试源代码转换器
以下按 C++ to C# Converter 代码分析为例,经过分析其它源代码转换器文件组成和代码结构非常雷同。
3.1、源代码转换器关键文件组成
C++ to C# Converter 源代码转换器,关键文件为以下 3 个,其它库文件为 .NET 8 库:
- C++ to C# Converter.exe
- C++ to C# Converter.dll
- C++ to CSharp Converter Logic.dll
其它源代码转换器文件组成与此雷同。其它源代码转换器可以按此分析调试!!!
3.2、ExeinfoPe 查看 EXE 和 DLL 文件信息
经过检查发现:
- C++ to C# Converter.exe 为 x64 Microsoft Visual C++ v14.39 - 202x 编译文件
- C++ to C# Converter.dll 为 x64 .NET exe 编译文件
- C++ to CSharp Converter Logic.dll 为 .NET 64 bit DLL 编译文件
这样,就可以使用 dnSpy 调试 C++ to C# Converter.dll 和 C++ to CSharp Converter Logic.dll 了。
3.3、使用 dnSpy 打开源代码转换器进行调试
3.3.1、使用 dnSpy 打开 C++ to C# Converter.dll 分析代码结构
打开后发现三个明显关键类:
- winAbout — 关于窗体类
- winMain — 主窗体类
- winRegDetails — 注册消息窗体类
由此可见 C++ to C# Converter.exe 不过是外壳文件,实际调用 C++ to C# Converter.dll 和 C++ to CSharp Converter Logic.dll 实现代码转换功能,包含高级版注册功能。
- 其它源代码转换器使用 dnSpy 打开后,分析情况高度一致。
3.3.2、dnSpy 分析 winAbout — 关于窗体类
取以下代码可见 _g194._g197 为布尔值判断自由版和高级版,AppCore._g257 为是否过期订单号判断:
this.lblVersionDate.Content = AppCore._g254;
string g = AppCore._g257;
if (_g194._g197)
{
this.lblProductAndVersionNumber.Content = AppCore.ProductName + " - Free Edition (version 24.11.14)";
this.lblRegCode.IsVisible = false;
this.txtRegCode.IsVisible = false;
this.lblLicenseExpiry.IsVisible = false;
if (g.Length > 0)
{
this.lblOrderNumber.Content = "Expired order number";
this.txtOrderNumber.Text = g;
this.txtOrderNumber.SelectionStart = 0;
base.Height -= this.lblLicenseExpiry.Height + 20.0;
return;
}
this.lblOrderNumber.IsVisible = false;
this.txtOrderNumber.IsVisible = false;
base.Height -= this.lblLicenseExpiry.Height + this.txtOrderNumber.Height + 20.0;
return;
}
else
{
this.lblProductAndVersionNumber.Content = AppCore.ProductName + " - Premium Edition (version 24.11.14)";
this.txtRegCode.Text = AppCore.Copyright_Tangible_Software_Solutions_g256;
this.txtRegCode.SelectionStart = 0;
if (g.Length > 0)
{
this.txtOrderNumber.Text = g;
this.txtOrderNumber.SelectionStart = 0;
}
else
{
this.lblOrderNumber.IsVisible = false;
this.txtOrderNumber.IsVisible = false;
}
if (_g2604._g2615)
{
this.lblLicenseExpiry.IsVisible = false;
return;
}
this.lblLicenseExpiry.Content = AppCore._g267;
return;
}
3.3.3、dnSpy 分析 winRegDetails — 注册消息窗体类
初步代码分析,可以预判就是以下窗体的代码:
取以下代码分析(Unlock 单击事件):
private async void cmdUnlock_Click(object _p0, RoutedEventArgs Copyright_Tangible_Software_Solutions_p1)
{
string orderNumber = this.mskOrderNumber.Text.Trim('_').Trim();
if (orderNumber.Length == 0)
{
await _g5._g9(this, "Enter your order number.");
this.mskOrderNumber.Focus(NavigationMethod.Unspecified, KeyModifiers.None);
}
else
{
int num;
int.TryParse(orderNumber, out num);
if (num == 0)
{
await _g5._g9(this, "The order number should be 5 digits.");
this.mskOrderNumber.Focus(NavigationMethod.Unspecified, KeyModifiers.None);
}
else if (num < 10000 || num > 80000)
{
await _g5._g9(this, "Please check the order number you received after purchasing.");
this.mskOrderNumber.Focus(NavigationMethod.Unspecified, KeyModifiers.None);
}
else
{
string newRegCode = this.txtRegCode.Text._g1928();
if (newRegCode.Length == 0)
{
await _g5._g9(this, "Enter your registration code.");
this.txtRegCode.Focus(NavigationMethod.Unspecified, KeyModifiers.None);
}
else if (newRegCode == AppCore.Copyright_Tangible_Software_Solutions_g256)
{
await _g5._g9(this, "Enter the new registration code you received after purchasing.");
this.txtRegCode.Focus(NavigationMethod.Unspecified, KeyModifiers.None);
}
else if (AppCore._g272(newRegCode, orderNumber))
{
winEUA inst = new winEUA(false);
await inst.ShowDialog(this);
if (inst.Accepted)
{
this._proceed = true;
AppCore._g263(newRegCode, orderNumber);
this._g0 = _g0.OK;
base.Close();
inst = null;
}
else
{
await _g5._g9(this, "You have not accepted the license terms.");
}
}
else
{
await _g5._g10(this, string.Concat(new string[]
{
_g1590.Copyright_Tangible_Software_Solutions_g1591(),
" (",
newRegCode,
"). ",
_g1590._g1602(),
"."
}));
}
}
}
}
从上面代码分析可见语句: else if (AppCore._g272(newRegCode, orderNumber)) 此条件判断很关键,
可见 AppCore._g272 是判断注册码和订单号是否正确的逻辑代码。
当逻辑式 AppCore._g272 为 true,条件通过即注册通过!!!
在 dnSpy 中单击 _g272 进入该代码段,可见该代码段位于 C++ to CSharp Converter Logic.dll 动态链接库内 AppCore 类中:
public static bool _g272(string _p0, string Copyright_Tangible_Software_Solutions_p1)
{
return AppCore._g265(_p0, Copyright_Tangible_Software_Solutions_p1) && AppCore._g264(_p0, Copyright_Tangible_Software_Solutions_p1) && !AppCore._g259;
}
从上面代码分析可见,当逻辑式 AppCore._g265 、AppCore._g264 、!AppCore._g259 都为 true 时,逻辑式 AppCore._g272 为 true,条件通过即注册通过!!!
分别在 dnSpy 中单击 _g265 、_g264 、_g259 进入相关代码:
private static bool _g264(string _p0, string Copyright_Tangible_Software_Solutions_p1)
{
int num;
int num2;
_g2604._g2630(_p0, out num, out num2);
int num3;
return num <= 0 || num2 <= 0 || !int.TryParse(Copyright_Tangible_Software_Solutions_p1, out num3) || (num3 >= num && num3 <= num2);
}
private static bool _g265(string _p0, string Copyright_Tangible_Software_Solutions_p1)
{
if (_p0.Length == 0)
{
return false;
}
if (_g2207.Copyright_Tangible_Software_Solutions_g2231(_g1590._g1597(), "") == _p0)
{
return false;
}
if (_g2604.Copyright_Tangible_Software_Solutions_g2631(_p0, Copyright_Tangible_Software_Solutions_p1))
{
_g2207.Copyright_Tangible_Software_Solutions_g2236(_g1590._g1597(), _p0);
return false;
}
return _g2553.Copyright_Tangible_Software_Solutions_g2586(_p0);
}
public static bool _g259
{
get
{
return _g2207._g2232(_g1590._g1599(), false);
}
}
由上可见 _g265 、_g264 是计算 注册码和订单号的关键代码
将 AppCore._g265 、AppCore._g264、 AppCore._g272 通过编辑 IL 指令,设置返回逻辑值 true。
分别将 AppCore._g265 、AppCore._g264、 AppCore._g272 编辑 IL 指令 为:
0 0000 ldc.i4.1
1 0001 ret
确定编辑即可。
编辑 IL 指令完成后, AppCore._g265 、AppCore._g264、 AppCore._g272 显示的 C# 代码为:
private static bool _g264(string _p0, string Copyright_Tangible_Software_Solutions_p1)
{
return true;
}
private static bool _g265(string _p0, string Copyright_Tangible_Software_Solutions_p1)
{
return true;
}
public static bool _g272(string _p0, string Copyright_Tangible_Software_Solutions_p1)
{
return true;
}
在 dnSpy 中保存模块,即保存修改后的 C++ to CSharp Converter Logic.dll
运行程序,随意输入订单号和注册码(字符长度符合要求),确定解锁弹出许可协议,菜单 Unlock the Premium Edition 消失,注册成功。
但程序退出,重新运行时,弹出订单号逾期。
在 dnSpy 中输入 Premium Edition 搜索(C++ to C# Converter.dll 和 C++ to CSharp Converter Logic.dll 中搜索):
在 C++ to CSharp Converter Logic.dll 中搜索 Premium Edition 字符串
发现 _g267 代码符合高级版逾期显示字符:
public static string _g267
{
get
{
DateTime copyright_Tangible_Software_Solutions_g = AppCore.Copyright_Tangible_Software_Solutions_g266;
if (copyright_Tangible_Software_Solutions_g == DateTime.MinValue)
{
return "";
}
if (AppCore.Copyright_Tangible_Software_Solutions_g271)
{
return "Your one-year Premium Edition license expired on " + copyright_Tangible_Software_Solutions_g.ToLongDateString() + ".";
}
return "Your one-year Premium Edition license expires on " + copyright_Tangible_Software_Solutions_g.ToLongDateString() + ".";
}
}
3.3.4、dnSpy 分析 winMain — 主窗体
由上代码分析 AppCore.Copyright_Tangible_Software_Solutions_g271 很关键,结合以上分析,程序重新运行弹出逾期窗体,应该在 winMain — 主窗体类 中有相关逻辑代码
在 C++ to C# Converter.dll 搜索 Premium Edition 字符串
分析可见逾期窗体为 winPremiumEditionRenewal 类
在 winMain — 主窗体类 代码中搜索 winPremiumEditionRenewal
也发现了 AppCore.Copyright_Tangible_Software_Solutions_g271 逻辑关系式,以及逾期打开 winPremiumEditionRenewal 窗体的代码
winMain — 主窗体类 窗体打开事件代码如下:
protected override async void OnOpened(EventArgs e)
{
base.OnOpened(e);
if (!Design.IsDesignMode)
{
winMain._formShown = true;
_g1238._g1255("+ main window OnOpened");
Copyright_Tangible_Software_Solutions_g21._g28(this);
this.FillHistory();
string text;
float num;
_g65.Copyright_Tangible_Software_Solutions_g76(out text, out num);
this.txtSnippetSource.FontFamily = new FontFamily(text);
this.txtSnippetSource.FontSize = (double)num;
string text2;
float num2;
_g65._g77(out text2, out num2);
this.txtSnippetOutput.FontFamily = new FontFamily(text2);
this.txtSnippetOutput.FontSize = (double)num2;
this.grdHistory.Columns[0].Header = "Original " + AppCore._g275 + " Source";
this.grdHistory.Columns[1].Header = "Converted " + AppCore.Copyright_Tangible_Software_Solutions_g276 + " Results";
if (this._bannedRegCode.Length > 0)
{
await _g5._g10(this, string.Concat(new string[]
{
_g1590.Copyright_Tangible_Software_Solutions_g1591(),
" (",
this._bannedRegCode,
"). ",
_g1590._g1602(),
"."
}));
}
bool flag = false;
bool flag2 = false;
int num3 = 0;
bool showUpdateAvailablePopupNotification = false;
if (AppCore.Copyright_Tangible_Software_Solutions_g271)
{
if (!_g2207._g2230)
{
flag = true;
}
}
else
{
if (!_g194._g197 && !_g2604._g2615)
{
num3 = (AppCore.Copyright_Tangible_Software_Solutions_g266 - DateTime.Now).Days;
if (num3 >= 0 && num3 < 10)
{
flag2 = true;
}
}
if (!flag2 && AppCore._g269)
{
showUpdateAvailablePopupNotification = true;
}
}
this.ConversionLinksEnabled = false;
if (flag)
{
await new winPremiumEditionRenewal(true).ShowDialog(this);
}
else if (flag2)
{
if (num3 == 0)
{
await _g5._g9(this, "Your license for " + AppCore.ProductName + " expires today.");
}
else if (num3 == 1)
{
await _g5._g9(this, "Your license for " + AppCore.ProductName + " expires in one day.");
}
else if (num3 > 1)
{
await _g5._g9(this, string.Concat(new string[]
{
"Your license for ",
AppCore.ProductName,
" expires in ",
num3.ToString(),
" days."
}));
}
}
if (showUpdateAvailablePopupNotification)
{
await _g5._g9(this, "A newer version of " + AppCore.ProductName + " is available.");
}
if (!Copyright_Tangible_Software_Solutions_g1276._g1280)
{
string displayName = CultureInfo.CurrentCulture.DisplayName;
if (displayName != "English (Canada)" && !displayName._g1932("English (United States"))
{
await new winFileEncoding(true).ShowDialog(this);
}
Copyright_Tangible_Software_Solutions_g1276._g1280 = true;
}
_g1238._g1255("- main window OnOpened");
}
}
以及 winMain — 主窗体类 中安装最新版本(InstallLatestBuild)代码段,也存在AppCore.Copyright_Tangible_Software_Solutions_g271 调用逾期打开 winPremiumEditionRenewal 窗体的代码:
private async Task InstallLatestBuild()
{
if (AppCore.Copyright_Tangible_Software_Solutions_g271)
{
await new winPremiumEditionRenewal(false).ShowDialog(this);
}
else
{
_g105._g109(_g2604._g2618);
base.Close();
}
}
由此可见 AppCore.Copyright_Tangible_Software_Solutions_g271 逻辑值是 false,则高级版不逾期。
dnSpy 中,在以上代码中单击 g271 进入该代码段:
public static bool Copyright_Tangible_Software_Solutions_g271
{
get
{
if (AppCore._g255)
{
if (_g2604._g2615)
{
return false;
}
long num = DateTime.Now.AddMonths(1).Ticks - DateTime.Now.Ticks;
bool flag;
bool flag2;
long num2 = _g2604._g2629(AppCore._g232, out flag, out flag2);
if (num2 > 0L)
{
if (AppCore._g233 == "13383" && AppCore._g232._g1932("86341KV"))
{
return DateTime.Now.Ticks > new DateTime(2024, 11, 4).Ticks;
}
if (AppCore._g233 == "13620" && AppCore._g232._g1932("84153KS"))
{
return DateTime.Now.Ticks > new DateTime(2025, 11, 4).Ticks;
}
long num3 = DateTime.Now.AddDays(1.0).Ticks - DateTime.Now.Ticks;
if (AppCore._g234 > 0L && AppCore._g234 < num2 + num)
{
if (DateTime.Now.Ticks > AppCore._g234 + AppCore._g270 + num3)
{
return true;
}
}
else if (DateTime.Now.Ticks > num2 + AppCore._g270 + num + num3)
{
return true;
}
}
else
{
if (flag)
{
return true;
}
if (AppCore._g234 > 0L)
{
if (_g2604._g2622 != DateTime.MinValue && _g2604._g2622.Ticks > AppCore._g234 + AppCore._g270 + num)
{
return true;
}
if (AppCore._g205 > AppCore._g234 + AppCore._g270 + num)
{
return true;
}
}
}
}
return false;
}
}
将 AppCore.Copyright_Tangible_Software_Solutions_g271 编辑 IL 指令 为:
0 0000 ldc.i4.0
1 0001 ret
确定编辑即可。
编辑 IL 指令完成后, AppCore.Copyright_Tangible_Software_Solutions_g271 显示的 C# 代码为:
public static bool Copyright_Tangible_Software_Solutions_g271
{
get
{
return false;
}
}
在 dnSpy 中保存模块,即保存修改后的 C++ to CSharp Converter Logic.dll
测试运行 C++ to CSharp Converter,不再弹出逾期,程序调试成功。