老生常谈---通过PID获取用户名的方法。我先写一个。

oldmtn 2011-04-29 04:53:58
#include <windows.h>

#include <iostream>
using namespace std;

#include "WtsApi32.h"
#pragma comment(lib,"WtsApi32.lib")

#pragma comment(lib,"Advapi32.lib")

int main()
{
DWORD dwProcessId = 980;

TCHAR userName[MAX_PATH];

SID_NAME_USE snu;
TCHAR buffUsername[MAX_PATH];
TCHAR buffDomainname[MAX_PATH];
DWORD unSize;
DWORD dnSize;

WTS_PROCESS_INFO* ppi;
WTS_PROCESS_INFO* tp;
DWORD ppin;

//返回特定服务上的活动进程
if(::WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &ppi, &ppin))
{
tp = ppi;
for(DWORD i=0; i < ppin; i++)
{
unSize = sizeof(buffUsername);
dnSize = sizeof(buffDomainname);
if(tp->ProcessId == dwProcessId)
{ //获取特定SID对应的domain
if(LookupAccountSid(NULL, tp->pUserSid, buffUsername, &unSize, buffDomainname, &dnSize, &snu))
{
lstrcpy(userName, buffUsername);
}
break;
}
tp++;
}
::WTSFreeMemory(ppi);
}

wcout << userName << endl;
return 0;
}

上面是我的代码,不过个人感觉效率底下。每获取一次就需要做一次循环。
目前据说可以通过一个未公开API----GetSiteSidFromToken来实现,该API在advapi32.dll里面,需要动态导入。
我试了很多次就是获取不到,不哪位获取了,可否把代码发到我邮箱里面。
793954747@qq.com
...全文
1095 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
yayexing 2013-11-22
  • 打赏
  • 举报
回复 1
8楼的方法可以 11楼的方法只能获取到Administrator,SYSTEM用户名
tongzhipeng5699 2013-01-25
  • 打赏
  • 举报
回复
7楼的方法是不是更简单一点, 不用谢那么多代码, 8楼的方法也可以, 但是代码比较多, 有什么明显的优势吗? 比如操作系统, 权限等等, 我试的是非administrator账户都可以获取所有其他账户(包括SYSTEM等)的进程, PID 为0 和 4 的 System Idle Process 和 System进程两种方法都获取失败。 我的是WIN7 系统, 看了先关API的MSDN, 应该都是支持XP 系统的。 楼主5楼的代码有些错误, 我查了MSDN修改下就好了。

#include "stdafx.h"
#include "stdio.h"
#include "tchar.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[]) { 

	DWORD dwProcessId = 348;
	HANDLE hProcess2 = OpenProcess(PROCESS_QUERY_INFORMATION , FALSE, dwProcessId);
	HANDLE hToken;
	if (NULL != hProcess2)
	{
		BOOL bTokenOK = OpenProcessToken(hProcess2, TOKEN_QUERY, &hToken);
		wcout << L"OpenProcess is successful." << endl;
		if (bTokenOK)
		{
			wcout << L"OpenProcessToken is successful." << endl;

			DWORD dwSize;
			BOOL bGetTokenOK = GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
			if (!bGetTokenOK)
			{
				DWORD dwResult = GetLastError();
				if ( dwResult != ERROR_INSUFFICIENT_BUFFER)
				{
					fprintf(stderr, "GetTokenInformation 失败,GetLastError()=%d\n", GetLastError());
					return 1;
				}
			}

			PTOKEN_USER  pTokenUser = (PTOKEN_USER)new BYTE[dwSize];
			bGetTokenOK = GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize);
			if(bGetTokenOK)
			{
				BOOL bLookupSid;
				SID_NAME_USE snu;
				TCHAR szUserName[1024];
				int nLen = sizeof(szUserName)/sizeof(TCHAR);
				DWORD dwUserSize = sizeof(szUserName)/sizeof(TCHAR);
				TCHAR szDomain[1024];
				DWORD cbDomain = sizeof(szDomain)/sizeof(TCHAR);
				bLookupSid = LookupAccountSid(NULL, pTokenUser->User.Sid, 
					szUserName, &dwUserSize, 
					szDomain, &cbDomain, &snu);

				if(!bLookupSid)
				{
					DWORD dwRet = ::GetLastError();
					printf("LookupAccountsid faild...GetLastError() = %d\n", dwRet);
				}
				_tprintf("%s\n", szUserName);
				//wcout << szUserName << endl;
			}

		}
	}	
	getchar();
	return 0; 
}
oldmtn 2011-04-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 tr0j4n 的回复:]
我从硬盘里翻出一段很早之前写的代码,不知道能不能用。
你试试


