目录

NLog日志框架使用探究-1

NLog日志框架使用探究-2

科学使用Log4View2

前言

这个标题很低调吧,但是既然你点进来,那么接下来的干货是属于你的。

不想成为黑客的程序员不是好程序员。在上一篇《NLog日志框架使用探究-2》文章提到了Log4View2工具有30天的试用期,超过试用期许多功能就被限制,比如不能使用数据库加载。那么我们如何科学使用它呢?

本篇文章涉及到反编译技术、对称加密技术、IL中间语言等技术。掌握了这些技术之后你会发现原来自己也能更加科学的使用软件。

接下来的内容仅供个人学习使用,任何人不得用于商业用途或用于非法途径,一切后果本人概不负责。

科学使用

我们可以使用dnspyilspy以及reflector对.net程序进行反编译。Log4View2就是纯.net开发的项目。

reflector是收费的,也需要科学使用。

ILSpy是开源的.NET程序集浏览器和编译器。

dnSpy是一个调试器和.NET程序集编辑器。即使没有任何可用的源代码,也可以使用它来编辑和调试程序集。

dnspy也是基于ILSpy的反编译引擎,在它基础上增加了丰富的功能,甚至可以直接修改源代码。首先我们通过dyspy看看相关注册的源码,直接在安装路径找到Log4View.exe文件拖入到dbSpy内。

找到licensing相关的模块(命名很友好)

在LicenseMgr可以找到ApplyLicense方法,它会调用CheckForTrial();检查过期时间。

在检查过期时间后回调用SetLicenseInformation()SetLicensedFeatures()

SetLicenseInformation方法是用于从License中获取一些注册信息。

Ctrl+鼠标左键可以跳转到方法

private void SetLicenseInformation()
{
base.LicensedTo = null;
if (this.License == null)
{
return;
}
Log4ViewProductProvider log4ViewProductProvider = this.ProductProvider as Log4ViewProductProvider;
this.ProductInfo = ((log4ViewProductProvider != null) ? log4ViewProductProvider.GetProductName(this.License.ProductReferenceId) : null);
if (!this.License.RegisteredName.IsNullOrEmpty() && !this.License.RegisteredCompany.IsNullOrEmpty())
{
base.LicensedTo = this.License.RegisteredName + "\n" + this.License.RegisteredCompany;
return;
}
if (!this.License.RegisteredName.IsNullOrEmpty())
{
base.LicensedTo = this.License.RegisteredName;
return;
}
if (!this.License.RegisteredCompany.IsNullOrEmpty())
{
base.LicensedTo = this.License.RegisteredCompany;
}
}

SetLicensedFeatures则是根据是否注册,是否试用等信息决定产品功能限制。若注册则根据注册的信息取配置,若是试用,则最大限度开放使用,否则只允许一个接收器,比如你使用网络接收器就不能使用文件接收器,且一些功能会被限制使用。

如图Logboxx和Database功能被禁用。

private void SetLicensedFeatures()
{
if (base.IsRegistered)
{
LicenseMgr.Logger.Info(string.Format("Log4View is licensed with {0}", this.License.LicenseKey));
Log4ViewFeatureAdapter log4ViewFeatureAdapter = new Log4ViewFeatureAdapter(this.License.Features);
this.MultipleInstances = log4ViewFeatureAdapter.MultipleInstances;
this.MaxReceivers = log4ViewFeatureAdapter.MaxReceivers;
this.FileReadFilterEnabled = log4ViewFeatureAdapter.FileReadFilterEnabled;
this.DatabaseReceiverEnabled = log4ViewFeatureAdapter.DatabaseReceiverEnabled;
this.ExportEnabled = log4ViewFeatureAdapter.ExportEnabled;
this.AnnotationsEnabled = log4ViewFeatureAdapter.AnnotationsEnabled;
this.ChartEnabled = log4ViewFeatureAdapter.ChartEnabled;
return;
}
if (this.IsTrial)
{
this.MaxReceivers = 250;
this.FileReadFilterEnabled = (this.MultipleInstances = (this.DatabaseReceiverEnabled = (this.ExportEnabled = (this.AnnotationsEnabled = (this.ChartEnabled = true)))));
return;
}
this.MaxReceivers = 1;
this.FileReadFilterEnabled = (this.MultipleInstances = (this.DatabaseReceiverEnabled = (this.ExportEnabled = (this.AnnotationsEnabled = (this.ChartEnabled = false)))));
}

