一个简单的.NET程序的脱壳以及破解
新手入门学习——脱壳破解练习第一期

新手入门学习——脱壳破解练习第一期新手入门学习——脱壳破解练习第一期拿到一个软件,先看看是加的什么壳。
用PEiD查得【Upack V0.37-V0.39 -> Dwing *】接着拿出破解第一要物OD进行脱壳(注意选好点的版本,由于Upack壳做了变形,有些版本的OD打开时会出错,最好是用英文版的)OD载入……我使用简单一点的ESP定律。
00401018 > BE B0114000 MOV ESI,脱壳破解.004011B00040101D AD LODS DWORD PTR DS:[ESI]0040101E 50 PUSH EAX0040101F FF76 34 PUSH DWORD PTR DS:[ESI+34]00401022 EB 7C JMP SHORT 脱壳破解.004010A0F8前进到【0040101F】,在寄存器窗口ESP处点右键,在数据窗口跟随【0012FFC0】如下图://数据窗口点右键,下硬件断点。
shift+F9运行0012FFC0 004011B8 脱壳破解.004011B80012FFC4 7C82F23B 返回到 kernel32.7C82F23B0012FFC8 00000000//来到OEP,通过观察可以发现,这是一个典型的VB入口。
这里记得要删除硬件断点!004011B8 68 24184000 PUSH 脱壳破解.00401824 //OEP004011BD E8 EEFFFFFF CALL 脱壳破解.004011B0004011C2 0000 ADD BYTE PTR DS:[EAX],AL004011C4 0000 ADD BYTE PTR DS:[EAX],AL 004011C6 0000 ADD BYTE PTR DS:[EAX],AL 004011C8 3000 XOR BYTE PTR DS:[EAX],AL记录新入口地址【11B8】接着打开LoadPE进行脱壳然后使用Import Fix 1.6 进行修复修复完成后即得到脱壳后的文件,用PeiD查询,果然是VB。
NET程序的代码混淆、加壳与脱壳讲述

通常我们通过代码混淆、加密的形式达到软件保护的目的。
在Web开发里我们接触过的可能就是JS代码加密了,可以通过对JS代码进行混淆、加密从而实现对核心JS代码的保护。
如果没有接触过的可以在这里简单了解一下,这次我们就不去细说了。
在以前Win32的软件中,加壳脱壳的技术已经发展的非常成熟,国内有大名鼎鼎的看雪、吾爱破解等论坛,三四年前还在上学时,论坛里的大牛一直都是自己的偶像。
而.NET程序因为编译结果不是机器代码语言,而是IL语言,所以加壳脱壳相关的软件还不是很多,我搜索到了一些,如VS自带的DotFuscator、.NET Reactor、xeoncode等,这次我们就简单介绍下手边有的.NET Reactor 。
1.代码混淆代码混淆主要通过一些名称替换、移位、流程混淆的方式来实现。
先来看一个测试的DEMO程序,很简单的一个Winform程序,实例化窗体时实例化一个User 类,点击按钮显示用户名,这样也可以测试加密、加壳后程序是否能够继续运行。
1using System;2using System.Windows.Forms;34namespace CodeObfuscator5 {6public partial class Form1 : Form7 {8private readonly User _currentUser;9public Form1()10 {11 InitializeComponent();12 _currentUser = new User13 {14 UserID = 1,15 UserName = "Parry@cnblogs"16 };17 }1819private void ButtonAlertClick(object sender, EventArgs e)20 {21 MessageBox.Show(_erName);22 }23 }2425public class User26 {27public int UserID { get; set; }28public string UserName { get; set; }29 }30 }我们使用最常用的反编译工具Reflector对生成的exe反编译查看源码。
软件破解脱壳法