C/C++ code

#include <windows.h>
#include <iostream.h>
#include <COMDEF.H>
#include <stdio.h>

typedef struct _UNICODE_STRING {
USHORT Length;
……
[/Quote]
不错,就是这个代码。
很感谢各位的回复。
MoXiaoRab 2011-04-29
  • 打赏
  • 举报
回复
顺便可以看下这个 http://hi.baidu.com/tr0j4n/blog/item/7531a62a613e12f0e6cd400a.html
MoXiaoRab 2011-04-29
  • 打赏
  • 举报
回复
我从硬盘里翻出一段很早之前写的代码,不知道能不能用。
你试试


#include <windows.h>
#include <iostream.h>
#include <COMDEF.H>
#include <stdio.h>

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

//SystemProcessInformation
typedef struct _SYSTEM_PROCESS_INFORMATION
{
DWORD dwNextEntryOffset;
DWORD dwNumberOfThreads;
LARGE_INTEGER qSpareLi1;
LARGE_INTEGER qSpareLi2;
LARGE_INTEGER qSpareLi3;
LARGE_INTEGER qCreateTime;
LARGE_INTEGER qUserTime;
LARGE_INTEGER qKernelTime;
UNICODE_STRING ImageName;
int nBasePriority;
DWORD dwProcessId;
DWORD dwInheritedFromUniqueProcessId;
DWORD dwHandleCount;
DWORD dwSessionId;
ULONG dwSpareUl3;
SIZE_T tPeakVirtualSize;
SIZE_T tVirtualSize;
DWORD dwPageFaultCount;
DWORD dwPeakWorkingSetSize;
DWORD dwWorkingSetSize;
SIZE_T tQuotaPeakPagedPoolUsage;
SIZE_T tQuotaPagedPoolUsage;
SIZE_T tQuotaPeakNonPagedPoolUsage;
SIZE_T tQuotaNonPagedPoolUsage;
SIZE_T tPagefileUsage;
SIZE_T tPeakPagefileUsage;
SIZE_T tPrivatePageCount;
LARGE_INTEGER qReadOperationCount;
LARGE_INTEGER qWriteOperationCount;
LARGE_INTEGER qOtherOperationCount;
LARGE_INTEGER qReadTransferCount;
LARGE_INTEGER qWriteTransferCount;
LARGE_INTEGER qOtherTransferCount;
}SYSTEM_PROCESS_INFORMATION;


/*----------------------------------------------------
函数说明: 动态加载动库文件
输入参数: pDllName 库文件名称,pProcName导出函数名字
输出参数: 无
返回值 : 返回函数的的地址
----------------------------------------------------*/
VOID *GetDllProc(CHAR * pDllName, CHAR *pProcName)
{
HMODULE hMod;
hMod = LoadLibraryA(pDllName);
if(hMod == NULL)
return NULL;

return GetProcAddress(hMod, pProcName);
}

//宏定义函数的指针
typedef LONG (WINAPI *Fun_NtQuerySystemInformation) ( int SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT ULONG * pReturnLength OPTIONAL);

typedef BYTE (WINAPI *Fun_WinStationGetProcessSid)(HANDLE hServer,DWORD ProcessId , FILETIME ProcessStartTime,PBYTE pProcessUserSid ,PDWORD dwSidSize);
typedef VOID (WINAPI *Fun_CachedGetUserFromSid)( PSID pSid , PWCHAR pUserName,PULONG cbUserName);
#define STATUS_INFO_LENGTH_MISMATCH ((LONG)0xC0000004L)
#define SystemProcessInformation 5


/*------------------------------------------------------------------
函数说明: 获取系统进程的信息
输入参数: SYSTEM_PROCESS_INFORMATION
输出参数: 无

--------------------------------------------------------------------*/
BOOL GetSysProcInfo(SYSTEM_PROCESS_INFORMATION ** ppSysProcInfo)
{
Fun_NtQuerySystemInformation _NtQuerySystemInformation;
_NtQuerySystemInformation = (Fun_NtQuerySystemInformation)::GetDllProc("NTDLL.DLL", "NtQuerySystemInformation");
if(_NtQuerySystemInformation == NULL)
return FALSE;

DWORD dwSize = 1024*1024;
VOID * pBuf = NULL;
LONG lRetVal;

for(;;)
{
if(pBuf)
free(pBuf);
pBuf = (VOID *)malloc(dwSize);
lRetVal = _NtQuerySystemInformation(SystemProcessInformation,
pBuf, dwSize, NULL);
if(STATUS_INFO_LENGTH_MISMATCH != lRetVal)
break;
dwSize *= 2;
}

if(lRetVal == 0)
{
*ppSysProcInfo = (SYSTEM_PROCESS_INFORMATION *)pBuf;
return TRUE;
}
free(pBuf);
return FALSE;
}



BOOL GetProcessUser(DWORD dwPid, _bstr_t *pbStrUser)
{ Fun_WinStationGetProcessSid _WinStationGetProcessSid;
Fun_CachedGetUserFromSid _CachedGetUserFromSid;

_WinStationGetProcessSid = (Fun_WinStationGetProcessSid)
GetDllProc("Winsta.dll", "WinStationGetProcessSid");
_CachedGetUserFromSid = (Fun_CachedGetUserFromSid)
GetDllProc("utildll.dll", "CachedGetUserFromSid");

if(_WinStationGetProcessSid == NULL || _CachedGetUserFromSid == NULL)
return FALSE;

BYTE cRetVal;
FILETIME ftStartTime;
DWORD dwSize;
BYTE * pSid;
BOOL bRetVal, bFind;
SYSTEM_PROCESS_INFORMATION * pProcInfo, * pCurProcInfo;

bRetVal = GetSysProcInfo(&pProcInfo);
if(bRetVal == FALSE || pProcInfo == NULL)
return FALSE;

bFind = FALSE;
pCurProcInfo = pProcInfo;
for(;;)
{
if(pCurProcInfo->dwProcessId == dwPid)
{
memcpy(&ftStartTime, &pCurProcInfo->qCreateTime, sizeof(ftStartTime));
bFind = TRUE;
break;
}

if(pCurProcInfo->dwNextEntryOffset == 0)
break;
pCurProcInfo = (SYSTEM_PROCESS_INFORMATION *)((BYTE *)pCurProcInfo +
pCurProcInfo->dwNextEntryOffset);
}
if(bFind == FALSE)
{
free(pProcInfo);
return FALSE;
}

cRetVal = _WinStationGetProcessSid(NULL, dwPid, ftStartTime, NULL, &dwSize);
if(cRetVal != 0)
return FALSE;

pSid = new BYTE[dwSize];
cRetVal = _WinStationGetProcessSid(NULL, dwPid, ftStartTime, pSid, &dwSize);
if(cRetVal == 0)
{
delete [] pSid;
return FALSE;
}

WCHAR szUserName[1024];
dwSize = 1024;
_CachedGetUserFromSid(pSid, szUserName, &dwSize);
delete [] pSid;
if(dwSize == 0)
return FALSE;

*pbStrUser = szUserName;
return TRUE;
}

int main()
{

char ch[256] = {0};
_bstr_t bs;

memcpy(&bs,ch,sizeof(bs));

GetProcessUser(932,&bs);

printf(bs);
printf("\n");



return 0;
}
SaberIII 2011-04-29
  • 打赏
  • 举报
回复

int main(int argc, char* argv[])
{
int ProcessId = 532;
WCHAR chBuffer[2][1024];
DWORD ReturnLength;
HANDLE hProcessToken;
int Result;
char tkUser[1024];
SID_NAME_USE sn;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,ProcessId);
Result=OpenProcessToken(hProcess,TOKEN_QUERY,&hProcessToken);
Result=GetTokenInformation(hProcessToken,TokenUser,tkUser,sizeof(tkUser),&ReturnLength);
Result=LookupAccountSid(NULL,((PTOKEN_USER)tkUser)->User.Sid,chBuffer[0],&ReturnLength,chBuffer[1],&ReturnLength,&sn);
printf("用户名: %S \n计算机名: %S\n",chBuffer[0],chBuffer[1]);
return 0;
}