我们知道了试用所有功能都可以使用,试用又是有试用期的,那么只要我们调大试用期即可。

IsTrial是否试用。

private void CheckForTrial()
{
this.IsTrial = false;
if (this.License != null)
{
return;
}
DateTime? dateTime = base.CheckTrialDate();
if (dateTime != null && dateTime.Value > DateTime.Now)
{
this.TrialExpireTime = dateTime.Value;
LicenseMgr.Logger.Info(string.Format("Log4View License expires on {0}", this.TrialExpireTime));
this.IsTrial = true;
}
}

试用期判断,首先从_licenseStore读取日期参数,然后进行校验。

protected DateTime? CheckTrialDate()
{
Tuple<DateTime, DateTime> tuple = this._licenseStore.CheckTrialDate();
if (tuple == null)
{
return null;
}
DateTime item = tuple.Item1;
DateTime dateTime = tuple.Item2;
if (item > DateTime.Now)
{
return null;
}
if (dateTime < new DateTime(2007, 8, 15, 16, 58, 0))
{
dateTime = DateTime.Now.AddDays(30.0);
}
this._licenseStore.SaveTrialDate(dateTime);
return new DateTime?(dateTime);
}

我们可以直接看保存的时间存放路径。首先将当前时间和过期时间拼凑后加密,然后存储到文件名为FodszqufeUsjbmEbuf的文件中。文件路径则存到了_storagePath字段中

public void SaveTrialDate(DateTime expireDate)
{
string value = LicenseStore.EncryptTrialDate(string.Format(CultureInfo.InvariantCulture, "{0}#{1}", DateTime.Now.ToString(this._trialFormat), expireDate.ToString(this._trialFormat)));
using (StreamWriter streamWriter = new StreamWriter(Path.Combine(this._storagePath, "FodszqufeUsjbmEbuf"), false))
{
streamWriter.Write(value);
}
}

直接Ctrl+F查找一下该变量,可以看到在LicenseStore初始化时会赋值。

public LicenseStore(string productFamilyId, SigningSerializer serializer)
{
this._serializer = serializer;
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
this._storagePath = Path.Combine(folderPath, "Prolic", productFamilyId);
}

Environment.SpecialFolder.CommonApplicationData指向的是系统盘的ProgramData目录下,我的系统盘是C盘,则为C:\ProgramData\,在该目录下可以找到Log4View的日期保存的文件。

我们获取到了文件内容,可以看下NLog是如何加解密的。

protected DateTime? CheckTrialDate()
{
Tuple<DateTime, DateTime> tuple = this._licenseStore.CheckTrialDate();
...
}
public Tuple<DateTime, DateTime> CheckTrialDate()
{
string text = this.ReadTrialDate();
if (string.IsNullOrEmpty(text))
{
return null;
}
string text2 = LicenseStore.DecryptTrialDate(text);
...
}
private static string DecryptTrialDate(string cip)
{
if (cip == null)
{
return null;
}
RijndaelManaged rijndaelManaged = null;
MemoryStream memoryStream = null;
CryptoStream cryptoStream = null;
StreamReader streamReader = null;
string result = null;
try
{
rijndaelManaged = new RijndaelManaged
{
IV = Convert.FromBase64String("X9w3vURHpNUhpU+kICttoQ=="),
Key = Convert.FromBase64String("vhMit23SLc56FN8oylrOUy8trs0I2z7piFrh4vnfx+s=")
};
ICryptoTransform transform = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
memoryStream = new MemoryStream(Convert.FromBase64String(cip));
cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
streamReader = new StreamReader(cryptoStream);
result = streamReader.ReadToEnd();
}
...
return result;
}

可以看出来它使用的是3DES算法。Key和IV都有了。对于RijndaelManaged我个人不是很了解它,因此还需要看以下它默认的分组模式和填充模式。

public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
{
return this.NewEncryptor(rgbKey, this.ModeValue, rgbIV, this.FeedbackSizeValue, RijndaelManagedTransformMode.Encrypt);
}
private ICryptoTransform NewEncryptor(byte[] rgbKey, CipherMode mode, byte[] rgbIV, int feedbackSize, RijndaelManagedTransformMode encryptMode)
{
if (rgbKey == null)
{
rgbKey = Utils.GenerateRandom(this.KeySizeValue / 8);
}
if (rgbIV == null)
{
rgbIV = Utils.GenerateRandom(this.BlockSizeValue / 8);
}
return new RijndaelManagedTransform(rgbKey, mode, rgbIV, this.BlockSizeValue, feedbackSize, this.PaddingValue, encryptMode);
}

