none
如何用VB 2010 实现控制用户运行程序? RRS feed

  • 问题

  • 我想用VB2010写一个程序来控制小孩子使用电脑,比如说只让在本机上运行“金山打字通”,首先程序将“金山打字通”MD5值写入一个特定的数据库文件中,如果用户运行了“金山打字通”那么监控程序刚自动将运行的“金山打字通”程序文件的MD5值与数据库中的值进行对比,一样则运行,不一样则拒绝,以达到小孩子想通过修改其它程序名称为“金山打字通”来运行的目的!
    现在问题的关键就是,我的程序要如何截获用户要运行的程序来进行MD5值判断?这原理就有点像杀毒软件截获木马运行一样,要怎么做?
    望高手赐教呀!

    2011年2月18日 12:34

答案

  • Hi 鱼,

    建一个控制台工程,看代码:

    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Public Class ProcessFile
      <DllImport("psapi.dll")> _
      Public Shared Function GetModuleFileNameEx(ByVal hProcess As IntPtr, ByVal hModule As IntPtr, <Out()> ByVal lpBaseName As StringBuilder, <[In]()> <MarshalAs(UnmanagedType.U4)> ByVal nSize As Integer) As UInteger
      End Function
      Public Shared Function MD5OfFile(ByVal FileName As String) As String
        '文件较占资源,使用using关键字,使得其用完后及时释放
        Using reader As New System.IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read)
          Using md5 As New System.Security.Cryptography.MD5CryptoServiceProvider
            Dim hash() As Byte = md5.ComputeHash(reader)
            Return ByteArrayToString(hash)
          End Using
        End Using
      End Function
    
      Private Shared Function ByteArrayToString(ByVal arrInput() As Byte) As String
    
        Dim sb As New System.Text.StringBuilder(arrInput.Length * 2)
        For i As Integer = 0 To arrInput.Length - 1
          '转换为十六进制
          sb.Append(arrInput(i).ToString("X2"))
        Next
        Return sb.ToString().ToLower
    
      End Function
    End Class
    
    Module Module1
      Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
      Private Const PROCESS_QUERY_INFORMATION = &H400
      Const MAX_PATH As Integer = 260
    
      Sub Main()
        For Each proc As Process In Process.GetProcessesByName("金山打字通")
          Dim buf As New StringBuilder(MAX_PATH)
          Dim filename As String
          ProcessFile.GetModuleFileNameEx(proc.Handle, IntPtr.Zero, buf, MAX_PATH)
          Console.WriteLine(buf.ToString)
          filename = buf.ToString
          Console.WriteLine(ProcessFile.MD5OfFile(filename))
          '比较MD5值
          If ProcessFile.MD5OfFile(filename) <> "预设的MD5值" Then
            '关闭进程
            proc.CloseMainWindow()
            '释放资源
            proc.Close()
          End If
        Next
        'Console.ReadKey()
      End Sub
    
    End Module
    
    Best regards,
    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年2月21日 8:27
    版主

全部回复

  • Hi 鱼,

    建一个控制台工程,看代码:

    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Public Class ProcessFile
      <DllImport("psapi.dll")> _
      Public Shared Function GetModuleFileNameEx(ByVal hProcess As IntPtr, ByVal hModule As IntPtr, <Out()> ByVal lpBaseName As StringBuilder, <[In]()> <MarshalAs(UnmanagedType.U4)> ByVal nSize As Integer) As UInteger
      End Function
      Public Shared Function MD5OfFile(ByVal FileName As String) As String
        '文件较占资源,使用using关键字,使得其用完后及时释放
        Using reader As New System.IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read)
          Using md5 As New System.Security.Cryptography.MD5CryptoServiceProvider
            Dim hash() As Byte = md5.ComputeHash(reader)
            Return ByteArrayToString(hash)
          End Using
        End Using
      End Function
    
      Private Shared Function ByteArrayToString(ByVal arrInput() As Byte) As String
    
        Dim sb As New System.Text.StringBuilder(arrInput.Length * 2)
        For i As Integer = 0 To arrInput.Length - 1
          '转换为十六进制
          sb.Append(arrInput(i).ToString("X2"))
        Next
        Return sb.ToString().ToLower
    
      End Function
    End Class
    
    Module Module1
      Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
      Private Const PROCESS_QUERY_INFORMATION = &H400
      Const MAX_PATH As Integer = 260
    
      Sub Main()
        For Each proc As Process In Process.GetProcessesByName("金山打字通")
          Dim buf As New StringBuilder(MAX_PATH)
          Dim filename As String
          ProcessFile.GetModuleFileNameEx(proc.Handle, IntPtr.Zero, buf, MAX_PATH)
          Console.WriteLine(buf.ToString)
          filename = buf.ToString
          Console.WriteLine(ProcessFile.MD5OfFile(filename))
          '比较MD5值
          If ProcessFile.MD5OfFile(filename) <> "预设的MD5值" Then
            '关闭进程
            proc.CloseMainWindow()
            '释放资源
            proc.Close()
          End If
        Next
        'Console.ReadKey()
      End Sub
    
    End Module
    
    Best regards,
    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年2月21日 8:27
    版主
  • Hi 鱼,

    我把自己的回复mark了,要是你觉得没什么用,请unmark 。

    Best regards,


    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年2月28日 3:50
    版主