怎样给没有源代码的.net程序添加修改功能

要修改一段代码,可是找不到源代码了,怎么办呢?
具体情况如下:

某个.NET小网站,在做数据库的查询修改删除操作的时候,没有验证输入参数的合法性,没有做错误处理,导致页面异常.

代码如下:

Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      iClass.Verify(Me)
      Me.DirId = Me.Request.QueryString.Item("DirId")
      Me.InfoId = Me.Request.QueryString.Item("InfoId")
      If Not IsNumber(Me.DirId) Then
            Me.DirId = ""
      End If
      Dim adapter1 As New OleDbDataAdapter(("Select * from Directory where Dirid = " & Me.DirId), Me.mCn)
      Dim table1 As New DataTable
      adapter1.Fill(table1)
      Me.DirPath = StringType.FromObject(table1.Rows.Item(0).Item("DirPath"))
      If (StringType.StrCmp(FileSystem.Dir(Me.Server.MapPath(Me.DirPath), FileAttribute.Directory), "", False) = 0) Then
            FileSystem.MkDir(Me.Server.MapPath(Me.DirPath))
      End If
      If Not Me.Page.IsPostBack Then
            Dim adapter2 As New OleDbDataAdapter(("Select * from info where InfoId=" & Me.InfoId & "and dirid=" & Me.DirId), Me.mCn)
            Dim table2 As New DataTable
            adapter2.Fill(table2)
            Me.txtTitle.Text = table2.Rows.Item(0).Item("Infotitle").ToString.Trim
            Me.txtMain.set_Text(table2.Rows.Item(0).Item("Infomain").ToString.Trim)
            Me.txtMain.set_Text(iClass.unchangestr(Me.txtMain.get_Text).ToString.Trim)
            Me.txtMaker.Text = table2.Rows.Item(0).Item("Infomaker").ToString.Trim
            Me.txtReship.Text = table2.Rows.Item(0).Item("Inforeship").ToString.Trim
      End If
End Sub

其中如果参数DirId和InfoId不为数字型的话,会造成
 "Select * from Directory where Dirid = " & Me.DirId
以及
 "Select * from info where InfoId=" & Me.InfoId & "and dirid=" & Me.DirId
的SQL语句查询出错

解决方法:
If Not IsNumber(Me.DirId) Then
    Me.DirId = ""
End If
改成
If Not IsNumber(DirId) Or Not IsNumeric(InfoId) Then
   DirId = ""
   Return
End If

新建一WEB项目,在Page_Load事件中加入以下代码

Verify(Me)
DirId = Request.QueryString("DirId")
InfoId = Request.QueryString("InfoId")
If Not IsNumber(DirId) Or Not IsNumeric(InfoId) Then
   DirId = ""
   Return
End If
Dim objApt As New OleDbDataAdapter("Select * from Directory where Dirid = " & DirId, mCn)
Dim objDt1 As New DataTable
objApt.Fill(objDt1)
DirPath = objDt1.Rows(0)("DirPath")
If Dir(Me.Server.MapPath(DirPath), FileAttribute.Directory) = "" Then
    MkDir(Me.Server.MapPath(DirPath))
End If
If Not Page.IsPostBack Then
    Dim objApt1 As New OleDbDataAdapter("Select * from info where InfoId=" & InfoId & " and dirid=" & DirId, mCn)
    Dim objDt As New DataTable
    objApt1.Fill(objDt)
    txtTitle.Text = objDt.Rows(0)("Infotitle").ToString.Trim
    txtMain.Text = objDt.Rows(0)("Infomain").ToString.Trim
    txtMain.Text = unchangestr(txtMain.Text).ToString.Trim
    txtMaker.Text = objDt.Rows(0)("Infomaker").ToString.Trim
    txtReship.Text = objDt.Rows(0)("Inforeship").ToString.Trim
End If

(注意,控件中要用到的一些控件要手动添加,函数根据.NET Reflector反编译出源代码加入到项目中.)

将新建项目编译成DLL

接着,用VS自带的ILDASM将原始DLL反编译成IL,用文本编辑器打开IL文件,用查找功能定位到
 "Select * from info where InfoId="
这一行
往下走来到函数结尾
 } // end of method Admin_FileEdit::Page_Load
往上走来到函数开头
 .method private instance void  Page_Load(object sender,
                                             class [mscorlib]System.EventArgs e) cil managed
中间部分就是要修改的代码了

再接着,用VS自带的ILDASM打开刚才生成的项目的DLL,打开IL的树形结构,找到改正后的函数,双击,可以打开一个详细的代码文件
将里面的所有代码复制到刚才打开的IL代码,替换IL文件中的原始函数
即下面的部分
 .method private instance void  Page_Load(object sender,
                                             class [mscorlib]System.EventArgs e) cil managed
  ...................................
  ...................................
  ...................................
 } // end of method Admin_FileEdit::Page_Load

重新编译修改过的IL,"ilasm filename.il /dll"  (filename指你开始用ILDASM导出的IL文件名)


将生成的DLL拷贝到BIN目录,覆盖旧的DLL

至此,修改工作告一段落

==================================
对IL部分的代码修改思路再做一点补充说明: 
此种方法办适用于函数内部代码的修改,如果要新增方法或者事件,还需要了解IL代码的组成结构,与其这样,还不如另建一个相同命名空间的DLL,将要增加的方法属性事件加进去,用VS编译成DLL供其他代码来调用. 
重点: 
1.确定代码哪一部分需要修改,问题出在什么地方,需要怎么改. 
2.如何改IL代码,为什么我没有直接在IL中改代码,而是另外新建项目? 
因为,在IL代码中,有这样的数据 
IL_0002: ldarg.2 
IL_0018: stloc.0 
IL_0019: ldloc.0 
IL_001a: ldarg.0 
(IL_....)标号并不代表行号,他还存储有一些其他的信息,代码改动以后,标号(IL_....)肯定会变动,如果对IL不熟,标号错乱会导致程序异常.(IL_....)标号在一个函数内部是相对独立的,所以我选择用编译器编译好的代码来填充整个函数. 
3.如何得到正确的IL代码? 
这个工作就交给VS去做了,利用VS的编译器编译正确的代码,通过ILDASM取出改正的IL代码. 
4.如何替换IL中不正确的代码? 
这个要利用VS带的ILDASM工具了,首先用ILDASM反编译新旧两个DLL,生成IL代码文件,在IL中找到这样的结构 
method private instance void Page_Load(object sender,class [mscorlib]System.EventArgs e) cil managed 
................................... 
} // end of method Admin_FileEdit::Page_Load 
直接用改好的代码替换旧代码保存. 
5.再用ILASM编译IL代码生成DLL就行了. 

=======================================

说白了,就是反汇编成IL代码,然后进行修改,再编译成DLL。 

不管怎么说,还是用Reflector反编译成C#、VB.NET等高级语言,然后直接修改代码,再编译成DLL,这样要来得更安全,更方便,更简单。

==============================
对于过大的项目,建议修改局部更安全。 
而且有的代码混淆过的,也只能修改 IL 代码。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值