能力值:
( LV15,RANK:3306 )
|
-
-
2 楼
先用ZwQueryInformationProcess获取指定进程的PEB, 再从PEB中读取StartupInfo参数(可以参考GetStartupInfo)
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
这个过程有点曲折吧,简单点说,能拿到StartInfo中的lpDesktop就行了
|
能力值:
( LV15,RANK:3306 )
|
-
-
4 楼
自己mark下, 不知道有什么更简单的方法
#include <windows.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szCmd[MAX_PATH] = TEXT("c:\\windows\\notepad.exe");
TCHAR szDesktop[MAX_PATH] = TEXT("TEST1234567");
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
// desktop must be created before CreateProcess under win7
CreateDesktop(szDesktop, NULL, NULL, 0, GENERIC_ALL, NULL);
si.cb = sizeof(si);
si.lpDesktop = szDesktop;
CreateProcess(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
// wait until resources needed by child process being loaded
WaitForSingleObject(pi.hProcess, 3000);
return 0;
}
#include <windows.h>
#include <stdio.h>
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define NT_SUCCESS(status) ((NTSTATUS)(status) == 0)
typedef LONG NTSTATUS;
typedef ULONG ACCESS_MASK;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemHandleInformation = 16,
} SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectNameInformation = 1,
ObjectTypeInformation = 2,
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
typedef NTSTATUS (WINAPI *ZWQUERYSYSTEMINFORMATION)(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
typedef NTSTATUS (WINAPI *NTQUERYOBJECT)(
HANDLE Handle,
OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength
);
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
WCHAR NameBuffer[1];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
typedef enum _POOL_TYPE {
NonPagedPool = 0,
} POOL_TYPE;
typedef struct _OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
ULONG TotalNumberOfHandles;
ULONG TotalNumberOfObjects;
WCHAR Unused1[8];
ULONG HighWaterNumberOfHandles;
ULONG HighWaterNumberOfObjects;
WCHAR Unused2[8];
ACCESS_MASK InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ACCESS_MASK ValidAttributes;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
USHORT MaintainTypeList;
POOL_TYPE PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
BOOL EnablePriv(LPCTSTR lpName)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
if(!::OpenProcessToken(::GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
return FALSE;
}
if(!LookupPrivilegeValue(NULL, lpName, &luid))
{
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
if(!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
return FALSE;
}
return TRUE;
}
BOOL EnumProcessHandle(DWORD ProcessId)
{
BOOL bRet = FALSE;
HMODULE hNtDll = NULL;
ZWQUERYSYSTEMINFORMATION pfnZwQuerySystemInformation = NULL;
NTQUERYOBJECT pfnNtQueryObject = NULL;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = NULL;
POBJECT_NAME_INFORMATION pNameInfo = NULL;
POBJECT_TYPE_INFORMATION pTypeInfo = NULL;
ULONG nHandleCount = 0;
NTSTATUS ntStatus = 0;
ULONG ulSize;
ULONG ulBufSize;
char *cBuffer = NULL;
char cInfoBuffer[0x10000];
char cTypeBuffer[0x10000];
do
{
hNtDll = GetModuleHandle(TEXT("ntdll.dll"));
if (hNtDll == NULL)
{
break;
}
pfnZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,"ZwQuerySystemInformation");
pfnNtQueryObject = (NTQUERYOBJECT)GetProcAddress(hNtDll,"NtQueryObject");
if (pfnZwQuerySystemInformation == NULL)
{
break;
}
if (pfnNtQueryObject == NULL)
{
break;
}
ulBufSize = 0x80000;
ntStatus = STATUS_INFO_LENGTH_MISMATCH;
while (true)
{
cBuffer = (char *)calloc(1, ulBufSize);
if (cBuffer == NULL)
{
break;
}
ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation, cBuffer, ulBufSize, &ulSize);
if (NT_SUCCESS(ntStatus))
{
break;
}
if (ntStatus != STATUS_INFO_LENGTH_MISMATCH)
{
break;
}
free(cBuffer);
cBuffer = NULL;
ulBufSize *= 2;
}
if (!NT_SUCCESS(ntStatus))
{
break;
}
nHandleCount = *(PULONG)cBuffer;
pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)(cBuffer + 4);
for(ULONG i = 0; i < nHandleCount; ++i)
{
if(pSysHandleInfo[i].ProcessId != ProcessId)
{
continue;
}
HANDLE hTargetProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId());
HANDLE hTargetHandle = NULL;
HANDLE hSourceProcess = OpenProcess(PROCESS_VM_READ | PROCESS_DUP_HANDLE, FALSE, ProcessId);
HANDLE hSourceHandle = (HANDLE)pSysHandleInfo[i].Handle;
if (hSourceProcess == NULL)
{
continue;
}
if (!DuplicateHandle(
hSourceProcess,
hSourceHandle,
hTargetProcess,
&hTargetHandle,
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
FALSE,
0))
{
continue;
}
ntStatus = pfnNtQueryObject(hTargetHandle, ObjectNameInformation, cInfoBuffer, 0x10000, &ulSize);
if (!NT_SUCCESS(ntStatus))
{
continue;
}
pNameInfo = (POBJECT_NAME_INFORMATION)cInfoBuffer;
ntStatus = pfnNtQueryObject(hTargetHandle, ObjectTypeInformation, cTypeBuffer, 0x10000, &ulSize);
if (!NT_SUCCESS(ntStatus))
{
continue;
}
pTypeInfo = (POBJECT_TYPE_INFORMATION)cTypeBuffer;
//wprintf(L"handle: %08X, type: %s, name: %s\n", hSourceHandle, pTypeInfo->TypeName.Buffer, pNameInfo->NameBuffer);
if (wcscmp(pTypeInfo->TypeName.Buffer, L"Desktop") == 0)
{
wprintf(L"name: %s\n", pNameInfo->NameBuffer + 1);
}
}
bRet = TRUE;
} while (0);
return bRet;
}
void main( )
{
DWORD dwProcessId = 8800;
do
{
if (!EnablePriv(SE_DEBUG_NAME))
{
break;
}
if (!EnumProcessHandle(dwProcessId))
{
break;
}
} while (0);
}
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
我测试了单个进程ID,程序能正常使用,但是我尝试如下方法,程序会莫名卡死
HANDLE hProSnap;
HANDLE handle;
hProSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 Pe;
Pe.dwSize=sizeof(PROCESSENTRY32);
BOOL return_value;
return_value = Process32First(hProSnap,&Pe);
while(return_value)
{
if(EnumProcessHandle(Pe.th32ProcessID))
{
handle=OpenProcess(PROCESS_TERMINATE,TRUE,Pe.th32ProcessID);
if (handle!=NULL)
TerminateProcess(handle,0);
}
return_value = Process32Next(hProSnap,&Pe);
}
CloseHandle(hProSnap);
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
菜鸟进来学习,C#写多了,C不怎么写了,完全忘记了
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
我已经找到解决方法了,通过进行线程快照找到对应进程ID的主线程,使用GetThreadDesktop可以取得桌面句柄,然后使用GetUserObjectInformation()参数指定为UIO_NAME即可获得桌面名称,可能我之前问题没有描述清楚,谢谢风间仁童鞋的耐心回答,表示学习了。也谢谢陈心童鞋的关注,结贴
|
能力值:
( LV15,RANK:3306 )
|
-
-
8 楼
问下LZ, GetThreadDesktop可以返回进程X(假设Desktop为TEST1234)的的桌面句柄吗(假设查询进程的Desktop为Default),
我之前测试的情况是在没有OpenDesktop(TEST1234)的情况下, GetThreadDesktop总是会失败的
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
通过进程X的ID,然后快照线程查找与该进程相关的线程,再通过GetTreadDesktop(线程ID)取得桌面句柄,MSDN上描述GetThreadDesktop的参数可以是CreateProcess的返回的值,但事实上直接调用会提示参数错误。通过线程ID可以正常取得
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
if( Thread32First( hThreadSnap, &te32) )
{
do{
if( dwProcessID == te32.th32OwnerProcessID )
{
dwThreadID = te32.th32ThreadID;
hTempDesktop = GetThreadDesktop(dwThreadID);
char name[100];
DWORD dwLengthNeed;
if(GetUserObjectInformationA(hTempDesktop, UOI_NAME, name, 1024, &dwLengthNeed))
{
DWORD errocode = GetLastError();
if (0 == lstrcmpA(name,pszDesktopName))
{
handle=OpenProcess(PROCESS_TERMINATE,TRUE,dwProcessID);
if (handle!=NULL)
if(TerminateProcess(handle,0))
return TRUE;
}
}
}
}while( Thread32Next( hThreadSnap, &te32) );
|
能力值:
( LV15,RANK:3306 )
|
-
-
10 楼
thx, 了解了
LZ这段代码, 看来是已知desktop name了,
在这段代码执行之前想必已经OpenDesktop或者CreateDesktop了, 不然GetThreadDesktop也会失败的.
我这前的想法都是基于不知道desktop name的情况..
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
Desktop name是未知的,我是遍历了所有进程,然后查找所有进程的线程,GetThreadDesktop传线程的ID是没有问题,能正确返回
|