一个简单的.NET程序的脱壳以及破解前几天有朋友问.NET程序的破解,又鉴于论坛里关于.NET脱壳和破解的文章也不多,于是抽空写一个。
由于本人也很少接触.NET的程序,因此文章没什么技术含量,用到的技术也是在网上很早就公开的东西。
有什么错误还请多多指教。
本文的目标文件是一个非常简单的CrackMe.本CrackMe的任务有4个:1.脱壳2.去NAG3.去灰色按钮4.破解OK,一个一个来完成任务吧。
一、脱壳查壳发现为:按照经验,此程序应该是用.NET Reactor加的壳下面来脱壳吧根据前人经验,此壳其实只是在简单的混淆,在运行的同时,在内存中会释放原程序的镜像根据这一特点,我们下断点:BP WriteProcessMemory,然后F9运行,中断下来中断下来看堆栈写入的地址为:17B1050在数据窗口查看,然后拉到最顶端可以发现,PE头在017B0000于是可以dump此地址的镜像。
当然,此时dump下来的程序不行,因为还有好多内容没写入。
于是,不断SHIFT+F9,直到程序运行。
这时候就可以dump了.用LordPE,区域转存017B0000这个区段,保存为dumped.exe就OK了.不过,此时dump后,程序是无法运行的。
我们还得再用CFF修正几个量(1).选Nt Headers,再File Header,然后选Characteristics,再点旁边的Click here,在出现的对话框中,去掉“File is a DLL”就OK了。
(2)修正MetaData RV A和MetaData Size的值MetaData RV A值的获得可以用2种方法第一种:原程序中,下完BP WriteProcessMemory,F9运行,第一次中断的时候就dump这个区段,此时的MetaData RV A是正确的。
在CFF中,选.NET Directory,看MetaData RV A的值,并记录:记录这个值为A400,然后在dumped.exe中同样修正这个值为A400第二种:参考老K的文章CFF中,选Address Converter,然后搜索字符“BSJB”接着就换算成RV A的值:换算结果同样为A400下面接着来计算MetaData Size的值选Optional Header,接着点Data Directories [x],然后看Import Directory RV A 的值记下值为BD4C所以,MetaData Size=BD4C-A400=194C故把MetaData Size的值修正为194C脱壳就到此结束了,再用PEiD查下,已经无壳了另外一种抓取镜像文件的方法如下(参考老K文章):首先运行下原程序,继续下标题为:Sample CrackmeOD载入程序,接着F9运行程序,然后ALT+M打开内存镜像,CTRL+B,在搜索UNICODE字符串“Sample Crackme”大约搜索2次后,就来到下面的地方:拉到最上端然后就选备份,保存数据文件,扩展名改为.exe就行后续的操作同上二、去NAG运行程序可以发现,此程序有个讨厌的NAG,并且作者也要求我们去掉分析.NET程序常用的工具为:ildasm2.0,Reflector,xenocode fox我这里就用xenocode fox这个了,因为这个工具可以查看地址当然,默认的选项可能没显示地址,我们可以自己手动改下设置在设置中,选DeCompiler这个选项卡,然后勾上“Show method body address”前面的勾就OK了在语言(Language)选项中,我们先为了分析方便,可以选C#语言,当然你也可以选其他的OK,下面就找关键地方吧,这个没什么好说的,靠自己去寻找。
很明显了吧,这个地方就是显示NAG窗口的代码。
下面就修改这个代码吧,思路就是,在此代码段的头,直接ret,这样,就可以避免产生NAG 窗口了。
为了看机器码和偏移地址,我们把语言改为中间语言IL Assembly代码如下:method private hidebysig instance void uuNkODx(object, [mscorlib]System.EventArgs) cil managed{// Method Body Address: 0x00001524// Code Size: 14 byte(s).maxstack 1.locals init (SampleCrackme.frmNag nag1)L_0000: newobj instance void SampleCrackme.frmNag::.ctor()L_0005: stloc.0L_0006: ldloc.0L_0007: callvirt instance [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.Form::ShowDialog()L_000c: popL_000d: ret}可以发现,ret的机器码为0x 2A,而开头代码段的机器码为0x 73,偏移地址为0x00001524接着就用16进制编辑工具打开脱壳后的程序,定位到0x00001524,把起始代码0x 73修改为0x 2A修改后保存一下,就去掉NAG了三、去灰色按纽原程序这个Check按纽是灰色,而用一般的灰色按纽精灵又去不掉,因为,我们就自己手动来去吧。
同样用xenocode fox来进行分析private void uQZDKK (){// Method Body Address: 0x00001628uuNkODx = new Container();uvUSBXHuS = new Label();ubGakVp2Mu = new Label();uJUoPB0V4HyITVABlwk = new TextBox();uQZDKK = new TextBox();uSIEDr = new Button();ulcmJh = new Button();usL7yU = new Button();u2lcYy2h = new ToolTip(uuNkODx);base.SuspendLayout();uvUSBXHuS.AutoSize = true;uvUSBXHuS.Location = new Point(9, 11); = "label1";uvUSBXHuS.Size = new Size(0x23, 13);uvUSBXHuS.TabIndex = 0;uvUSBXHuS.Text = "Name";ubGakVp2Mu.AutoSize = true;ubGakVp2Mu.Location = new Point(9, 0x28); = "label2";ubGakVp2Mu.Size = new Size(0x21, 13);ubGakVp2Mu.TabIndex = 1;ubGakVp2Mu.Text = "Serial";uJUoPB0V4HyITVABlwk.Location = new Point(0x35, 9); = "txtName";uJUoPB0V4HyITVABlwk.Size = new Size(0xe3, 0x14);uJUoPB0V4HyITVABlwk.TabIndex = 2;uJUoPB0V4HyITVABlwk.TextAlign = HorizontalAlignment.Center;uQZDKK.Location = new Point(0x35, 0x25); = "txtSerial";uQZDKK.Size = new Size(0xe3, 0x14);uQZDKK.TabIndex = 3;uQZDKK.TextAlign = HorizontalAlignment.Center;uSIEDr.Enabled = false;uSIEDr.FlatStyle = FlatStyle.Flat;uSIEDr.Location = new Point(12, 0x45); = "btnCheckIt";uSIEDr.Size = new Size(0x3f, 0x1a);uSIEDr.TabIndex = 4;uSIEDr.Text = "&Check It!";u2lcYy2h.SetToolTip(uSIEDr, "2. Challenge, please enable this button");eVisualStyleBackColor = true;uSIEDr.Click += new EventHandler(this.uJUoPB0V4HyITVABlwk);ulcmJh.DialogResult = DialogResult.Cancel;ulcmJh.FlatStyle = FlatStyle.Flat;ulcmJh.Location = new Point(0x72, 0x45); = "btnExit";ulcmJh.Size = new Size(0x3f, 0x1a);ulcmJh.TabIndex = 5;ulcmJh.Text = "&Exit";eVisualStyleBackColor = true;ulcmJh.Click += new EventHandler(this.uvUSBXHuS);usL7yU.FlatStyle = FlatStyle.Flat;usL7yU.Location = new Point(0xd8, 0x45); = "btnAbout";usL7yU.Size = new Size(0x3f, 0x1a);usL7yU.TabIndex = 6;usL7yU.Text = "&About";eVisualStyleBackColor = true;usL7yU.Click += new EventHandler(this.ubGakVp2Mu);base.AcceptButton = uSIEDr;base.AutoScaleDimensions = new SizeF(6.00F, 13.00F);base.AutoScaleMode = AutoScaleMode.Font;base.CancelButton = ulcmJh;base.ClientSize = new Size(0x124, 0x65);base.Controls.Add(usL7yU);base.Controls.Add(ulcmJh);base.Controls.Add(uSIEDr);base.Controls.Add(uQZDKK);base.Controls.Add(uJUoPB0V4HyITVABlwk);base.Controls.Add(ubGakVp2Mu);base.Controls.Add(uvUSBXHuS);base.FormBorderStyle = FormBorderStyle.FixedToolWindow;base.Icon=(Icon)newComponentResourceManager(typeof(Form1)).GetObject("$this.Icon"); = "Form1";base.StartPosition = FormStartPosition.CenterScreen;Text = "Sample Crackme";base.Load += new EventHandler(this.uuNkODx);base.ResumeLayout(false);base.PerformLayout();}仔细分析可以发现这行代码:uSIEDr.Enabled = false;很明显,就这行代码把这个按钮的可用属性设置为了假,也就是变成的灰色按钮下面,我们就把这个“假”修改为真,让这个按纽可用,把语言修改为中间语言,再分析代码太多,稍微省略点:// Method Body Address: 0x00001628L_01e5: ldarg.0L_01e6: ldfld [System.Windows.Forms]System.Windows.Forms.Button SampleCrackme.Form1::uSIEDrL_01eb: ldc.i4.0L_01ec: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Enabled(bool) L_01f1: ldarg.0L_01f2: ldfld [System.Windows.Forms]System.Windows.Forms.Button SampleCrackme.Form1::uSIEDrL_01f7: ldc.i4.0L_01f8:callvirt instance void [System.Windows.Forms]System.Windows.Forms.ButtonBase::set_FlatStyle([System.Win dows.Forms]System.Windows.Forms.FlatStyle)L_01fd: ldarg.0L_01fe: ldfld [System.Windows.Forms]System.Windows.Forms.Button SampleCrackme.Form1::uSIEDrL_0203: ldc.i4.s 12L_0205: ldc.i4.s 69L_0207: newobj instance void [System.Drawing]System.Drawing.Point::.ctor(int32, int32)L_020c:callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Location([System.Drawing ]System.Drawing.Point)L_0211: ldarg.0L_0212: ldfld [System.Windows.Forms]System.Windows.Forms.Button SampleCrackme.Form1::uSIEDrL_0217: ldstr "btnCheckIt"简单分析结果为:L_01eb: ldc.i4.0 的代码修改为相反的,也就是原来的机器码0x16修改为0x17现在来计算下偏移地址:0x1628+0x1eb=0x1813同样用16进制工具修改:修改完后保存,看下效果哈,灰色按钮去掉了。