将统计表中 应收余额改为应收金额,并隐藏现金收入,储值扣款,过车数量
01原始界面.png (124.15 KB, 下载次数: 0)
下载附件
1
2024-10-30 13:05 上传
二,分析:
(一)Exeinfo查出,程序为.net写的:
用dnspy打开,发现有些变量名是乱码的,导出工程后,在vs中打开,发现会有一些资源丢失了, 用ILSpy打开,再导入到VS中,好多了.系统提示只有为数不多的几个语法错误,一一修复.然后就可以生成exe了.
(二)初步运行
将生成的exe放到原目录,可以打开登录界面并能成功连接数据库,登录系统.但是会弹一个缺少资源的错误
在ILSpy和dnspy中都有看到有这个资源,但是无法导出有效内容,
// Park_manage.Properties.Resources.resources (Embedded, Public)
于是在工程中随意增加一个resources,就不报这个错了,但再次打开时会弹出一个未授权的窗体,
05程序未授权.jpg (10.09 KB, 下载次数: 0)
下载附件
3
2024-10-30 13:05 上传
确定后,就会强制关闭程序,并会打开一个网页,指示未授权.
但是这个原始主程序是可以正常使用的,已经添加了授权的,所有功能都可以正常使用,即始没有授权,也会有一个试用期,不确定这个新打包的程序弹出的界面是从哪冒出来的.
(三)分析主程序
根据网页的提示,搜索到这个是一个需要授权的插件,但是这个原程序中已经就有这个授权了,猜测解包时,授权签名不能导出,可能就是前面提到的Properties.Resources.resources资源文件, 再打包后,就是授权签名就不存在,所以就会提示程序未授权了.
在程序目录中的确有一个前面网页中提示的dll文件.
在主程序中搜索一番,发现有大量调用这个插件里的库, 但一时也不知道这个窗口是从哪个位置调用出来的,
也搜索不到这个字串,搜索MessageBox函数,也没有找到有用的信息.于是在主程序中不断的下断点,结果虽然知道是在 Form_Login 之后的Form_Main中触发的,但是始终找不到具体的位置,用MessageBox来做断点时,初步确定是在某个控件时,dll中自己弹出的.
(四)分析Dll
查看dll,发现也是c#的,用ILSpy查看时,发现是加了混淆的,
06混淆dll.jpg (92.97 KB, 下载次数: 0)
下载附件
4
2024-10-30 13:05 上传
尝试用 de4dot,处理下,结果相当哇噻.
07解混淆.jpg (75.98 KB, 下载次数: 0)
下载附件
5
2024-10-30 13:05 上传
于是载入vs中分析,开始依然是处理语法问题,其中有2处方法,显示0引用,方法体很简单,就直接注释了,后面有问题再说.
[C#] 纯文本查看 复制代码 /*
[CompilerGenerated]
private bool method_0(_003C_003Ef__AnonymousType0 _003C_003Ef__AnonymousType0_0)
{
return _003C_003Ef__AnonymousType0_0.a == this;
}*/
语法处理完毕,再生成dll成功,先将 exe和dll都放在原安装目录,dll替换掉原来的,再运行exe,会提示
引发的异常:“System.IO.FileNotFoundException”(位于 mscorlib.dll 中)
**string_0** 是 null。
08为string0为null.jpg (137.34 KB, 下载次数: 0)
下载附件
6
2024-10-30 13:05 上传
发现 这个source就是刚好就是处理的这个dll, 将 string_0 == "" 改为 string_0 == null || string_0 == "" 解决下参数错误的问题 ,同时发现这个模块()中,有很多加密解密相关的方法,记下模块名为 internal static class Class4
点继续,弹出弹出未授权的窗口.
到这里,exe和dll在功能上基本恢复了.
(五)正式解密
(1) 从出错的地方分析:
查看调用来自一个简类:
[C#] 纯文本查看 复制代码internal class Class5
{
private static string string_0;
internal static string smethod_0(string string_1)
{
return Class4.smethod_1(string_1, smethod_1("8Mv这一串码部分已作隐藏处理MtNcN"));
}
private static string smethod_1(string string_1)
{
try
{
int num = 0;
int length = string_0.Length;
byte[] array = new byte[string_1.Length / 2];
for (int i = 0; i
用测试demo 测试这个解码1函数:
Console.WriteLine(Class5.smethod_1("8Mv这一串码部分已作隐藏处理MtNcN "));
返回结果
这一串码部分已作隐藏处理papa
就是说 Class5.smethod_0(string string_1) 执行的是一个解码2函数 ,相当于
string Class4.smethod_1(string_1, “这一串码部分已作隐藏处理papa”);
这个结果先放到一边,另一边,在dll中搜索MessageBox.Show,结果很有用,
除开 MessageBox.Show(ex.Message);的try错误后,有几个有用的:
MessageBox.Show(Class5.smethod_0(Resources.smethod_36()));
MessageBox.Show(string_0);
先看 MessageBox.Show(Class5.smethod_0(Resources.smethod_36()));所在的函数在 internal class Class6中的:
[C#] 纯文本查看 复制代码 private static void smethod_4() {
bool_0 = false;
int num = 0;
while (true)
{
num++;
if (Application.OpenForms.Count = 3)
{
break;
}
Thread.Sleep(1000);
continue;
}
Application.OpenForms[0].Invoke((MethodInvoker)delegate
{
MessageBox.Show(Class5.smethod_0(Resources.smethod_36()));
Process.Start(Class5.smethod_0(Resources.smethod_37()));
Environment.Exit(0);
});
return;
}
Process.Start(Class5.smethod_0(Resources.smethod_37()));
Environment.Exit(0);
}
参数Resources.smethod_36()调用为
[C#] 纯文本查看 复制代码 internal static string smethod_36()
{
return ResourceManager_0.GetString("t", cultureInfo_0);
}
internal static ResourceManager ResourceManager_0
{
get
{
if (resourceManager_0 == null)
{
ResourceManager resourceManager = resourceManager_0 = new ResourceManager("xxxx.Properties.Resources", typeof(Resources).Assembly);
}
return resourceManager_0;
}
}
依次追踪,发现最终是读取资源文件中的t字符串,资源名称为 xxxx.Properties.Resources,找到里面的资源文件,发现有t值:
t值为: 5E2B7这一串码部分已作隐藏处理37226636EF68
将t值取出,做了一个demo代入到
MessageBox.Show(Class5.smethod_0(Resources.smethod_36()));
得到 “程序未授权!(Unauthorized program!)” 这个字符串,
我说开始搜索不到这个串呢,原来也是要解码的.
得到结论, Class6.smethod_4() 就是弹出个需要授权窗口的操作,再看看另外一个 MessageBox.Show(Class5.smethod_0(Resources.smethod_36()));,也在class6里面的这个方法内:
[C#] 纯文本查看 复制代码 private static void smethod_14()
{
string text = Class4.smethod_1(smethod_20(typeof(Class6).Assembly.Location), Resources.mm.smethod_2()).smethod_3();
if (!string.IsNullOrEmpty(text))
{
string[] array = text.Split('^');
if (array.Length == 2)
{
string text2 = array[0];
int num = Convert.ToInt32(array[1]);
if (!string.IsNullOrEmpty(text2) && num != 0)
{
bool flag = false;
switch (num)
{
case 1:
{
string value = class3_0.method_2();
flag = text2.Equals(value);
break;
}
case 2:
{
List list = smethod_21();
list.AddRange(smethod_22());
flag = list.Contains(text2);
break;
}
}
if ((num == 1 || num == 2) && flag)
{
if (num == 2)
{
smethod_15(text2);
}
if (bool_1 && thread_1 == null)
{
thread_1 = new Thread(smethod_3);
thread_1.IsBackground = true;
thread_1.Start(text);
}
bool_0 = true;
return;
}
}
}
}
bool_0 = false;
MessageBox.Show(Class5.smethod_0(Resources.smethod_36()));
Process.Start(Class5.smethod_0(Resources.smethod_37()));
Environment.Exit(0);
}
这里面最后的操作:
bool_0 = false;
MessageBox.Show(Class5.smethod_0(Resources.smethod_36()));
Process.Start(Class5.smethod_0(Resources.smethod_37()));
Environment.Exit(0);
在两个调用中都出现了,现在分析下具体功能:
bool_0 = false; 为class6的一个属性,猜测为是否已授权
MessageBox.Show(Class5.smethod_0(Resources.smethod_36())); 弹出未授权
Process.Start(Class5.smethod_0(Resources.smethod_37())); 用demo解码出来后 指示一个网页 http://d.xxxx.net/noauthorize.aspx ,就是跳到这个未授权的网页
Environment.Exit(0); 当然就是退出程序了.
(2)
到这里,就有一个简单的暴破的方案:
就是在 Class6.smethod_4() 中直接返回,和 Class6.smethod_14() 中设置bool_0 = true,再直接返回,就行了.
(3)
再次运行,提示缺少资源,MenuTitle.Image = (Image)resources.GetObject("MenuTitle.Image"); 一个图片,直接就是甩一个图片进去.完成后,就可以正常进入系统了.不再弹出授权窗口.
三,后续处理:
(一)
返回exe中,找到相关界面:
namespace Park_manage.statistice 中的 public class Form_monthSumList.cs 和 public class Form_monthSumLis.resx,
修改界面,SQL的操作修改,这里与授权无关,就不再赘叙了.完成后的图
11完成后,cpu高.jpg (191.74 KB, 下载次数: 0)
下载附件
8
2024-10-30 13:05 上传
(二)
有个问题,这个cpu占用一直很高,想到dll中原来会有一个 Thread.Sleep(1000);
于是在这个方法中返回之前 添加一个延时10秒,再次运行,瞬间安静下来了.
private static void smethod_4()
{
Thread.Sleep(10000);
return;
12修复CPU.jpg (178.17 KB, 下载次数: 0)
下载附件
9
2024-10-30 13:05 上传
至此,需求问题就算是初步解决了.这里不想做进一步的授权侵入操作,点到为止.刹果.
四,结束:
文章只是提供了一个解决思路,程序理清后相对简单,以前没有遇到在dll中嵌入授权的情况,特此分享经验.
请勿用于任何非法用途,文章内不提供任何成品代码,思路仅供学习。转载请注明出处