从 Windows 8 TaskManager 隐藏进程

Posted

技术标签:

【中文标题】从 Windows 8 TaskManager 隐藏进程【英文标题】:Hide a process from Windows 8 TaskManager 【发布时间】:2013-06-08 17:32:32 【问题描述】:

我想在 Windows 8 TaskManager 中隐藏一个进程。

前段时间我发现了一个名为“TMListViewDelete”的类,它在互联网上有点出名(和地下),有人在该类中进行了必要的修改以使用 Windows Vista/7 TaskManager,几天前我做了所有必要的修改,将 Class 变成了几个带有一些选项的通用函数。

...但是即使修改了很多代码我也无法 100% 理解代码,我知道它会从 Taskmanager 进程中读取类名,然后删除一个项目(一行),我可以注意到这是不是向任务管理器隐藏进程的最佳方法,但这就是我所拥有的。

我需要实现/扩展功能以使用 Windows 8 x86/x64 TaskManager,但就像我说过的那样,即使我找到了 win8 任务管理器的类名,我也不知道如何添加该功能或者在哪里写代码。

这是班级:

#Region " Hide Process From TaskManager "

' [ Hide Process From TaskManager ]
'
' // By Elektro H@cker
'
' Examples :
'
' Hide_Process_From_TaskManager.Processes_Names = Process.GetCurrentProcess.ProcessName, "cmd", "notepad.exe" ' Processes to hide.
' Hide_Process_From_TaskManager.Task_Manager_Window_Titles = "Administrador de tareas de Windows", "Windows Task Manager" ' Support for unknown TaskManager Window Titles.
' Hide_Process_From_TaskManager.Hide_Interval = 3 ' Hidding Interval.
' Hide_Process_From_TaskManager.Running = True ' Start hidding processes.
' Hide_Process_From_TaskManager.Running = False ' Stop hidding processes.

#Region " Hide Process From TaskManager Class "

Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.ComponentModel

Module Hide_Process_From_TaskManager

#Region " API's "

    Private Delegate Function EnumDelegate(ByVal lngHwnd As IntPtr, ByVal lngLParam As Integer) As Integer
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal Hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Private Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal lpEnumFunc As EnumDelegate, ByVal lParam As Integer) As Integer
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As IntPtr, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As IntPtr) As Integer
    Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer

    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Private Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer)
    End Sub

#End Region

#Region " Variables "

    ''' <summary>
    ''' The processses to hide from TaskManager.
    ''' Caution: The process name is Case-Sensitive.
    ''' </summary>
    Public Processes_Names() As String = Process.GetCurrentProcess.ProcessName ' The current process.

    ''' <summary>
    ''' The interval time in ms to hide the process from TaskManager.
    ''' Values greater than "5" can cause bad visual effects in TaskManager processes list.
    ''' </summary>
    Public Hide_Interval As Int32 = 3 ' ms

    ''' <summary>
    ''' The known Window Titles for Task Manager process.
    ''' This is necessary to work properly in all languages.
    ''' Add here your own Task Manager Window Tittle if is not inside.
    ''' Default support: Spanish, English, Deutsch
    ''' </summary>
    Public Task_Manager_Window_Titles() As String =  _
        "Administrador de tareas de Windows", _
        "Windows Task Manager", _
        "Windows Task-Manager", _
    

    ''' <summary>
    ''' Gets the next process in the Processes_Names array to hide it.
    ''' Don't touch this.
    ''' </summary>
    Public MyProc As String

    Dim t As New Timer
    Dim hwnd As IntPtr
    Dim controls As String
    Dim ProcLV As IntPtr = IntPtr.Zero

    Private Const LVM_FIRST = &H1000
    Private Const LVM_DELETECOLUMN = LVM_FIRST + 28
    Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
    Private Const LVM_SORTITEMS = (LVM_FIRST + 48)
    Private Const LVM_DELETEITEM = (LVM_FIRST + 8)
    Private Const LVM_GETNEXTITEM = (LVM_FIRST + 12)
    Private Const LVM_GETITEM = (LVM_FIRST + 75)

#End Region