我也是第一次写 ,没有问题啊 可以获取到
Lactoferrin 2011-04-29
  • 打赏
  • 举报
回复
哪一步失败?先处理像explorer.exe这样的进程,某些系统进程的要修改token的dacl
oldmtn 2011-04-29
  • 打赏
  • 举报
回复
DWORD dwProcessId = 1060;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION , FALSE, dwProcessId);
HANDLE hToken;
if (NULL != hProcess)
{
BOOL bTokenOK = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
wcout << L"OpenProcess is successful." << endl;
if (bTokenOK)
{
wcout << L"OpenProcessToken is successful." << endl;

DWORD dwSize;
BOOL bGetTokenOK = GetTokenInformation(hToken, TokenUser, NULL, dwSize, &dwSize);
if (!bGetTokenOK)
{
DWORD dwResult = GetLastError();
if ( dwResult != ERROR_INSUFFICIENT_BUFFER)
{
fprintf(stderr, "GetTokenInformation 失败,GetLastError()=%d\n", GetLastError());
return 1;
}
}

PTOKEN_USER pTokenUser = NULL;
pTokenUser = (PTOKEN_USER) GlobalAlloc(GPTR, dwSize);
if (!pTokenUser)
{
fprintf(stderr, "GlobalAlloc 失败,GetLastError()=%d\n", GetLastError());
return 1;
}


BOOL bLookupSid;
SID_NAME_USE snu;
TCHAR szUserName[MAX_PATH];
DWORD dwUserSize;
TCHAR szDomain[1024];
DWORD cbDomain = 1024;
bLookupSid = LookupAccountSid(NULL, pTokenUser->User.Sid,
szUserName, &dwUserSize,
szDomain, &cbDomain, &snu);

wcout << szUserName << endl;

}
}

我的代码,就是获取不到。。。⊙﹏⊙b汗。。
SaberIII 2011-04-29
  • 打赏
  • 举报
回复
OpenProcessToken 获取访问令牌

GetTokenInformation 参数TokenUser,获取令牌用户
oyljerry 2011-04-29
  • 打赏
  • 举报
回复
可以把这个功能放到一个线程中处理,这样就提高效率了,线程反正在循环执行
oldmtn 2011-04-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 oyljerry 的回复:]

先用depends查看一下dll是否有导出.
[/Quote]
很有帮助的建议,我查了一下。果然在XP SP3 + VS2005 的配置里面查看了advapi32.dll没有找到,GetSiteSidFromToken这个函数,看来微软抛弃了。

但是我自己需要实现这个函数的功能,
PID得到进程句柄------OpenProcess
进程句柄获取进程安全令牌-----OpenProcessToken
安全令牌获取Sid-------------??本来想通过GetSiteSidFromToken来实现的,现在此路不通。
通过Sid获取用户名-----------LookupAccountSid

中间断了,。。。继续考虑中,。。谁能给点启示。。。
oyljerry 2011-04-29
  • 打赏
  • 举报
回复
先用depends查看一下dll是否有导出.

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