/*
sid一个神秘的东西,本想是获取或者枚举用户和它的关系.
这里有两个从微软搬过来的函数,
一个是从句柄获得sid,这个好像有问题,难道是我使用的问题.
一个是从(用户)名字获取sid.这个经试验是好的.
这里主要用了两个函数:GetTokenInformation,LookupAccountNameW
因为用GetTokenInformation的函数获取的东西好像有点问题,所以此文就命名为:LookupAccountName.Cpp.
*/
#include "stdafx.h"
#include <windows.h>
#include "D:\Program Files\Microsoft Visual Studio 9.0\SmartDevices\SDK\Smartphone2003\Include\mq.h"
#include <Sddl.h>
#pragma comment(lib, "advapi32.lib")
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa446670(v=vs.85).aspx
BOOL GetLogonSID (HANDLE hToken, PSID *ppsid)
{
BOOL bSuccess = FALSE;
DWORD dwIndex;
DWORD dwLength = 0;
PTOKEN_GROUPS ptg = NULL;
if (NULL == ppsid)// Verify the parameter passed in is not NULL.
goto Cleanup;
if (!GetTokenInformation(// Get required buffer size and allocate the TOKEN_GROUPS buffer.
hToken, // handle to the access token
TokenGroups, // get information about the token's groups
(LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
0, // size of buffer
&dwLength // receives required buffer size
))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup;
ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, dwLength);
if (ptg == NULL)
goto Cleanup;
}
if (!GetTokenInformation(hToken,TokenGroups,(LPVOID) ptg,dwLength,&dwLength)) {// Get the token group information from the access token.
goto Cleanup;
}
// Loop through the groups to find the logon SID.
for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++) //这个没有大括号.
if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
{ // Found the logon SID; make a copy of it.
dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
*ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
if (*ppsid == NULL)
goto Cleanup;
if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))
{
HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
goto Cleanup;
}
break;
}
bSuccess = TRUE;
Cleanup:
if (ptg != NULL)// Free the buffer for the token groups.
HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);
return bSuccess;
}
//这个不要了.
//VOID FreeLogonSID (PSID *ppsid)
//{
// HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
//}
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms707085(v=vs.85).aspx
//还有一个函数:CreateQSecDescriptor
HRESULT GetSid(LPCWSTR wszAccName,PSID * ppSid) //此函数,还可以精简,我没有精简.
{
if (wszAccName == NULL || ppSid == NULL) {// Validate the input parameters.
return MQ_ERROR_INVALID_PARAMETER;
}
// Create buffers that may be large enough.If a buffer is too small, the count parameter will be set to the size needed.
const DWORD INITIAL_SIZE = 32;
DWORD cbSid = 0;
DWORD dwSidBufferSize = INITIAL_SIZE;
DWORD cchDomainName = 0;
DWORD dwDomainBufferSize = INITIAL_SIZE;
WCHAR * wszDomainName = NULL;
SID_NAME_USE eSidType;
DWORD dwErrorCode = 0;
HRESULT hr = MQ_OK;
*ppSid = (PSID) new BYTE[dwSidBufferSize];// Create buffers for the SID and the domain name.
if (*ppSid == NULL) {
return MQ_ERROR_INSUFFICIENT_RESOURCES;
}
memset(*ppSid, 0, dwSidBufferSize);
wszDomainName = new WCHAR[dwDomainBufferSize];
if (wszDomainName == NULL) {
return MQ_ERROR_INSUFFICIENT_RESOURCES;
}
memset(wszDomainName, 0, dwDomainBufferSize*sizeof(WCHAR));
for ( ; ; )// Obtain the SID for the account name passed.
{ // Set the count variables to the buffer sizes and retrieve the SID.
cbSid = dwSidBufferSize;
cchDomainName = dwDomainBufferSize;
if (LookupAccountNameW(
NULL, // Computer name. NULL for the local computer
wszAccName,
*ppSid, // Pointer to the SID buffer. Use NULL to get the size needed,
&cbSid, // Size of the SID buffer needed.
wszDomainName, // wszDomainName,//这个还能获取域名.
&cchDomainName,
&eSidType)) //其实这个函数就是返回sid和域名用的别的没啥,不要多想,下面的是垃圾,加上更完美.
{
if (IsValidSid(*ppSid) == FALSE)
{
wprintf(L"The SID for %s is invalid.\n", wszAccName);
dwErrorCode = MQ_ERROR;
}
break;
}
dwErrorCode = GetLastError();
if (dwErrorCode == ERROR_INSUFFICIENT_BUFFER) // Check if one of the buffers was too small.
{
if (cbSid > dwSidBufferSize)
{ // Reallocate memory for the SID buffer.
wprintf(L"The SID buffer was too small. It will be reallocated.\n");
FreeSid(*ppSid);
*ppSid = (PSID) new BYTE[cbSid];
if (*ppSid == NULL)
{
return MQ_ERROR_INSUFFICIENT_RESOURCES;
}
memset(*ppSid, 0, cbSid);
dwSidBufferSize = cbSid;
}
if (cchDomainName > dwDomainBufferSize)
{ // Reallocate memory for the domain name buffer.
wprintf(L"The domain name buffer was too small. It will be reallocated.\n");
delete [] wszDomainName;
wszDomainName = new WCHAR[cchDomainName];
if (wszDomainName == NULL)
{
return MQ_ERROR_INSUFFICIENT_RESOURCES;
}
memset(wszDomainName, 0, cchDomainName*sizeof(WCHAR));
dwDomainBufferSize = cchDomainName;
}
}
else
{
wprintf(L"LookupAccountNameW failed. GetLastError returned: %d\n", dwErrorCode);
hr = HRESULT_FROM_WIN32(dwErrorCode);
break;
}
}
delete [] wszDomainName;
return hr;
}
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa379554(v=vs.85).aspx
#define MAX_NAME 256
BOOL SearchTokenGroupsForSID (VOID) //这个暂时放这里.不做讨论.
{
DWORD i, dwSize = 0, dwResult = 0;
HANDLE hToken;
PTOKEN_GROUPS pGroupInfo;
SID_NAME_USE SidType;
char lpName[MAX_NAME];
char lpDomain[MAX_NAME];
PSID pSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
// Open a handle to the access token for the calling process.
if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken ))
{
printf( "OpenProcessToken Error %u\n", GetLastError() );
return FALSE;
}
// Call GetTokenInformation to get the buffer size.
if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
{
dwResult = GetLastError();
if( dwResult != ERROR_INSUFFICIENT_BUFFER ) {
printf( "GetTokenInformation Error %u\n", dwResult );
return FALSE;
}
}
// Allocate the buffer.
pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );
// Call GetTokenInformation again to get the group information.
if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize ) )
{
printf( "GetTokenInformation Error %u\n", GetLastError() );
return FALSE;
}
// Create a SID for the BUILTIN\Administrators group.
if(! AllocateAndInitializeSid( &SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID) )
{
printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );
return FALSE;
}
// Loop through the group SIDs looking for the administrator SID.
for(i=0; i<pGroupInfo->GroupCount; i++)
{
if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) )
{ // Lookup the account name and print it.
dwSize = MAX_NAME;
if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid, (LPWSTR)lpName, &dwSize, (LPWSTR)lpDomain, &dwSize, &SidType ) ) //此函数能实现根据sid获取用户名的功能,进而可以想办法利用此函数进行枚举.
{
dwResult = GetLastError();
if( dwResult == ERROR_NONE_MAPPED )
strcpy_s (lpName, dwSize, "NONE_MAPPED" );
else
{
printf("LookupAccountSid Error %u\n", GetLastError());
return FALSE;
}
}
printf( "Current user is a member of the %s\\%s group\n", lpDomain, lpName );
// Find out whether the SID is enabled in the token.
if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
printf("The group SID is enabled.\n");
else if (pGroupInfo->Groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY)
printf("The group SID is a deny-only SID.\n");
else
printf("The group SID is not enabled.\n");
}
}
if (pSID)
FreeSid(pSID);
if ( pGroupInfo )
GlobalFree( pGroupInfo );
return TRUE;
}
//更多的还有http://msdn.microsoft.com/en-us/library/windows/desktop/aa379608(v=vs.85).aspx
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t sz_UserNamew[260] = {0};
int len = sizeof(sz_UserNamew);
GetUserName(sz_UserNamew,(LPDWORD)&len);
LPWSTR * wsz_sid = (LPWSTR *)HeapAlloc(GetProcessHeap(), 0, 0x200);
PSID * ppSid = (PSID *)HeapAlloc(GetProcessHeap(), 0, 0x200);
GetSid(sz_UserNamew,ppSid);//Administrator,Defaultapppool应该有枚举的办法.NetUserEnum,但不全.特殊的没有.
bool b = ConvertSidToStringSid(*ppSid,(LPWSTR *)wsz_sid);
int x = GetLastError();
MessageBox(0,(LPCWSTR)(* ( int *)wsz_sid),0,0);
RtlZeroMemory(wsz_sid,0x200);
RtlZeroMemory(ppSid,0x200);
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY_SOURCE | TOKEN_QUERY, &hToken)) return( FALSE );
GetLogonSID(hToken,ppSid);//字面意思是登录的sid,用的是当前进程或者线程的句柄.
b = ConvertSidToStringSid(*ppSid,(LPWSTR *)wsz_sid);
x = GetLastError();
MessageBox(0,(LPCWSTR)(* ( int *)wsz_sid),0,0);//得到的这个值在注册表中找不到.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
HeapFree(GetProcessHeap(), 0, wsz_sid);
HeapFree(GetProcessHeap(), 0, ppSid);
SearchTokenGroupsForSID();
return 0;
}
//made by correy.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
参考:Microsoft SDKs\Windows\v7.1\Samples\security\authorization\textsid这个工程.
获取当前用户(进程的)SID更简单.其实也就这么简单.
made at 2013.10.10
*/
#include <windows.h>
#include <Sddl.h>
int _tmain()
{
#define MY_BUFSIZE 256 // all allocations should be dynamic
HANDLE hToken;
BYTE buf[MY_BUFSIZE];
PTOKEN_USER ptgUser = (PTOKEN_USER)buf;
DWORD cbBuffer=MY_BUFSIZE;
BOOL bSuccess;
// obtain current process token
if(!OpenProcessToken(
GetCurrentProcess(), // target current process
TOKEN_QUERY, // TOKEN_QUERY access
&hToken // resultant hToken
)) {
return 1;
}
// obtain user identified by current process' access token
bSuccess = GetTokenInformation(
hToken, // identifies access token
TokenUser, // TokenUser info type
ptgUser, // retrieved info buffer
cbBuffer, // size of buffer passed-in
&cbBuffer // required buffer size
);
CloseHandle(hToken);
if(!bSuccess) {
return 1;
}
LPWSTR lpSid = NULL;
ConvertSidToStringSid(ptgUser->User.Sid, &lpSid);
//这时已经获取到了,可以查看了.
LocalFree(lpSid);
return 1;
}
没有评论:
发表评论