程序逆向:.NET程序逆向分析
NET是一种用于构建多种应用的免费开源开发平台,可以使用多种语言,编辑器和库开发Web应用、Web API和微服务、云中的无服务器函数、云原生应用、移动应用、桌面应用、Windows WPF、Windows窗体、通用 Windows平台 (UWP)、游戏、物联网 (IoT)、机器学习、控制台应用、Windows服务。.NET类库在不同应用和应用类型中共享功能,无论构建哪种类型的应用,代码和项目文件
一、.NET平台简介:
1. 简介:
.NET是一种用于构建多种应用的免费开源开发平台,可以使用多种语言,编辑器和库开发Web应用、Web API和微服务、云中的无服务器函数、云原生应用、移动应用、桌面应用、Windows WPF、Windows窗体、通用 Windows平台 (UWP)、游戏、物联网 (IoT)、机器学习、控制台应用、Windows服务。.NET类库在不同应用和应用类型中共享功能,无论构建哪种类型的应用,代码和项目文件看起来都一样,可以访问每个应用的相同运行时、API和语言功能。
NET是微软设计的独立于操作系统之上的平台,可以将其看成一套虚拟机,无论机器运行的是什么操作系统,只要该系统安装了.NET 框架,便可以运行.NET可执行程序。
2.常用的开发语言:
C#(C Sharp):它是.NET平台上的一种编程语言。实际上,C#是为.NET专门设计的,尽管.NET支持多种其他语言。C#是一种现代的、面向对象的、强类型的编程语言,与Java有许多相似之处。
这里再补充一些关于关于windows窗口编程的知识点:
-
Windows应用程序也称为WinForm应用程序,通常包含一个或多个窗体,窗体中又包含了多种控件,如按钮、文本框等。
-
而Form窗体是Windows应用程序的基本单元。Form窗体可以理解为平时程序打开的一个窗口,关于Form窗体的具体事件和常用属性可以看这篇文章:
-
一般使用Visual Studio程序进行窗体应用程序开发的话项目名称为WindowsFormsApplication1
二、.NET平台的逆向:
1. .NET平台程序的识别:
拿到一个程序我们一般会放进一些查壳工具分析,我这里使用的是EXEinfo:
一般会看到该程序是C#编写或者Basic.NET
2.使用工具:
dnspy
3.如何分析.NET平台的程序:
对于这个平台的一些逆向其实和普通的ida分析没啥区别,都是拖进对应的工具分析其算法,但是有些题目可能会对函数名进行混淆,如果在分析时发现一些变量名,类名,函数名的字符特别奇怪,像这样:
对于这些做了混淆的程序,可以使用De4dot来做一个去混淆化的处理。
具体使用方法为
de4dot.exe CrackMe.exe //针对不同位数的程序可以使用de4dot.exe或de4dot-x64.exe
使用该命令后会在当前目录下生成一个以原程序名加“-cleaned”的文件这就是反混淆后的程序
这些知识点可以跟据下面两个程序来实际分析:
三、实例分析:
实例一:
前期信息收集:
1.EXEinfo:
32位,.NET程序,无壳,无混淆
2.运行一下:
在文本框中随便输入一些东西:
Dnspy分析:
用dnspy打开后可以发现这是用Visual Studio创建的一个项目
右击它跳转到函数入口:
查看Main方法的代码:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
// Token: 0x02000004 RID: 4
internal static class Program
{
// Token: 0x0600000A RID: 10 RVA: 0x0000251D File Offset: 0x0000071D
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
一般C#里的Main方法的代码都是相似的一般分为三个语句,第一条语句用于启用应用程序的可视样式,第二条语句用于将某些控件上定义的 UseCompatibleTextRendering
属性设置为应用程序范围内的默认值,第三条代码用于指定要执行的窗体。这里要执行的窗体为“Form1”,双击“Form1”直接跳转值相应代码:
先从Form1方法开始分析:
这里只调用了InitializeComponent()方法,这个方法用于初始化窗口组件,具体的初始化过程在方法里面,继续跟踪:
注意到这里的button1,这里是对窗口中我们输入序列号处文本框的初始化,看到39行处使用了UseVisualStyleBackColor()方法获取一个值,然后在40行对于点击button这个动作的处理是调用button1_Click()方法,继续跟踪这个方法
这里的大概意思就是将获取的值通过Encode进行加密后得到的字符串与“fOCPTVF0diO+B0IMXntkPoRJDUj5CCsT”相比对。所以继续跟踪Encode方法:
Encode方法是将传入的data变量进行DES加密,key为wctf{wol,初始向量为:dy_crack}。然后以base64的形式输出。直接丢到在线网站进行解密即可。
实例二:
前期信息收集:
EXEinfo:
可以看到这个程序是一个.NET程序,但是使用了ConfuserEx,这是一个针对于.NET的混淆器
可以看到上图直接使用dnspy分析程序会看到类名已经是被混淆了,十分影响函数的可读性。之前介绍过可以使用工具de4dot反混淆。
去混淆:
键入命令:
de4dot.exe CrackMe.exe
键入命令后便会生成一个源文件名加上-cleand的程序。之后我们可以直接分析新生成的程序
打开新生成的程序后会发现类名、函数名都已经恢复了
Dnspy分析:
因为这是我的第一个.NET程序的逆向所以会分析的详细一点:
用dnspy打开程序后点击程序集资源管理器中的紫色的CrackMe.exe,可以在右图查看到程序的入口点为“Class0.Main”,其实在程序集资源管理器中还是能看到很多东西比如PE文件结构以及引用等。
点击源代码处找到Class0的Main方法:
可以看到这个图上点击Class0类下面列出了其中包括的方法,这里只有一个Main方法。
点击Class0看一下代码:
这里有点像c语言的start函数:
- Application.EnableVisualStyles()方法:
- 该方法的作用:启用应用程序的可视样式。
- Application.SetCompatibleTextRenderingDefault()方法:
- 该方法的作用:将某些控件上定义的
UseCompatibleTextRendering
属性设置为应用程序范围内的默认值。 - 这个方法有参数,用于新控件的默认值。参数的值为bool值:
- true:则支持
UseCompatibleTextRendering
的新控件使用基于 GDI+ 类进行文本呈现 - false:则新控件使用基于 GraphicsGDI 的 TextRenderer类
- true:则支持
- 该方法的作用:将某些控件上定义的
- Application.Run()方法:
- 该方法的作用:在当前线程上开始运行标准应用程序消息循环,并使指定窗体可见。
- 也就是运行指定窗口
函数入口没啥东西但是告诉了我们主要运行的窗口为Form1
窗体,继续跟踪Form1
窗体处的代码:
这里的关键判断在26~35行:字符串变量a接收输入的值并进行base64编码,之后与字符串变量b中的内容进行比对,相等则输出注册成功。函数的逻辑很简单,我们直接赋值b中的内容进行base64解码就行。
PCTF{Ea5y_Do_Net_Cr4ck3r}
运行程序验证一下:
更多推荐
所有评论(0)