软件破解脱壳法什么是脱壳技术?在一些电脑软件里有一段专门负责保护软件不被非法修改或反编译的程序。
它们一般都是先于程序运行拿到控制权,然后完成它们保护软件的任务。
就像动植物的壳一般都是在身体外面一样理所当然(但后来也出现了所谓的“壳中带籽”的壳)。
由于这段程序和自然界的壳在功能上有很多相同的地方,基于命名的规则,大家就把这样的程序称为“壳”了。
就像电脑病毒和自然界的病毒一样,其实都是命名上的方法罢了。
从功能上抽象,软件的壳和自然界中的壳相差无几。
无非是保护、隐蔽壳内的东西。
而从技术的角度出发,壳是一段执行于原始程序前的代码。
原始程序的代码在加壳的过程中可能被压缩、加密……。
当加壳后的文件执行时,壳这段代码先于原始程序运行,他把压缩、加密后的代码还原成原始程序代码,然后再把执行权交还给原始代码。
软件的壳分为加密壳、压缩壳、伪装壳、多层壳等类,目的都是为了隐藏程序真正的OEP(入口点,防止被破解)。
关于“壳”以及相关软件的发展历史请参阅吴先生的《一切从“壳”开始》。
(一)壳的概念:作者编好软件后,编译成exe可执行文件。
1.有一些版权信息需要保护起来,不想让别人随便改动如作者的姓名,即为了保护软件不被破解,通常都是采用加壳来进行保护。
2.需要把程序搞的小一点,从而方便使用。
于是需要用到一些软件,它们能将exe可执行文件压缩。
3.在黑客界给木马等软件加壳脱壳以躲避杀毒软件。
实现上述功能,这些软件称为加壳软件。
(二)加壳软件最常见的加壳软件ASPACK ,UPX,PEcompact 不常用的加壳软件WWPACK32;PE-PACK;PETITE NEOLITE(三)侦测壳和软件所用编写语言的软件,因为脱壳之前要查他的壳的类型。
1.侦测壳的软件 fileinfo.exe 简称 fi.exe (侦测壳的能力极强)。
2.侦测壳和软件所用编写语言的软件language.exe(两个功能合为一体,很棒)推荐。
language2000中文版(专门检测加壳类型)。
无壳源程序破解实例

无壳源程序破解实例(原创版)目录一、无壳源程序的概述二、无壳源程序的破解方法三、无壳源程序破解实例四、总结正文一、无壳源程序的概述无壳源程序,顾名思义,是指没有外壳保护的源程序。
这种程序在计算机安全领域具有一定的研究价值,因为它可以直接反映程序的逻辑和结构,便于分析和理解。
然而,这也使得无壳源程序更容易受到攻击者的关注,他们可能会通过破解程序来实现非法目的。
因此,研究如何保护无壳源程序的安全性显得尤为重要。
二、无壳源程序的破解方法要想破解无壳源程序,攻击者通常会采用以下几种方法:1.静态分析:通过分析源程序的代码,找到潜在的安全漏洞,例如弱口令、硬编码密钥等。
2.动态分析:运行源程序,观察其行为,分析程序的逻辑和功能。
3.反编译:将源程序编译成目标程序,然后对目标程序进行反编译,以获取源程序的代码。
4.模糊测试:向源程序输入随机数据,观察程序的行为,以发现潜在的漏洞。
三、无壳源程序破解实例以一个简单的无壳源程序为例,该程序的功能是计算一个数的阶乘。
源程序如下:```c#include <stdio.h>int factorial(int n) {int result = 1;for (int i = 1; i <= n; i++) {result *= i;}return result;}int main() {int n;printf("请输入一个正整数:");scanf("%d", &n);int result = factorial(n);printf("%d的阶乘是:%d", n, result);return 0;}```攻击者可能会通过以下步骤破解该程序:1.静态分析:发现程序中存在硬编码的数字,如循环次数和输入提示,这些信息可能对攻击者有用。
2.动态分析:运行程序,发现输入一个正整数后,程序会计算该数的阶乘并输出结果。
第27课 .net程序破解