查找一下ModeValue是哪里赋值的,选中this.ModeValue右键点击分析

看下哪里被赋值的

protected SymmetricAlgorithm()
{
this.ModeValue = CipherMode.CBC;
this.PaddingValue = PaddingMode.PKCS7;
}

那么聪明的你知道怎么做了吗?比如把超时时间定义到2999年,这是不是很科学呢?

将加密后的文件替换原文件后重启,可以看到过期时间变为了2999年

什么?你懒得加解密,想让我直接给?

拿去吧Rtii82/K20ex7W41cuLLTHBq9qGA/VrVEf/zv7IoPUQL8ZUA8fikC3Saeh5oZUwcTUI+0xdX08OXGXqQwJP+eA==

替换后



想知道为什么?自己去解密一下吧。

编辑和调试程序集

本篇文章实际已经结束了,但是上一篇有人感谢我如此热心还教人破解。

我可不会破解!!!

但是为了让大家学到更多的使用技能,还是在讲一些干货吧。

前面提到了DnSpy是一个调试器和.NET程序集编辑器。即使没有任何可用的源代码,也可以使用它来编辑调试程序集

调试程序集

眼尖的同学可能一开始就看到第一张图绿色的启动按钮。

就像在VS中调试一下,我们打上断点直接启动。



调试方法和在VS中一样,快捷键也一样,F10逐过程或F11逐语句。

编辑程序集

前面我们科学使用还是挺麻烦的,找了半天代码,还要了解加密解密算法。

我们知道只要我们是试用,就可以最大程度的使用软件。那我们直接可以修改源码this.IsTrial = false改为this.IsTrial = true 然后就返回即可。

private void CheckForTrial()
{
this.IsTrial = false;
if (this.License != null)
{
return;
}
DateTime? dateTime = base.CheckTrialDate();
if (dateTime != null && dateTime.Value > DateTime.Now)
{
this.TrialExpireTime = dateTime.Value;
LicenseMgr.Logger.Info(string.Format("Log4View License expires on {0}", this.TrialExpireTime));
this.IsTrial = true;
}
}

直接在需要修改源码的地方右键选择编辑IL指令。

可以看到首先通过ldc.i4.0将0(false)加载到栈,然后调用set_IsTrial赋值。

我们可以将ldc.i4.0改为ldc.i4.1赋值为true。然后将ldarg.0改为ret返回。我们也可以直接新增指令。

本篇的重点不是讲如何学习IL,大家可以到网上搜一下,一搜一大把。

然后点击右下角确定保存,可以发现编译器自动优化了代码。

刚才只是保存到内存中,最后需要保存到文件中。

需要以管理员权限运行DnSpy,否则无法保存。

DnSpy还可以编辑方法。

但是我自己试了下无法编译保存,感兴趣的同学可以自己试试。

结语

本篇文章涉及到了反编译、3DES对称加密、IL语言等技术。同时使用DnSpy可以非常方便的修改IL,修改之后能干什么呢?大家自己发挥吧。

实际上DnSpy修改IL背后帮我们做了许多事情。这些后面的原理都需要我们花更多的时间去学习。最后还是呼吁大家尊重版权,不要传播盗版软件,不要用于非法用途。

最后的最后如果此文对你有帮助的话微信扫一扫关注订阅号杰哥技术分享

推荐文献

  1. 读懂IL代码就这么简单 (一)



微信扫一扫二维码关注订阅号杰哥技术分享

出处:本文地址:https://www.cnblogs.com/Jack-Blog/p/11976252.html

作者:杰哥很忙

本文使用「CC BY 4.0」创作共享协议。欢迎转载,请在明显位置给出出处及链接。

