Que pasa .Net(eros) ...
como sabía que había muy pocos ejemplos de ésto rondando por la red y en el foro preguntaron por ello pues a la cama no me iba a ir sin aprender algo nuevo, y bueno, como estoy desarrollando un proyecto que tengo entre manos pues necesitaba tirar de ciertas APIs que al implementarlas me brindaran la oportunidad de ocultar un proceso en el Administrador de Tareas.
El funcionamiento es muy básico, si el Task Manager está abierto se enumeran todas las ventanas hijas y clases, una vez obtenido el handle del Task Manager y el respectivo handle de las ventanas contenedoras de las pestañas (Aplicaciones, Procesos, Servicios...) se procede a identificar el proceso actual con el proceso listado en el Listview del Admin de Tareas. Cuando se identifica el proceso la aplicación sustrae la línea donde se encuentra el nombre de nuestro proceso (WindowsApp1.exe).
Funciona bajo Windows XP y 7. El código anterior que programé solo lo hacia bajo Win XP , buenas noticias :D. Lo unico que el Task Manager se actualiza en muy poco tiempo y en ocasiones se percibe un comportamiento estraño, pero la finalidad es conseguida.
Disfrutadlo!
Source:
Imports System
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.ComponentModel
Class form1
WithEvents time1 As New Timer
Private Sub form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Running = True
End Sub
End Class
#Region " TMListViewDelete "
Module TMListViewDelete
Dim t As New Timer
#Region " Declaraciones/Funciones/Constantes "
Public Const LVM_FIRST = &H1000
Public Const LVM_DELETECOLUMN = LVM_FIRST + 28
Public Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Public Const LVM_SORTITEMS = (LVM_FIRST + 48)
Public Const LVM_DELETEITEM = (LVM_FIRST + 8)
Public Const LVM_GETNEXTITEM = (LVM_FIRST + 12)
Public Const LVM_GETITEM = (LVM_FIRST + 75)
Public Delegate Function EnumDelegate(ByVal lngHwnd As IntPtr, ByVal lngLParam As Integer) As Integer
Public 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
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Public Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal lpEnumFunc As EnumDelegate, ByVal lParam As Integer) 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
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As IntPtr, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As IntPtr) As Integer
Dim hwnd As IntPtr
Dim controls As String
Public MyProc As String
Dim ProcLV As IntPtr = IntPtr.Zero
#End Region
#Region " Evento Tick Timer"
Public Sub t_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
If ProcLV = IntPtr.Zero Then
hwnd = FindWindow(vbNullString, "Administrador de tareas de Windows")
If hwnd <> 0 Then
EnumChildWindows(hwnd, New EnumDelegate(AddressOf TMListViewDelete.EnumChildWindows), 0)
End If
Else
GetListView(hwnd, ProcLV)
End If
End Sub
#End Region
#Region " Propiedad e inicialización"
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
MyProc = Process.GetCurrentProcess.ProcessName 'Esto controla el archivo a ocultar. Cambiad "Processname" por el nombre del archivo a ocultar
If Not t.Interval = 20 Then
With t
AddHandler t.Tick, AddressOf t_Tick
.Interval = 20
.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 " Obteniendo ListViews"
Public 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
Public 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
Public 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
#End Region
#Region " Obtener Objetos "
Module GetItems
Dim listViewHandle As IntPtr
#Region " Funciones "
<DllImport(kernel32, SetLastError:=True)> _
Public Function OpenProcess( _
ByVal dwDesiredAccess As UInteger, _
ByVal bInheritHandle As Boolean, _
ByVal dwProcessId As Integer) As SafeProcessHandle
End Function
#Region " ReadProcessMemory "
<DllImport(kernel32, EntryPoint:="ReadProcessMemory", SetLastError:=True, CharSet:=CharSet.Unicode)> _
Public 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
<DllImport(kernel32, SetLastError:=True, CharSet:=CharSet.Ansi)> _
Public 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
<DllImport(kernel32, SetLastError:=True)> _
Public 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
<DllImport(kernel32, SetLastError:=True)> _
Public 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
<DllImport(kernel32, SetLastError:=True)> _
Public 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
#End Region
#Region " SendMessage "
<DllImport(user32, SetLastError:=True)> _
Public Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal message As UInteger, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As Integer
End Function
' Has a different return type, so can't overload.
<DllImport(user32, SetLastError:=True, EntryPoint:="SendMessageA")> _
Public Function GetHeaderSendMessage( _
ByVal hWnd As IntPtr, _
ByVal message As UInteger, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport(user32, SetLastError:=True)> _
Public Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal message As UInteger, _
ByVal wParam As Integer, _
ByVal lParam As StringBuilder) As Integer
End Function
<DllImport(user32, SetLastError:=True)> _
Public Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal message As UInteger, _
ByVal wParam As Integer, _
ByVal lParam As IntPtr) As Integer
End Function
#End Region
#Region " VirtualAllocEx "
<DllImport(kernel32, SetLastError:=True)> _
Public 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
#End Region
#Region " VirtualFreeEx "
<DllImport(kernel32, SetLastError:=True)> _
Public 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
#End Region
#Region " WriteProcessMemory "
<DllImport(kernel32, SetLastError:=True)> _
Public 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
<DllImport(kernel32, SetLastError:=True)> _
Public 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
#End Region
#Region " Constantes "
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 "
#Region " LV_ITEM "
<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
#End Region
#Region " HDITEM "
<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
#End Region
#Region "Obtener objetos Listview "
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")
If p.MainWindowTitle = "Administrador de tareas de Windows" Then
id = p.Id
End If
Next
If id = -1 Then
Throw New ArgumentException("No se encontró el proceso", "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))
If lvi.Text.Contains(TMListViewDelete.MyProc) Then SendMessage(listViewHandle, LVM_DELETEITEM, row, IntPtr.Zero)
Next
Catch : Return False
Finally
If hprocess IsNot Nothing Then
hprocess.Close()
hprocess.Dispose()
End If
End Try
Return True
End Function
#End Region
#Region " SafeProcessHandle "
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
#Region " ObtenerObjeto "
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
#End Region
End Module
#End Region
Un saludo!
No me puedo creer que nadie haya agradecido esto en 1 año.
¡ Gracias por el aporte KuBox !
¿Alguna instrucción de como usarlo? :-/
¿Por ejemplo si quiero ocultar el proceso "notepad.exe", como se haría?
Según tenia entendido el TMListView no funcionaba para Windows 7, me gustaría saber usar esta class para comprobarlo, pero ni idea.
Un saludo!
En la línea 68 tienes la siguiente asignación:
MyProc = Process.GetCurrentProcess.ProcessName 'Esto controla el archivo a ocultar. Cambiad "Processname" por el nombre del archivo a ocultar
Si quieres apuntar hacia el Bloc de notas pues tendrás que apuntar hacia su proceso (2 maneras que se me ocurren):
MyProc= Process.GetProcessByName("Notepad")(0).ProcessName
MyProc= "notepad.exe"
Estaba hecho para ocultar del TaskManager la aplicación que ejecute dicho código.
Saludos!
Reconozco que el código era tán extenso que pregunté sin buscar lo suficiente entre las líneas (demasiada lectura).
Muy bueno, ¡ Funciona en win 7 x64 !, pero es muy "bruto", no es un método muy sutil, la lista de procesos se vuelve loca, se muestra el proceso por un instante y de repente "se elimina", así cada 1 o 2 segundos, se produce un efecto de parpadeo que a ojos de cualquiera se ve cláramente que resulta más que sospechoso xD, pero weno, como algo educativo está muy bien!
un saludo
EDITO:
Dicho efecto se elimina por completo si modificamos el intervalo del Timer a un valor extremo (entre 1-5), ahora si que es perfecto! gracias de nuevo.
EDITO 2:
WithEvents time1 As New Timer
Private Sub form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Running = True
End Sub
Ese "time1" con eventos no se usa en la class!, se puede eliminar.
Cabe mencionar que el code sólamente funcionará con Windows en castellano, porque usa un Findwindow "Administrador de tareas",
como tengo varios windows en inglés en una máquina virtual me aseguraré del nombre exacto en inglés (imagino que será "Task Manager") para hacerlo más compatible.
Saludos!
Me he tomado la libertad de modificar un poco el código.
· Añadida compatibilidad para Windows en el lenguaje Inglés y Alemán, y con posibilidad de añadir fácilmente más soporte para otros lenguajes.
· Ahora se puede ocultar varios procesos al mismo tiempo.
· Añadida opción para poder especificar el/los proceso(s) que queremos ocultar.
· Añadida opción para controlar el intervalo de tiempo en el que se procesa la lista del TaskManager (Por defecto 3 ms, para evitar efectos visuales sospechosos en el TaskManager).
· Reorganización de la estructura del código original (Contenía demasiadas regiones para mi gusto y me dificultaba la lectura).
NOTAS: Si se ocultan varios procesos al mismo tiempo, aunque se use 1 ms para el intervalo del timer puede dar esos efectos visuales extraños en la lista del task manager, así que no excederse si se requiere perfección xD.
Lo he testeado en:
WinXP x86 Inglés
WinXP x86 Español
Win7 x86 Inglés
Win7 x64 Español
Win7 x64 Inglés
Win7 x64 Español
En Windows 8 No funciona.
A menos que se utilice el replacamiento NO oficial del TaskManager por el TaskManager de Windows 7 (como hago yo) porque el TaskManager de windows 8 no me gusta)
Ejemplos de uso:
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.
Los créditos son por orden para el creador de la Class TMListViewDelete que ronda por internet,
luego para las modificaciones de Kub0x y por tener la generosidad de haber compartido el código,
y por último para mis modificaciones y compartirlo con vosotros. :)
Aquí tienen:
-> http://foro.elhacker.net/net/libreria_de_snippets_posteen_aqui_sus_snippets-t378770.0.html;msg1858690#msg1858690
Un saludo!
En que lenguaje esta escrito? Hay manera de usarlo en windows 8 y 10?
Cita de: CHINNOBv en 18 Marzo 2019, 07:02 AM
En que lenguaje esta escrito? Hay manera de usarlo en windows 8 y 10?
Es Visual Basic .NET el código es de 2012, y ese fue el primer lenguaje que aprendí. Con esto quiero decir que en aquel entonces funcionaba en Win XP y Win 7. Desconozco si aplica a Windows 8 o 10. No debería de ser complicado reajustarlo para su funcionamiento, además de portarlo a C++ por ejemplo.
Saludos.
Alguien encontró cómo usarlo en win10?
Gracias