【问题标题】:Where is the method call in the EXE file?EXE文件中的方法调用在哪里?
【发布时间】:2010-05-28 12:30:16
【问题描述】:

简介

在观看了来自 LIDNUG 的关于 .NET 代码保护http://secureteam.net/lidnug_recording/Untitled.swf(尤其是从 46:30 到 57:30)的视频后,我会在我创建的 EXE 中找到对 MessageBox.Show 的调用。

我的“TrialApp.exe”中唯一的逻辑是:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        MessageBox.Show("This is trial app");
    }
}

在发布配置上编译:http://rapidshare.com/files/392503054/TrialApp.exe.html

我如何定位来电

在 WinDBG 中运行应用程序并在出现消息框后中断。

使用!clrstack获取CLR堆栈:

0040e840 5e21350b [InlinedCallFrame: 0040e840] System.Windows.Forms.SafeNativeMethods.MessageBox(System.Runtime.InteropServices.HandleRef, System.String, System.String, Int32)
0040e894 5e21350b System.Windows.Forms.MessageBox.ShowCore(System.Windows.Forms.IWin32Window, System.String, System.String, System.Windows.Forms.MessageBoxButtons, System.Windows.Forms.MessageBoxIcon, System.Windows.Forms.MessageBoxDefaultButton, System.Windows.Forms.MessageBoxOptions, Boolean)
0040e898 002701f0 [InlinedCallFrame: 0040e898] 
0040e934 002701f0 TrialApp.Form1.Form1_Load(System.Object, System.EventArgs)

获取MethodDesc结构(使用Form1_Load的地址)!ip2md 002701f0

MethodDesc:   001762f8
Method Name:  TrialApp.Form1.Form1_Load(System.Object, System.EventArgs)
Class:        00171678
MethodTable:  00176354
mdToken:      06000005
Module:       00172e9c
IsJitted:     yes
CodeAddr:     002701d0
Transparency: Critical
Source file:  D:\temp\TrialApp\TrialApp\Form1.cs @ 22

转储此方法的 IL(通过 MethodDesc)!dumpil 001762f8

IL_0000: ldstr "This is trial app"
IL_0005: call System.Windows.Forms.MessageBox::Show 
IL_000a: pop 
IL_000b: ret 

因此,正如视频中提到的,对Show 的调用是从方法实现开始的 5 个字节。

现在我打开 CFFExplorer(就像在视频中一样)并获取 Form1_Load 方法的 RVA:00002083

之后,我转到地址转换器(再次在 CFF Explorer 中)并导航到偏移量00002083。我们有:

32 72 01 00 00 70 28 16 00 00 0A 26 2A 7A 03 2C
13 02 7B 02 00 00 04 2C 0B 02 7B 02 00 00 04 6F
17 00 00 0A 02 03 28 18 00 00 0A 2A 00 03 30 04 
00 67 00 00 00 00 00 00 00 02 28 19 00 00 0A 02

视频中提到前 12 个字节用于方法头,所以我跳过它们

                                    2A 7A 03 2C
13 02 7B 02 00 00 04 2C 0B 02 7B 02 00 00 04 6F
17 00 00 0A 02 03 28 18 00 00 0A 2A 00 03 30 04 
00 67 00 00 00 00 00 00 00 02 28 19 00 00 0A 02

从实现开始的5个字节应该是方法调用的操作码(28)。不幸的是,不存在。

   02 7B 02 00 00 04 2C 0B 02 7B 02 00 00 04 6F
17 00 00 0A 02 03 28 18 00 00 0A 2A 00 03 30 04 
00 67 00 00 00 00 00 00 00 02 28 19 00 00 0A 02

问题:

  1. 我做错了什么?
  2. 为什么文件中的那个位置没有方法调用?或者视频可能缺少某些信息...
  3. 为什么视频中的那个人用 9 个零代替了通话?

【问题讨论】:

    标签: c# clr windbg opcode cracking


    【解决方案1】:

    当我使用 Ildasm.exe 并查看启用了 Show Bytes 的 IL 时,我看到:

    .method private hidebysig instance void  Form1_Load(object sender,
                                                        class [mscorlib]System.EventArgs e) cil managed
    // SIG: 20 02 01 1C 12 15
    {
      // Method begins at RVA 0x20f1
      // Code size       12 (0xc)
      .maxstack  8
      IL_0000:  /* 72   | (70)00000D       */ ldstr      "This is trial app"
      IL_0005:  /* 28   | (0A)00001E       */ call       valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string)
      IL_000a:  /* 26   |                  */ pop
      IL_000b:  /* 2A   |                  */ ret
    } // end of method Form1::Form1_Load
    

    您的转储中的令牌值不一样,您似乎有一个更大的程序。但是转储中的 IL 从偏移量 1 开始,而不是 12。不确定它为什么关闭。

    【讨论】:

    • 嘿!感谢您的回答。你用你拥有的编译器编译了代码,对吧?因为我看到你有不同的 RVA。问题可能是因为我使用了 VS2010 的编译器(目标平台是 .NET 4.0)造成的吗?
    • 当然,内部结构在 CLR 版本 4 中可能已经完全改变。您正在破解未记录的 CLR 数据结构,一切皆有可能。了解它们的唯一原因是 SSCLI 2.0 源代码。它已经超过 5 年了。
    • 找到了(电话)!在我删除的 12 个字节中。 (从头开始的 6 个字节:28 16 00 00 0A)。 Hans Passant,非常感谢您的有用回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    相关资源
    最近更新 更多