|
|
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <ole2.h>
#include <stdio.h>
#include <stdlib.h>
#include "wmium.h"
#define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)Base + Offset))
//
// The routines below were blantenly stolen without remorse from the ole
// sources in \nt\private\ole32\com\class\compapi.cxx. They are copied here
// so that WMI doesn't need to load in ole32 only to convert a guid string
// into its binary representation.
//
//+-------------------------------------------------------------------------
//
// Function: HexStringToDword (private)
//
// Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
// return value in Value; check for chDelim;
//
// Arguments: [lpsz] - the hex string to convert
// [Value] - the returned value
// [cDigits] - count of digits
//
// Returns: TRUE for success
//
//--------------------------------------------------------------------------
BOOL HexStringToDword(LPCSTR lpsz, DWORD * RetValue, int cDigits, WCHAR chDelim) { int Count; DWORD Value;
Value = 0; for (Count = 0; Count < cDigits; Count++, lpsz++) { if (*lpsz >= '0' && *lpsz <= '9') Value = (Value << 4) + *lpsz - '0'; else if (*lpsz >= 'A' && *lpsz <= 'F') Value = (Value << 4) + *lpsz - 'A' + 10; else if (*lpsz >= 'a' && *lpsz <= 'f') Value = (Value << 4) + *lpsz - 'a' + 10; else return(FALSE); }
*RetValue = Value; if (chDelim != 0) return *lpsz++ == chDelim; else return TRUE; } //+-------------------------------------------------------------------------
//
// Function: wUUIDFromString (internal)
//
// Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000
//
// Arguments: [lpsz] - Supplies the UUID string to convert
// [pguid] - Returns the GUID.
//
// Returns: TRUE if successful
//
//--------------------------------------------------------------------------
BOOL wUUIDFromString(LPCSTR lpsz, LPGUID pguid) { DWORD dw;
if (!HexStringToDword(lpsz, &pguid->Data1, sizeof(DWORD)*2, '-')) return FALSE; lpsz += sizeof(DWORD)*2 + 1; if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-')) return FALSE; lpsz += sizeof(WORD)*2 + 1;
pguid->Data2 = (WORD)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-')) return FALSE; lpsz += sizeof(WORD)*2 + 1;
pguid->Data3 = (WORD)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0)) return FALSE; lpsz += sizeof(BYTE)*2;
pguid->Data4[0] = (BYTE)dw; if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, '-')) return FALSE; lpsz += sizeof(BYTE)*2+1;
pguid->Data4[1] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0)) return FALSE; lpsz += sizeof(BYTE)*2;
pguid->Data4[2] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0)) return FALSE; lpsz += sizeof(BYTE)*2;
pguid->Data4[3] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0)) return FALSE; lpsz += sizeof(BYTE)*2;
pguid->Data4[4] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0)) return FALSE; lpsz += sizeof(BYTE)*2;
pguid->Data4[5] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0)) return FALSE; lpsz += sizeof(BYTE)*2;
pguid->Data4[6] = (BYTE)dw; if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0)) return FALSE; lpsz += sizeof(BYTE)*2;
pguid->Data4[7] = (BYTE)dw;
return TRUE; }
//+-------------------------------------------------------------------------
//
// Function: wGUIDFromString (internal)
//
// Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000}
//
// Arguments: [lpsz] - the guid string to convert
// [pguid] - guid to return
//
// Returns: TRUE if successful
//
//--------------------------------------------------------------------------
BOOL wGUIDFromString(LPCSTR lpsz, LPGUID pguid) { DWORD dw;
if (*lpsz == '{' ) lpsz++;
if(wUUIDFromString(lpsz, pguid) != TRUE) return FALSE;
lpsz +=36;
if (*lpsz == '}' ) lpsz++;
if (*lpsz != '\0') // check for zero terminated string - test bug #18307
{ return FALSE; }
return TRUE; }
PTCHAR GuidToString( PTCHAR s, LPGUID piid ) { wsprintf(s, TEXT("%x-%x-%x-%x%x%x%x%x%x%x%x"), piid->Data1, piid->Data2, piid->Data3, piid->Data4[0], piid->Data4[1], piid->Data4[2], piid->Data4[3], piid->Data4[4], piid->Data4[5], piid->Data4[6], piid->Data4[7]);
return(s); }
#if 0
void WackOnFile(void) { ULONG Status; HANDLE FH; FH = CreateFile("e:\\foo.baz", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (FH != INVALID_HANDLE_VALUE) { Status = ERROR_SUCCESS; CloseHandle(FH); } else { Status = GetLastError(); } printf("CreateFile --> %d\n", Status); }
void CheckOwnPriv( void ) { UCHAR Buffer[4096]; HANDLE TokenHandle; ULONG SizeNeeded; BOOL b; ULONG i; PTOKEN_PRIVILEGES TokenPrivInfo;
if (! ImpersonateSelf(SecurityImpersonation)) { printf("Impersonatself -> %d\n", GetLastError()); return; } b = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &TokenHandle); if (! b) { printf("OpenThreadToken failed %d\n", GetLastError()); return; } printf("OpenThreadToken succeeded\n"); TokenPrivInfo = (PTOKEN_PRIVILEGES)Buffer; b = GetTokenInformation(TokenHandle, TokenPrivileges, TokenPrivInfo, sizeof(Buffer), &SizeNeeded); printf("GetTokenInformation(YokenPriv) -> %s (%d), sizeNeeded = %d\n", b ? "TRUE" : "FALSE", GetLastError(), SizeNeeded); RevertToSelf(); if (b) { printf("Priv count is %d\n", TokenPrivInfo->PrivilegeCount); for (i = 0; i < TokenPrivInfo->PrivilegeCount; i++) { UCHAR PrivName[1024]; ULONG SizePrivName = sizeof(PrivName); if ( ! LookupPrivilegeName(NULL, &TokenPrivInfo->Privileges[i].Luid, PrivName, &SizePrivName)) { sprintf(PrivName, "[Error %d]", GetLastError()); } printf("Priv %s %x%x has attr %x\n", PrivName, TokenPrivInfo->Privileges[i].Luid.HighPart, TokenPrivInfo->Privileges[i].Luid.LowPart, TokenPrivInfo->Privileges[i].Attributes); } printf("\n"); } }
PCHAR SidUsage[] = { "SidTypeZero", "SidTypeUser", "SidTypeGroup", "SidTypeDomain", "SidTypeAlias", "SidTypeWellKnownGroup", "SidTypeDeletedAccount", "SidTypeInvalid", "SidTypeUnknown", "SidTypeComputer", };
void GetCallerInfo(BOOLEAN Impersonating) { UCHAR Buffer[4096]; PTOKEN_USER TokenUserInfo = (PTOKEN_USER)Buffer; PSID_AND_ATTRIBUTES SidAndAttributes = &TokenUserInfo->User; PSID Sid; HANDLE TokenHandle; ULONG SizeNeeded; BOOLEAN b; CHAR Name[MAX_PATH]; CHAR Domain[MAX_PATH]; ULONG NameSize = sizeof(Name); ULONG DomainSize = sizeof(Domain); SID_NAME_USE SidNameUse; ULONG i; PUCHAR SidBuffer; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PTOKEN_PRIVILEGES TokenPrivInfo; SidBuffer = malloc(RtlLengthRequiredSid( 1 )); RtlInitializeSid( SidBuffer, &NtAuthority, 1); *(RtlSubAuthoritySid( SidBuffer, 0 )) = SECURITY_LOCAL_SYSTEM_RID; b = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &TokenHandle); if (! b) { printf("OpenThreadToken failed %d\n", GetLastError()); return; } printf("OpenThreadToken succeeded\n"); TokenPrivInfo = (PTOKEN_PRIVILEGES)Buffer; b = GetTokenInformation(TokenHandle, TokenPrivileges, TokenPrivInfo, sizeof(Buffer), &SizeNeeded); printf("GetTokenInformation(YokenPriv) -> %s (%d), sizeNeeded = %d\n", b ? "TRUE" : "FALSE", GetLastError(), SizeNeeded); if (b) { RpcRevertToSelf(); printf("Priv count is %d\n", TokenPrivInfo->PrivilegeCount); for (i = 0; i < TokenPrivInfo->PrivilegeCount; i++) { UCHAR PrivName[1024]; ULONG SizePrivName = sizeof(PrivName); if ( ! LookupPrivilegeName(NULL, &TokenPrivInfo->Privileges[i].Luid, PrivName, &SizePrivName)) { sprintf(PrivName, "[Error %d]", GetLastError()); } printf("Priv %s %x%x has attr %x\n", PrivName, TokenPrivInfo->Privileges[i].Luid.HighPart, TokenPrivInfo->Privileges[i].Luid.LowPart, TokenPrivInfo->Privileges[i].Attributes); } printf("\n"); RpcImpersonateClient(0); } b = GetTokenInformation(TokenHandle, TokenUser, TokenUserInfo, sizeof(Buffer), &SizeNeeded); printf("GetTokenInformation -> %s (%d), sizeNeeded = %d\n", b ? "TRUE" : "FALSE", GetLastError(), SizeNeeded); if (b) { if (Impersonating) { RpcRevertToSelf(); } Sid = SidAndAttributes->Sid;
if (EqualSid(Sid, (PSID)SidBuffer) && GetLastError() == ERROR_SUCCESS) { printf("Called by LocalSystem !!\n"); } else { printf("EqualSid %d\n", GetLastError()); }
b = LookupAccountSid(NULL, Sid, Name, &NameSize, Domain, &DomainSize, &SidNameUse); if (Impersonating) { RpcImpersonateClient(0); } if (b) { printf("Account: %s\\%s Type %s\n", Domain, Name, SidUsage[SidNameUse]); } else { printf("LookupAccountSid %d\n", GetLastError()); } } CloseHandle(TokenHandle); } #endif
void EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG Context);
#define DATA_PROVIDER_PNPID_GUID \
{ 0xc7bf35d2,0xaadb,0x11d1, { 0xbf,0x4a,0x00,0xa0,0xc9,0x06,0x29,0x10 } } GUID GuidXYZ = DATA_PROVIDER_PNPID_GUID;
ULONG EventsReceived;
void EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG Context) { PWNODE_SINGLE_INSTANCE WnodeSI = (PWNODE_SINGLE_INSTANCE)WnodeHeader; PWNODE_HEADER Wnode = WnodeHeader; LPGUID EventGuid = &WnodeHeader->Guid; CHAR s[MAX_PATH]; ULONG Status; WMIHANDLE Handle; #if 0
GetCallerInfo(FALSE); RevertToSelf(); GetCallerInfo(FALSE); WackOnFile();
Status = RpcImpersonateClient(0); printf("RpcImpersonateClient -> %d\n", Status); if (Status == ERROR_SUCCESS) { WmiOpenBlock(&GuidXYZ, GENERIC_READ, &Handle); GetCallerInfo(TRUE); WackOnFile(); RpcRevertToSelf(); } #endif
EventsReceived++;
printf("Receieved event for guid %s\n", GuidToString(s, EventGuid)); printf("BufferSize = 0x%x\n", Wnode->BufferSize); printf("ProviderId = %x\n", Wnode->ProviderId); // Provider Id of driver returning this buffer
printf("Version = %x\n", Wnode->Version); // Reserved
printf("Linkage = %x\n", Wnode->Linkage); // Linkage field reserved for WMI
printf("ClientContext = %x\n", Wnode->ClientContext); printf("Flags = %x\n", Wnode->Flags); // Flags, see below
if (Wnode->Flags & WNODE_FLAG_SINGLE_INSTANCE) { printf("WNODE_SINGLE_INSTANCE\n"); printf("OffsetInstanceName = %x\n", WnodeSI->OffsetInstanceName); printf("InstanceIndex = %x\n", WnodeSI->InstanceIndex); // (Static Instance Names)
printf("DataBlockOffset = %x\n", WnodeSI->DataBlockOffset); // offset from beginning of WNODE to data block
printf("SizeDataBlock = %x\n", WnodeSI->SizeDataBlock); // Size of data block for instance
}
printf("\n%d events received\n", EventsReceived); }
#if 0
#define WmiRpcProtocolSequence1 TEXT("ncacn_np")
#define WmiRpcProtocolSequence2 TEXT("ncalrpc")
#define MaxRpcCalls RPC_C_PROTSEQ_MAX_REQS_DEFAULT
void CreateEndpoints(void) { ULONG i; ULONG Status; CHAR UniqueEndpoint[MAX_PATH]; SECURITY_DESCRIPTOR SD; InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&SD, TRUE, NULL, FALSE); for (i = 0; i < 20; i++) { sprintf(UniqueEndpoint, "TESTLRPCEP_%x", i);
Status = RpcServerUseProtseqEp(WmiRpcProtocolSequence2, MaxRpcCalls, UniqueEndpoint, &SD); // Security descriptor
if (Status != ERROR_SUCCESS) { printf("RpcServerUseProtseqEp failed %d\n", Status); } }
for (i = 0; i < 20; i++) { sprintf(UniqueEndpoint, "\\pipe\\TESTEP_%x", i);
Status = RpcServerUseProtseqEp(WmiRpcProtocolSequence1, MaxRpcCalls, UniqueEndpoint, &SD); // Security descriptor
if (Status != ERROR_SUCCESS) { printf("RpcServerUseProtseqEp failed %d\n", Status); } } } #endif
PWNODE_HEADER EventPtrBuffer; int _cdecl main(int argc, char *argv[]) { ULONG Status; GUID Guid; ULONG c,i;
#if 0
c = 1; for (i = 0; i < 101; i++) { c += i; } printf("c = %d\n",c); #endif
if ((argc != 2) && (argc != 3)) { printf("getevent <guid>\n"); return(0); }
#if 0
CheckOwnPriv(); if (argc == 3) { printf("Creating endpoints\n"); CreateEndpoints(); } #endif
//
// Parse the guid parameter
if (! wGUIDFromString(argv[1], &Guid)) { printf("Bad guid %s\n", argv[1]); return(0); } Status = WmiNotificationRegistration(&Guid, TRUE, EventCallbackRoutine, 0, NOTIFICATION_CALLBACK_DIRECT); if (Status != ERROR_SUCCESS) { printf("WMINotificationRegistration %d\n", Status); return(1); }
// Loop forever receiving events
while (1) Sleep(1000*1000); return(ERROR_SUCCESS); }
|