第27课.net程序破解.net程序破解主要使用的工具是.net Reflector。
本教程所用的版本为4.2.43.0。
.net程序要想运行起来,系统必须装有.net Frame Work环境,目前有1.1和2.0两个版本。
有6种语言可供切换、选择。
你可以选择你熟悉的编程语言。
IL是中间语言,可读性差。
但修改时要通过它来定位字节码,修改指令,最后通过16进制编辑器(ultraedit或winhex)来达成心愿。
微软的Ildasm只能反汇编为IL语言,可读性差,因此,破解时不如.net Reflector好用。
另外,IDA pro也是破解.net程序不错的工具。
Ildasm的使用参见附录1,IL语言中各函数的含义参见附录2,仔细研读,你就会熟悉il 语言,破解起来游刃有余。
〔例1〕ForUIC运行程序,如图:就是弹出个窗口,说未注册.net Reflector载入程序,如图:目标程序总在最下方,像剥粽子一样的层层剥开。
注意:其中,References不是我们关心的,不必展开。
双击Main程序,在右边可以看到代码,我选的是VB。
如图:你若稍微懂一点编程,很容易看懂。
程序进行了一个比较,13和23比,不相等,因此,永远弹出注册失败。
因此,有3种改法:(1)13改为23(2)23改为13(3)num1不等于23,不相等则跳,bne改为beq然后,切换到IL语言,代码如下:.method public hidebysig static void Main() cil managed{.entrypoint.maxstack 2.locals init ([0] int32num1)L_0000: ldc.i4.s 13L_0002: stloc.0L_0003: ldloc.0L_0004: ldc.i4.s 23L_0006: bne.un.s L_001aL_0008: ldstr "Registrato!"L_000d: ldstr "Crackme"L_0012: call [System.Windows.Forms]System.Windows.Forms.DialogResult[System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string, string)L_0017: popL_0018: br.s L_002aL_001a: ldstr "Devi registrarmi! :-("L_001f: ldstr "Crackme"L_0024: call [System.Windows.Forms]System.Windows.Forms.DialogResult[System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string, string)L_0029: popL_002a: ret}光标停在L_0000: ldc.i4.s 13显示指令1f 而13的16进制为0d光标停在L_0002: stloc.0 显示指令0a用ILDasm察看,更加清晰。
_NET软件保护与破解浅析