科学使用Log4View2的更多相关文章

  1. NLog日志框架使用探究-2

    目录 前言 自定义参数 日志输出方式 文件 网络传输 数据库 科学使用 参考文档 前言 在一年前,我写过一篇关于NLog入门文章<NLog日志框架使用探究-1>,文章简单的介绍了Nlog的 ...

  2. .net反编译原理

    目录 目录 前言 ILdasm ILasm 结语 推荐文献 目录 NLog日志框架使用探究-1 NLog日志框架使用探究-2 科学使用Log4View2 前言 本来没有想写反编译相关的文章,但是写着写 ...

  3. [数据科学] 从text, json文件中提取数据

    文本文件是基本的文件类型,不管是csv, xls, json, 还是xml等等都可以按照文本文件的形式读取. #-*- coding: utf-8 -*- fpath = "data/tex ...

  4. csv 中 数值被自动转换成科学计数法 的问题 excel打开后数字用科学计数法显示且低位变0的解决方法

    保存在csv中的 013812345678,前面的0会被去掉,后面是科学计数法显示.保存成 col1,="013812345678" 即可. 注意,分隔符逗号后面直接接“=”等号. ...

  5. python和数据科学(Anaconda)

    Python拥有着极其丰富且稳定的数据科学工具环境.遗憾的是,对不了解的人来说这个环境犹如丛林一般(cue snake joke).在这篇文章中,我会一步一步指导你怎么进入这个PyData丛林. 你可 ...

  6. iOS警告收录及科学快速的消除方法

    来自: http://www.cnblogs.com/dsxniubility/p/4757760.html iOS警告收录及科学快速的消除方法     前言:现在你维护的项目有多少警告?看着几百条警 ...

  7. Anaconda 用于科学计算的 Python 发行版

    用于科学计算的 Python 发行版: 1.Anaconda  https://www.continuum.io/    公司continuum.  有商业版本. Anaconda is the le ...

  8. 科学计算软件——Octave安装

    Octave是一个旨在提供与Matlab语法兼容的开放源代码科学计算及数值分析的工具,是Matlab商业软件的一个强有力的竞争产品. 参考:[ML:Octave Installation] Gener ...

  9. 【转】js 中导出excel 较长数字串会变为科学计数法

    [转]js 中导出excel 较长数字串会变成科学计数法 在做项目中,碰到如题的问题.比如要将居民的信息导出到excel中,居民的身份证号码因为长度过长(大于10位),excel会自动的将过长的数字串 ...

随机推荐

  1. 让你的sql开启氮气加速

    事情的过程是:公司有一个上百行的sql 运行在MySQL数据库,速度奇慢无比,逻辑乱七八糟,我就不贴出来了,经过这次修改想总结一下如何写一个不被人骂的sql. 说一些被人诟病的问题: 一.子查询 把你 ...

  2. 【Medium翻译】Java抽象类有什么用?

    今天安利一个网站,其实很多朋友应该早就知道了,我之前ARTS打卡,英文文档的 很多出处就来自于这个网站,叫 「Medium」. 这个网站需要一定的技术去访问,但是为什么说他好呢,因为他号称全球最大的高 ...

  3. 面经-VIVO

    面试时间:2019.09.26 现场面试 面试岗位:广告推荐算法工程师/一面/正式批 面试时长:50Min 面试内容: 自我介绍 阶乘与阶乘和(复杂度高) 文本-视频论文讲解 视频排序讲解 概率题(2 ...

  4. CSP2019游记

    第一轮 Day 0 今天正好学校开运动会,就从开幕式开始翘,申请来机房训练. 早上六点多到了机房. 然后果不其然,运动会又下雨了(祈雨大会).机房冷的一批. 今天中午没有午休时间,去食堂吃个饭就直接来 ...

  5. wpf使用技巧

    1.设置资源 <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries ...

  6. 学习笔记11全局处理程序global.asax

    *全局处理程序Clobal.asax只能叫这个名字,不能修改文件名,如果网站没有的话,可以自己添加. *Application[]类似于session,是全局的,Application["k ...

  7. python正则小结

    注意pattern字符串前要加r    原始字符串 元字符 .                匹配除换行的任意字符 ^            匹配开头 $            匹配结尾 表示重复   ...

  8. NOIP模拟 33

    苏轼三连一脸懵逼 然而既惨者就是没素质 T1是正解思路 然而因为直接从暴力修改过来并且忘了把求约数改成求质约数并且由于快速幂打的有缺陷等 没 有 A C ! 如 果 A C rank1就是俺的了! ( ...

  9. 大数据之路day01_1--Java下载、安装等配置

    从今天开始,我就正式的走上大数据的道路了,如果说我为啥要去学习大数据,可能我的初衷是以后可以接触到人工智能方面的技术,后来在自学的过程中发现,学习人工智能,需要扎实的算法,以及对大量数据的处理,再者, ...

  10. GO 基础学习笔记(4)| 参数传递

    Go 语言的命令行参数传递 //通过下面实操可知,通过命令行传递文件和参数 可复制 1 package main 2 3 import( 4 "fmt" 5 "os&qu ...