通过编译器解析语句并计算判断条件,然后通过返回的值确定代码的类型。若是无效代码,则将整个代码块删除;若是冗余代码,则保留判断语句内部的代码块,其余部分(if判断语句)则删除以达到精简的目的。这里需要注意的是正则代码只匹配了if条件判断部分,没有针对可能出现的else部分进行匹配,因此在处理时需要单独注意,幸运的是reflector在生成语句的同时,对else语句部分均标注了Label_Else标签,因此我们的匹配过程就变得相对简单了,采用以下正则表达式即可:\nLabel_ELSE:\n[\n ]*else\n[ ]*{([^{}]*)}。在经过以上处理后得到的精简代码如下(由于while(true)死循环语句的特殊性,为了不影响程序执行的流程,我们这里没有对其进行处理):
private void x85601834555fb7d5() { ComponentResourceManager manager = new ComponentResourceManager(typeof(x4dc9cb69c65ee315)); this.x14b9c2a9b57534b8 = new Label(); this.x0049a6285a44bbd6 = new TextBox(); this.x792ada3ad34d61e0 = new TextBox(); this.xf8ffb0d954b2c2f6 = new PictureBox(); this.xb115ebd03641a474 = new Button(); Label_ELSE: goto Label_05BB; goto Label_031E; Label_0056: base.StartPosition = FormStartPosition.CenterParent; this.Text = "错误"; ((ISupportInitialize) this.xf8ffb0d954b2c2f6).EndInit(); base.ResumeLayout(false); base.PerformLayout(); return; Label_00AE: base.Controls.Add(this.xb115ebd03641a474); base.Controls.Add(this.xd15b9cf5592f8785); base.Controls.Add(this.xf6d68814b444670e); Label_ELSE: base.Icon = (Icon) manager.GetObject("$this.Icon"); base.MaximizeBox = false; base.MinimizeBox = false; this.MinimumSize = new Size(0x138, 0x10d); Label_ELSE: base.Name = "MessageForm"; base.SizeGripStyle = SizeGripStyle.Show; goto Label_0056; goto Label_0360; return; Label_010D: base.CancelButton = this.xb115ebd03641a474; base.ClientSize = new Size(0x16a, 0xf6); base.Controls.Add(this.x14b9c2a9b57534b8); Label_013F: base.Controls.Add(this.x0049a6285a44bbd6); base.Controls.Add(this.x792ada3ad34d61e0); base.Controls.Add(this.xf8ffb0d954b2c2f6); goto Label_00AE; Label_0219: this.xf6d68814b444670e.Font = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Bold, GraphicsUnit.Point, 0); this.xf6d68814b444670e.Location = new Point(0x38, 14); this.xf6d68814b444670e.Name = "lblMsg"; this.xf6d68814b444670e.Size = new Size(0x126, 40); this.xf6d68814b444670e.TabIndex = 10; this.xf6d68814b444670e.Text = "An error occurred"; base.AutoScaleMode = AutoScaleMode.Inherit; Label_ELSE: Label_ELSE: goto Label_010D; goto Label_031E; Label_0254: this.xd15b9cf5592f8785.Size = new Size(0x56, 0x11); this.xd15b9cf5592f8785.TabIndex = 12; this.xd15b9cf5592f8785.Text = "错误类型:"; this.xf6d68814b444670e.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top; this.xf6d68814b444670e.FlatStyle = FlatStyle.System; goto Label_0219; Label_031E: this.xb115ebd03641a474.DialogResult = DialogResult.Cancel; Label_ELSE: this.xb115ebd03641a474.FlatStyle = FlatStyle.Popup; while (true) { this.xb115ebd03641a474.Location = new Point(0x11b, 220); this.xb115ebd03641a474.Name = "buttonOK"; this.xb115ebd03641a474.Size = new Size(0x43, 0x18); this.xb115ebd03641a474.TabIndex = 8; this.xb115ebd03641a474.Text = "OK"; this.xb115ebd03641a474.Click += new EventHandler(this.x38e768d357a8f002); this.xd15b9cf5592f8785.FlatStyle = FlatStyle.System; this.xd15b9cf5592f8785.Location = new Point(12, 0x3b); this.xd15b9cf5592f8785.Name = "labelType"; Label_ELSE: Label_ELSE: goto Label_0254; } Label_0360: this.xf8ffb0d954b2c2f6.Paint += new PaintEventHandler(this.x952d2a572666dc32); this.xb115ebd03641a474.Anchor = AnchorStyles.Right | AnchorStyles.Bottom; goto Label_031E; goto Label_03EE; Label_0395: this.xf8ffb0d954b2c2f6.Location = new Point(12, 12); this.xf8ffb0d954b2c2f6.Name = "pictIcon"; this.xf8ffb0d954b2c2f6.Size = new Size(0x26, 0x22); this.xf8ffb0d954b2c2f6.TabIndex = 9; Label_ELSE: this.xf8ffb0d954b2c2f6.TabStop = false; goto Label_0360; Label_03EE: this.x792ada3ad34d61e0.Size = new Size(0x152, 0x15); this.x792ada3ad34d61e0.TabIndex = 13; goto Label_0395; Label_0435: this.x792ada3ad34d61e0.Name = "textType"; Label_ELSE: this.x792ada3ad34d61e0.ReadOnly = true; Label_ELSE: goto Label_03EE; Label_04D4: this.x0049a6285a44bbd6.Location = new Point(12, 0x83); Label_ELSE: this.x0049a6285a44bbd6.Multiline = true; this.x0049a6285a44bbd6.Name = "textDetails"; this.x0049a6285a44bbd6.ReadOnly = true; this.x0049a6285a44bbd6.ScrollBars = ScrollBars.Vertical; this.x0049a6285a44bbd6.Size = new Size(0x152, 0x53); this.x0049a6285a44bbd6.TabIndex = 15; this.x792ada3ad34d61e0.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top; this.x792ada3ad34d61e0.BackColor = SystemColors.Info; this.x792ada3ad34d61e0.BorderStyle = BorderStyle.FixedSingle; this.x792ada3ad34d61e0.Location = new Point(12, 0x4c); goto Label_0435; Label_0523: this.x14b9c2a9b57534b8.Text = "错误明细:"; this.x0049a6285a44bbd6.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Top; this.x0049a6285a44bbd6.BackColor = SystemColors.Info; this.x0049a6285a44bbd6.BorderStyle = BorderStyle.FixedSingle; goto Label_04D4; goto Label_05BB; Label_0558: this.x14b9c2a9b57534b8.Size = new Size(0x43, 0x11); this.x14b9c2a9b57534b8.TabIndex = 14; goto Label_0523; Label_0593: this.x14b9c2a9b57534b8.Location = new Point(12, 0x6f); Label_05A7: this.x14b9c2a9b57534b8.Name = "labelDetails"; goto Label_0558; Label_05BB: this.xd15b9cf5592f8785 = new Label(); this.xf6d68814b444670e = new Label(); Label_05D1: ((ISupportInitialize) this.xf8ffb0d954b2c2f6).BeginInit(); base.SuspendLayout(); this.x14b9c2a9b57534b8.FlatStyle = FlatStyle.System; Label_ELSE: goto Label_0593; goto Label_0523; }
从上面可以看出,经过清理的语句精简了很多,除正常代码语句外,只保留了完整的goto_***跳转语句及Label_***标签。可以证实,清除无效代码及精简冗余代码并不会对原有代码的执行流程造成影响,我们下一步的工作就是将这一执行的流程还原出来,也即流程的反混淆。采用的方法很简单,就是模拟程序正常执行的过程将以上代码执行一遍,遇到需要跳转的地方就将跳转后所执行的语句块替换到该位置,然后顺序执行、再替换直到执行到最后一条语句或是直到无效的跳转即可。在这里通常会有担心程序出现死循环的可能,但是我们这里所指的“执行”与真正的程序运行之间是有区别的,是针对语句的检查而不是真实的运行,考虑到经过加密后的代码在执行时必须会保证流程正常这一前提,并且在清除了无效代码以后,前面担心出现的死循环的问题就不存在了。经过反混淆后得到的代码如下:
private void x85601834555fb7d5() { ComponentResourceManager manager = new ComponentResourceManager(typeof (x4dc9cb69c65ee315)); this.x14b9c2a9b57534b8 = new Label(); this.x0049a6285a44bbd6 = new TextBox(); this.x792ada3ad34d61e0 = new TextBox(); this.xf8ffb0d954b2c2f6 = new PictureBox(); this.xb115ebd03641a474 = new Button(); this.xd15b9cf5592f8785 = new Label(); this.xf6d68814b444670e = new Label(); ((ISupportInitialize) this.xf8ffb0d954b2c2f6).BeginInit(); base.SuspendLayout(); this.x14b9c2a9b57534b8.FlatStyle = FlatStyle.System; this.x14b9c2a9b57534b8.Location = new Point(12, 0x6f); this.x14b9c2a9b57534b8.Name = "labelDetails"; this.x14b9c2a9b57534b8.Size = new Size(0x43, 0x11); this.x14b9c2a9b57534b8.TabIndex = 14; this.x14b9c2a9b57534b8.Text = "错误明细:"; this.x0049a6285a44bbd6.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Top; this.x0049a6285a44bbd6.BackColor = SystemColors.Info; this.x0049a6285a44bbd6.BorderStyle = BorderStyle.FixedSingle; this.x0049a6285a44bbd6.Location = new Point(12, 0x83); this.x0049a6285a44bbd6.Multiline = true; this.x0049a6285a44bbd6.Name = "textDetails"; this.x0049a6285a44bbd6.ReadOnly = true; this.x0049a6285a44bbd6.ScrollBars = ScrollBars.Vertical; this.x0049a6285a44bbd6.Size = new Size(0x152, 0x53); this.x0049a6285a44bbd6.TabIndex = 15; this.x792ada3ad34d61e0.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top; this.x792ada3ad34d61e0.BackColor = SystemColors.Info; this.x792ada3ad34d61e0.BorderStyle = BorderStyle.FixedSingle; this.x792ada3ad34d61e0.Location = new Point(12, 0x4c); this.x792ada3ad34d61e0.Name = "textType"; this.x792ada3ad34d61e0.ReadOnly = true; this.x792ada3ad34d61e0.Size = new Size(0x152, 0x15); this.x792ada3ad34d61e0.TabIndex = 13; this.xf8ffb0d954b2c2f6.Location = new Point(12, 12); this.xf8ffb0d954b2c2f6.Name = "pictIcon"; this.xf8ffb0d954b2c2f6.Size = new Size(0x26, 0x22); this.xf8ffb0d954b2c2f6.TabIndex = 9; this.xf8ffb0d954b2c2f6.TabStop = false; this.xf8ffb0d954b2c2f6.Paint += new PaintEventHandler(this.x952d2a572666dc32); this.xb115ebd03641a474.Anchor = AnchorStyles.Right | AnchorStyles.Bottom; this.xb115ebd03641a474.DialogResult = DialogResult.Cancel; this.xb115ebd03641a474.FlatStyle = FlatStyle.Popup; this.xb115ebd03641a474.Location = new Point(0x11b, 220); this.xb115ebd03641a474.Name = "buttonOK"; this.xb115ebd03641a474.Size = new Size(0x43, 0x18); this.xb115ebd03641a474.TabIndex = 8; this.xb115ebd03641a474.Text = "OK"; this.xb115ebd03641a474.Click += new EventHandler(this.x38e768d357a8f002); this.xd15b9cf5592f8785.FlatStyle = FlatStyle.System; this.xd15b9cf5592f8785.Location = new Point(12, 0x3b); this.xd15b9cf5592f8785.Name = "labelType"; this.xd15b9cf5592f8785.Size = new Size(0x56, 0x11); this.xd15b9cf5592f8785.TabIndex = 12; this.xd15b9cf5592f8785.Text = "错误类型:"; this.xf6d68814b444670e.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top; this.xf6d68814b444670e.FlatStyle = FlatStyle.System; this.xf6d68814b444670e.Font = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Bold, GraphicsUnit.Point, 0); this.xf6d68814b444670e.Location = new Point(0x38, 14); this.xf6d68814b444670e.Name = "lblMsg"; this.xf6d68814b444670e.Size = new Size(0x126, 40); this.xf6d68814b444670e.TabIndex = 10; this.xf6d68814b444670e.Text = "An error occurred"; base.AutoScaleMode = AutoScaleMode.Inherit; base.CancelButton = this.xb115ebd03641a474; base.ClientSize = new Size(0x16a, 0xf6); base.Controls.Add(this.x14b9c2a9b57534b8); base.Controls.Add(this.x0049a6285a44bbd6); base.Controls.Add(this.x792ada3ad34d61e0); base.Controls.Add(this.xf8ffb0d954b2c2f6); base.Controls.Add(this.xb115ebd03641a474); base.Controls.Add(this.xd15b9cf5592f8785); base.Controls.Add(this.xf6d68814b444670e); base.Icon = (Icon) manager.GetObject("$this.Icon"); base.MaximizeBox = false; base.MinimizeBox = false; this.MinimumSize = new Size(0x138, 0x10d); base.Name = "MessageForm"; base.SizeGripStyle = SizeGripStyle.Show; base.StartPosition = FormStartPosition.CenterParent; this.Text = "错误"; ((ISupportInitialize) this.xf8ffb0d954b2c2f6).EndInit(); base.ResumeLayout(false); base.PerformLayout(); }
经工具处理后得到了正常流程的代码,while(true)死循环语句在处理得到正确流程后再匹配并去除。在流程还原出来以后,程序就比较容易阅读了,基本上也可以正常调试了。最后,我们还希望还原以上加密了的字符串,类似Xenocode的加密工具往往采取的是不可逆的加密算法(推测),因此直接破译的难度会很大。我们只好退而求其次,从代码中可以看到,在生成每个控件的时候控件均赋予了一个名称,如:this.x14b9c2a9b57534b8.Name = "labelDetails";一般而言,这个名称如果不是程序员手工命名的,VS也会自动添加诸如label1这样的名称。于是很简单的,我们可以认为上述代码中x14b9c2a9b57534b8的原始名称即为labelDetails。另外,针对事件响应的绑定代码:比如this.xb115ebd03641a474.Click += new EventHandler(this.x38e768d357a8f002);按VS自动生成的规律来推测,委托的函数名称为控件名称、加下划线、加事件名称组合而成,因此就可以还原x38e768d357a8f002的值。依此规律即可将大部分加密的名称和参数还原(注意,仅针对窗体程序)。还原后得到代码如下:
private void x85601834555fb7d5() { ComponentResourceManager manager = new ComponentResourceManager(typeof (MessageForm)); this.labelDetails = new Label(); this.textDetails = new TextBox(); this.textType = new TextBox(); this.pictIcon = new PictureBox(); this.buttonOK = new Button(); this.labelType = new Label(); this.lblMsg = new Label(); ((ISupportInitialize) this.pictIcon).BeginInit(); base.SuspendLayout(); this.labelDetails.FlatStyle = FlatStyle.System; this.labelDetails.Location = new Point(12, 0x6f); this.labelDetails.Name = "labelDetails"; this.labelDetails.Size = new Size(0x43, 0x11); this.labelDetails.TabIndex = 14; this.labelDetails.Text = "错误明细:"; this.textDetails.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Top; this.textDetails.BackColor = SystemColors.Info; this.textDetails.BorderStyle = BorderStyle.FixedSingle; this.textDetails.Location = new Point(12, 0x83); this.textDetails.Multiline = true; this.textDetails.Name = "textDetails"; this.textDetails.ReadOnly = true; this.textDetails.ScrollBars = ScrollBars.Vertical; this.textDetails.Size = new Size(0x152, 0x53); this.textDetails.TabIndex = 15; this.textType.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top; this.textType.BackColor = SystemColors.Info; this.textType.BorderStyle = BorderStyle.FixedSingle; this.textType.Location = new Point(12, 0x4c); this.textType.Name = "textType"; this.textType.ReadOnly = true; this.textType.Size = new Size(0x152, 0x15); this.textType.TabIndex = 13; this.pictIcon.Location = new Point(12, 12); this.pictIcon.Name = "pictIcon"; this.pictIcon.Size = new Size(0x26, 0x22); this.pictIcon.TabIndex = 9; this.pictIcon.TabStop = false; this.pictIcon.Paint += new PaintEventHandler(this.pictIcon_Paint); this.buttonOK.Anchor = AnchorStyles.Right | AnchorStyles.Bottom; this.buttonOK.DialogResult = DialogResult.Cancel; this.buttonOK.FlatStyle = FlatStyle.Popup; this.buttonOK.Location = new Point(0x11b, 220); this.buttonOK.Name = "buttonOK"; this.buttonOK.Size = new Size(0x43, 0x18); this.buttonOK.TabIndex = 8; this.buttonOK.Text = "OK"; this.buttonOK.Click += new EventHandler(this.buttonOK_Click); this.labelType.FlatStyle = FlatStyle.System; this.labelType.Location = new Point(12, 0x3b); this.labelType.Name = "labelType"; this.labelType.Size = new Size(0x56, 0x11); this.labelType.TabIndex = 12; this.labelType.Text = "错误类型:"; this.lblMsg.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top; this.lblMsg.FlatStyle = FlatStyle.System; this.lblMsg.Font = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Bold, GraphicsUnit.Point, 0); this.lblMsg.Location = new Point(0x38, 14); this.lblMsg.Name = "lblMsg"; this.lblMsg.Size = new Size(0x126, 40); this.lblMsg.TabIndex = 10; this.lblMsg.Text = "An error occurred"; base.AutoScaleMode = AutoScaleMode.Inherit; base.CancelButton = this.buttonOK; base.ClientSize = new Size(0x16a, 0xf6); base.Controls.Add(this.labelDetails); base.Controls.Add(this.textDetails); base.Controls.Add(this.textType); base.Controls.Add(this.pictIcon); base.Controls.Add(this.buttonOK); base.Controls.Add(this.labelType); base.Controls.Add(this.lblMsg); base.Icon = (Icon) manager.GetObject("$this.Icon"); base.MaximizeBox = false; base.MinimizeBox = false; this.MinimumSize = new Size(0x138, 0x10d); base.Name = "MessageForm"; base.SizeGripStyle = SizeGripStyle.Show; base.StartPosition = FormStartPosition.CenterParent; this.Text = "错误"; ((ISupportInitialize) this.pictIcon).EndInit(); base.ResumeLayout(false); base.PerformLayout(); }
以上代码的字符串虽然还原的不算十分彻底(比如涉及到与其它控件关联的函数名称,需要结合代码其它部分进行分析和还原),但是目前的代码就已经很容易进行阅读和测试了。
(注:本文为 [风影网络工作室] 原创文章,未经书面许可,严禁转载和复制本站的任何信息,违者必究)