网上很少看到有关.NET软件保护与破解的文章,刚好分析了几款有一定代表性的.NET软件,于是便将他们的保护措施和如何破解方法记录下来,以便和大家交流。
在开始之前,首先申明:本文中反编译和破解的软件只是为学习和研究的目的,请勿非法使用。
.NET平台下的软件(exe,dll文件)叫做程序集。
它使用一种扩展的PE格式文件来保存。
.NET程序集与以往的应用程序不同,它保存的是Microsoft中间语言指令(MSIL)和元数据(Metadata),而不是机器指令和数据。
.NET程序集在运行的时候才会动态将Microsoft中间语言编译成机器指令执行。
所以我们不能简单的使用反汇编来解读程序逻辑。
初学者明白这点很重要。
不过幸运的是,.NET程序集是一种自描述的组件,可以用它自描述的特性反编译出高级程序代码(如c#,),这比汇编代码更容易读懂得多。
即使不反编译成高级程序代码,Microsoft中间语言本身也是一种抽象、基于堆栈的面向对象伪汇编语言。
它本身也比汇编代码更容易读懂。
在代码易阅读这点上,.NET程序更容易遭到破解。
不过,有矛必有盾,现在有很多产品都可以混淆.NET代码,使得反编译出来后的结果也同样没有可读性。
.NET程序集与以往的应用程序另一个不同点在于它可以使用强名称签名来防止自身被篡改。
使用强名称签名的程序集包含公钥和数字签名信息。
.NET在执行具有强名称的程序集前会对它进行安全检查,以防止它被非法篡改。
这一点很厉害,它限制了我们通过修改程序代码(爆破)来破解程序的方法。
.NET平台还提供了很多安全相关的类库,利用这些类库可以写成很强壮的注册算法(如使用RSA 对注册文件签名,只有使用私钥才能产生正确的注册码)。
这些算法破解者很难破解。
另外,现在还出现了很多其他的保护措施,如流程混淆,元数据加密,加密壳,虚拟机技术,编译为本地代码等保护手段。
综合使用这些保护手段,会使破解难道大幅度提高。
软件破解一般有两种方式。
dnguard脱壳原理

dnguard脱壳原理DNGuard脱壳原理什么是DNGuard?DNGuard是一种. NET 程序保护工具,可以对. NET 程序进行加密和混淆,防止恶意破解和逆向工程。
它采用了一系列算法和技术来保护程序代码的安全性。
什么是脱壳?脱壳是指将被保护的程序代码从加密或混淆的状态中还原出来,以便对其进行分析、修改或逆向工程。
脱壳通常被用于学习和研究目的,但也可能被用于非法活动。
DNGuard脱壳原理概述DNGuard采用了多种技术来防止恶意用户对程序进行脱壳。
其脱壳原理可以简要概括如下:1.加密与混淆:DNGuard通过加密和混淆技术来隐藏和保护程序代码。
它使用了不同的加密和混淆算法,使得代码难以被识别和还原。
2.反调试与反反编译:DNGuard内置了反调试和反反编译技术,可以防止调试工具和反编译器对程序进行分析。
它会寻找并禁用常见的调试和反编译工具,并通过增加反调试代码来增加攻击者的难度。
3.运行时保护:DNGuard通过在程序运行时对代码进行保护,增加了脱壳的难度。
它会在代码中插入保护代码,以检测和干扰脱壳行为,如检测调试器、检测动态调用和HOOK等。
DNGuard脱壳原理详解1. 加密与混淆DNGuard使用了多种加密和混淆算法来保护程序代码的安全性。
它会将代码片段进行加密,并将加密后的代码嵌入到程序中。
代码加密可以使用对称加密算法如AES或DES,或者使用非对称加密算法如RSA。
混淆是指将程序代码进行重排、重命名、代码替换等操作,使得代码的结构和逻辑难以被识别和理解。
混淆可以使用代码重排、变量和方法重命名、控制流变换等技术来实现。
2. 反调试与反反编译DNGuard内置了反调试和反反编译技术来防止恶意用户对程序进行脱壳和分析。
它会检测并禁用常见的调试工具和反编译器,如OllyDbg、IDA Pro等。
此外,DNGuard还会在代码中增加反调试代码,以防止调试器的运行。
反反编译是指使用代码和技术来干扰和欺骗反编译工具。
破解步骤

破解软件步骤1,侦壳:先打开侦壳language.exe,选择打开----找到要破解的网络填表终结者:FormGhost.exe,点确定,如图1。
language.exe便显示出软件的壳是:Aspack,如图2。
2,脱壳:双击脱壳AspackDie.exe,出现一个对话框,选择网络填表终结者:FormGhost.exe,打开。
如图3。
出现图4框,点确定脱壳完成。
在网络填表终结者:FormGhost.exe同目录下生成一个unpacked.exe文件,这就是脱壳后的FormGhost.exe。
3,运行脱壳后的unpacked.exe,点帮助----注册,图9。
注册名称,注册码随便添。
图10。
点注册,提示:“注册码错误”图11,好了记住这5个字。
关了它。
大家可以看见,这个:4,开始反汇编:打开反编译W32Dasm黄金中文版,选择反汇编----打开脱壳后的unpacked.exe,变开始加载。
如图5。
图6。
返汇编之后如图7。
点击上面的参考----串式参考如图8出现这个对话框图12。
找到“注册码错误”,双击它,汇编主程序便来到这里:图13。
(注意:正确注册信息在错误信息之上)关闭串式参考框。
看主程序:图14。
从注册码错误向上找到第一个跳转(关键跳,除了jmp的其它跳:je,jne,jz,jnz),来到这里图15(它上面的call叫关键call。
),双击关键跳,看软件最下面有一行字:Line:379267 Pg 7586 of 7626 Code Data@004ACB4B@Offset 00ACB4BH in File:unpacked.exe.其中@Offset 00ACB4BH就是偏移地址,记住00ACB4B(后面的h代表16进制,不用管他),图16。
5,开始修改软件:打开16进制编辑器UltraEdit.rar,(有点慢)图17。
打开脱壳后的unpacked.exe,直接按ctrl+g,出现对话框,输入0xacb4b(即偏移地址,不要前面的000)图18。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一个简单的.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进制工具修改:修改完后保存,看下效果哈,灰色按钮去掉了。