#Region " Properties "

    ''' <summary>
    ''' Turns ON/OFF the process hiding.
    ''' </summary>
    Public Property Running() As Boolean
        Get
            If t.Enabled = True Then
                Return True
            Else
                Return False
            End If
        End Get
        Set(ByVal value As Boolean)
            If value = True Then

                If Processes_Names.Length = 0 Then Throw New Exception("Processes_Names Array is empty.")
                If Hide_Interval <= 0 Then Throw New Exception("Hide_Interval value is too low, minimum value: 1")

                MyProc = Processes_Names(0)
                If Not t.Interval = Hide_Interval Then
                    With t
                        AddHandler t.Tick, AddressOf t_Tick
                        .Interval = Hide_Interval
                        .Enabled = True
                        .Start()
                    End With
                Else
                    t.Enabled = True
                    t.Start()
                End If
            Else
                t.Enabled = False
                t.Stop()
                ProcLV = IntPtr.Zero
            End If
        End Set
    End Property

#End Region

#Region " Timer Tick event "

    Private Sub t_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If ProcLV = IntPtr.Zero Then

            For Each Title In Task_Manager_Window_Titles
                hwnd = FindWindow(vbNullString, Title)
                If hwnd <> 0 Then
                    EnumChildWindows(hwnd, New EnumDelegate(AddressOf Hide_Process_From_TaskManager.EnumChildWindows), 0)
                End If
            Next

        Else
            GetListView(hwnd, ProcLV)
        End If
    End Sub

#End Region

#Region " Functions "

    ' EnumChildWindows
    Private Function EnumChildWindows(ByVal lngHwnd As IntPtr, ByVal lngLParam As Integer) As Integer
        Dim strClassName As String = ObtenerClase(lngHwnd)
        Dim strText As String = ObtenerTextoVentana(lngHwnd)
        If InStr(strClassName, "SysListView32") Then
            GetListView(hwnd, lngHwnd)
            If InStr(strText, "Procesos") Then
                ProcLV = lngHwnd
            End If
        End If
        Dim Classes As String = lngHwnd.ToString & ", " & strClassName & ", " & strText
        Return 1
    End Function

    ' ObtenerClase
    Private Function ObtenerClase(ByVal handle As IntPtr) As String
        Dim strClassName As New System.Text.StringBuilder()
        strClassName.Length = 255
        GetClassName(handle, strClassName, strClassName.Length)
        Return strClassName.ToString
    End Function

    ' ObtenerTextoVentana
    Private Function ObtenerTextoVentana(ByVal handle As IntPtr) As String
        Dim titleText As New System.Text.StringBuilder()
        titleText.Length = GetWindowTextLength(handle) + 1
        GetWindowText(handle, titleText, titleText.Length)
        Return titleText.ToString
    End Function

#End Region

End Module

Module GetItems

#Region " API's "

    ' OpenProcess
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As SafeProcessHandle
    End Function

    ' ReadProcessMemoryW
    <DllImport(kernel32, EntryPoint:="ReadProcessMemory", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Function ReadProcessMemoryW(ByVal hProcess As SafeProcessHandle, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ' ReadProcessMemory
    <DllImport(kernel32, SetLastError:=True, CharSet:=CharSet.Ansi)> _
    Private Function ReadProcessMemory(ByVal hProcess As SafeProcessHandle, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ' ReadProcessMemory
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function ReadProcessMemory(ByVal hProcess As SafeProcessHandle, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEM, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ' ReadProcessMemory
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function ReadProcessMemory(ByVal hProcess As SafeProcessHandle, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As HDITEM, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ' ReadProcessMemory
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function ReadProcessMemory(ByVal hProcess As SafeProcessHandle, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ' SendMessage
    <DllImport(user32, SetLastError:=True)> _
    Private Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function

    ' GetHeaderSendMessage
    <DllImport(user32, SetLastError:=True, EntryPoint:="SendMessageA")> _
    Private Function GetHeaderSendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    End Function

    ' SendMessage
    <DllImport(user32, SetLastError:=True)> _
    Private Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer
    End Function

    ' SendMessage
    <DllImport(user32, SetLastError:=True)> _
    Private Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
    End Function

    ' VirtualAllocEx
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function VirtualAllocEx(ByVal hProcess As SafeProcessHandle, ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
    End Function

    ' VirtualFreeEx
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function VirtualFreeEx(ByVal hProcess As SafeProcessHandle, ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal dwFreeType As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ' WriteProcessMemory
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function WriteProcessMemory(ByVal hProcess As SafeProcessHandle, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEM, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ' WriteProcessMemory
    <DllImport(kernel32, SetLastError:=True)> _
    Private Function WriteProcessMemory(ByVal hProcess As SafeProcessHandle, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As HDITEM, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

#End Region

#Region " Variables "

    Dim listViewHandle As IntPtr

    Public Const LVM_FIRST As UInteger = &H1000
    Public Const LVM_DELETEITEM As UInteger = (LVM_FIRST + 8)
    Public Const kernel32 As String = "kernel32"
    Public Const user32 As String = "user32"
    Public Const LVM_GETITEMCOUNT As UInteger = &H1004
    Public Const LVM_GETITEMTEXT As UInteger = &H102D
    Public Const LVM_GETHEADER As UInteger = &H101F
    Public Const HDM_GETIEMA As UInteger = &H1203
    Public Const HDM_GETITEMW As UInteger = &H120B
    Public Const HDM_GETITEMCOUNT As UInteger = &H1200
    Public Const HDM_GETUNICODEFORMAT As UInteger = &H2006
    Public Const HDI_TEXT As UInteger = 2
    Public Const MEM_COMMIT As UInteger = &H1000
    Public Const MEM_RELEASE As UInteger = &H8000
    Public Const PAGE_READWRITE As UInteger = 4
    Public Const PROCESS_VM_READ As UInteger = &H10
    Public Const PROCESS_VM_WRITE As UInteger = &H20
    Public Const PROCESS_VM_OPERATION As UInteger = &H8
    Public Const WM_GETTEXT As UInteger = &HD
    Public Const WM_GETTEXTLENGTH As UInteger = &HE

#End Region

#Region " Structures "

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure LV_ITEM
        Public mask As UInteger
        Public iItem As Integer
        Public iSubItem As Integer
        Public state As UInteger
        Public stateMask As UInteger
        Public pszText As IntPtr
        Public cchTextMax As Integer
        Public iImage As Integer
        Public lParam As IntPtr
        Public iIndent As Integer
        Public iGroupId As Integer
        Public cColumns As Integer
        Public puColumns As IntPtr
        Public piColFmt As IntPtr
        Public iGroup As Integer
        Public Function Size() As Integer
            Return Marshal.SizeOf(Me)
        End Function
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure HDITEM
        Public mask As UInteger
        Public cxy As Integer
        Public pszText As IntPtr
        Public hbm As IntPtr
        Public cchTextMax As Integer
        Public fmt As Integer
        Public lParam As IntPtr
        Public iImage As Integer
        Public iOrder As Integer
        Public Function Size() As Integer
            Return Marshal.SizeOf(Me)
        End Function
    End Structure

#End Region

#Region " Functions "

    Public Function GetListView(ByVal handle As IntPtr, ByVal lvhandle As IntPtr) As Boolean
        listViewHandle = lvhandle
        Dim hParent As IntPtr = handle

        Dim id As Integer = -1
        Try
            For Each p In Process.GetProcessesByName("taskmgr")
                id = p.Id
            Next
            If id = -1 Then
                Throw New ArgumentException("Can't find process", "processName")
            End If
        Catch : Return False : End Try

        Dim hprocess As SafeProcessHandle = Nothing
        Try
            hprocess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, id)

            If hprocess Is Nothing Then
                If Marshal.GetLastWin32Error = 0 Then
                    Throw New System.ComponentModel.Win32Exception
                End If
            End If

            Dim itemCount As Integer = SendMessage(listViewHandle, LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero)

            For row As Integer = 0 To itemCount - 1

                Dim lvi As New ListViewItem(GetItem(row, 0, hprocess))

                For Each processname In Processes_Names
                    MyProc = processname
                    If lvi.Text.Contains(Hide_Process_From_TaskManager.MyProc) Then SendMessage(listViewHandle, LVM_DELETEITEM, row, IntPtr.Zero)
                Next

            Next
        Catch : Return False
        Finally
            If hprocess IsNot Nothing Then
                hprocess.Close()
                hprocess.Dispose()
            End If

        End Try
        Return True
    End Function

    Public Function GetItem(ByVal row As Integer, ByVal subitem As Integer, _
                                ByVal hProcess As SafeProcessHandle) As String

        Dim lvitem As New LV_ITEM
        lvitem.cchTextMax = 260
        lvitem.mask = 1
        lvitem.iItem = row
        lvitem.iSubItem = subitem
        Dim pString As IntPtr
        Dim s As New StringBuilder(260)

        Try

            pString = VirtualAllocEx(hProcess, IntPtr.Zero, 260, MEM_COMMIT, PAGE_READWRITE)
            lvitem.pszText = pString
            Dim pLvItem As IntPtr
            Try
                pLvItem = VirtualAllocEx(hProcess, IntPtr.Zero, lvitem.Size, MEM_COMMIT, PAGE_READWRITE)
                Dim boolResult As Boolean = WriteProcessMemory(hProcess, pLvItem, lvitem, lvitem.Size, 0)
                If boolResult = False Then Throw New Win32Exception

                SendMessage(listViewHandle, LVM_GETITEMTEXT, row, pLvItem)
                boolResult = ReadProcessMemory(hProcess, pString, s, 260, 0)
                If boolResult = False Then Throw New Win32Exception
                boolResult = ReadProcessMemory(hProcess, pLvItem, lvitem, Marshal.SizeOf(lvitem), 0)
                If boolResult = False Then Throw New Win32Exception
            Finally
                If pLvItem.Equals(IntPtr.Zero) = False Then
                    Dim freeResult As Boolean = VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE)
                    If freeResult = False Then Throw New Win32Exception
                End If
            End Try
        Finally
            If pString.Equals(IntPtr.Zero) = False Then
                Dim freeResult As Boolean = VirtualFreeEx(hProcess, pString, 0, MEM_RELEASE)
                If freeResult = False Then Throw New Win32Exception
            End If
        End Try

        Return s.ToString

    End Function

    Friend NotInheritable Class SafeProcessHandle : Inherits SafeHandleZeroOrMinusOneIsInvalid

        Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal hObject As IntPtr) As Boolean

        Public Sub New()
            MyBase.New(True)
        End Sub

        Public Sub New(ByVal handle As IntPtr)
            MyBase.New(True)
            MyBase.SetHandle(handle)
        End Sub

        Protected Overrides Function ReleaseHandle() As Boolean
            Return CloseHandle(MyBase.handle)
        End Function

    End Class

#End Region

End Module

#End Region

#End Region

【问题讨论】:

我当然希望你找不到这个问题的答案。我想不出这段代码有什么合法用途。 @zmbq 也许是教育学习以某种方式欺骗操作系统的事实,以及学习使用不常见的各种 API 功能的事实。 也许,尽管您可以通过在 Windows 资源管理器中为某些文件添加笑脸来学习相同的技巧。 Windows 8 中的任务管理器从头开始完全重写。早期版本的 Windows 中的任何技术都将完全无效。你将不得不重新开始。不清楚你的问题是什么。这听起来像是“有人可以为我编写这个程序吗?”这不是 SO 的意义所在。 @zmbq:线索就在他的昵称中:D 【参考方案1】:

不应该,因为这不是任务管理器的重点。应该使用任务管理器来允许用户检查进程。其他诸如组策略之类的东西可以阻止用户查看任务管理器,但肯定不会对任务管理器本身隐藏进程。

一个和你类似的问题:http://www.codeproject.com/Questions/218183/Csharp-hide-a-apllication-process-from-taskmanager

【讨论】:

请您仔细阅读我的问题,尤其是代码,可以将进程隐藏在 TaskManager 列表中,因为 TaskManager 是一个已编译的 exe,托管代码,如此简单获取存储进程列表视图的类的名称,然后删除该进程的行,这就是我的问题的代码。我只需要知道 Windows 8 的 Taskmanager 的类的名称(因为有不同的名称),以及如何调整我的代码以在 Windows 8 中使用修改后的类。 这也是一个 VB.NET 问题,但 2011 年的任何 C#/VB 代码都可以帮助我,因为那年 Windos 8 尚未发布,那么在 2011 年没有人知道如何管理 TMListViewDelete Windows 8 的 TaskManager 类。但是谢谢。【参考方案2】:

您需要使用 rootkit 技术。 阅读:

http://www.amazon.com/Managed-Code-Rootkits-Hooking-Environments/dp/1597495743 http://www.amazon.com/Rootkits-Subverting-Windows-Greg-Hoglund/dp/0321294319 http://www.amazon.com/books/dp/1598220616

【讨论】:

以上是关于从 Windows 8 TaskManager 隐藏进程的主要内容,如果未能解决你的问题,请参考以下文章

使用 TaskManager 查找在 Windows 上运行的 python 进程

C# 如何正确设置 Windows 8 任务管理器的程序集标题?

Flink 源码解析 —— Flink TaskManager 有什么作用?

如何在 TaskManager 中更改 C# WinForms exe 的图标

HMM(隐马尔可夫模型)

FLinkFlink 1.12 TaskManager 内存结构