绘制线条-PolylineTo函数逆向分析


绘制一条或多条直线 它的函数原型

BOOL PolylineTo(
  [in] HDC         hdc,//设备上下文的句柄。
  [in] const POINT *apt,//指向包含线的顶点的POINT结构数组的指针,以逻辑单位表示。
  [in] DWORD       cpt//数组中的点数。
);

这里主要看内核实现  通过win32u.dll 进入内核的NtGdiPolyPolyDraw 所以这里就分析NtGdiPolyPolyDraw

__int64 __fastcall NtGdiPolyPolyDraw(__int64 a1, void *a2, void *a3, unsigned int a4, int a5)
{
  __int64 v5; // r13
  __int64 PolyPolygonRgnInternal; // rdi
  int v9; // r14d
  unsigned int *v10; // r12
  struct _POINTL *v11; // r15
  void *v12; // rdx
  char *v13; // rcx
  unsigned int v14; // r13d
  __int64 i; // rcx
  size_t v16; // r8
  void *v17; // rdx
  __int64 v18; // rdx
  __int64 (__fastcall *v19)(__int64, struct _POINTL *, unsigned int *, _QWORD, unsigned int); // rax
  int v20; // eax
  __int64 (__fastcall *v22)(__int64, struct _POINTL *, _QWORD); // rax
  int v23; // eax
  int v24; // eax
  unsigned int v26; // [rsp+34h] [rbp-E4h] BYREF
  __int64 v27; // [rsp+38h] [rbp-E0h]
  unsigned int v28; // [rsp+40h] [rbp-D8h]
  int v29; // [rsp+44h] [rbp-D4h]
  unsigned int v30; // [rsp+48h] [rbp-D0h]
  __int64 v31; // [rsp+50h] [rbp-C8h]
  unsigned int *v32; // [rsp+58h] [rbp-C0h]
  struct _POINTL *v33; // [rsp+60h] [rbp-B8h]
  void *Src; // [rsp+68h] [rbp-B0h]
  void *v35; // [rsp+70h] [rbp-A8h]
  __int64 v36; // [rsp+78h] [rbp-A0h]
  struct _POINTL v37; // [rsp+80h] [rbp-98h] BYREF

  v5 = a4;
  Src = a3;
  v35 = a2;
  v27 = a1;
  v36 = a1;
  v30 = a4;
  v28 = 0;
  PolyPolygonRgnInternal = 1i64;
  v31 = 1i64;
  v26 = 0;
  if ( !a4 )                                    // 判断r9 是否有值
    return 0i64;
  if ( a5 == 2 )
  {
    if ( qword_1C02517F0 )
    {
      v23 = qword_1C02517F0();
      v9 = 0xC00000BB;
      a1 = v27;
    }
    else
    {
      v9 = 0xC00000BB;
      v23 = 0xC00000BB;
    }
    if ( v23 < 0 )
      return PolyPolygonRgnInternal;
    v24 = (int)qword_1C02517F8;
    if ( qword_1C02517F8 )
      v24 = qword_1C02517F8(a1, a2, a3, (unsigned int)v5);
    if ( v24 )
      return PolyPolygonRgnInternal;
  }
  else
  {
    v9 = 0xC00000BB;
  }
  if ( (unsigned int)v5 <= 1 )
  {
    v10 = &v26;
    goto LABEL_6;
  }
  if ( (unsigned int)(a5 - 3) > 2 )
  {
    if ( (unsigned int)v5 > 0x9C4000 )
    {
      EngSetLastError(0x57u);
      v10 = 0i64;
    }
    else
    {
      v10 = (unsigned int *)PALLOCMEM2((unsigned int)(4 * v5), 0x706D7447u, 0);
    }
LABEL_6:
    v32 = v10;
    if ( v10 )
    {
      v11 = &v37;
      v33 = &v37;
      v29 = 0;
      v12 = Src;
      v13 = (char *)Src + 4 * v5;
      if ( v13 < Src || (unsigned __int64)v13 > MmUserProbeAddress )
        *(_BYTE *)MmUserProbeAddress = 0;
      memmove(v10, v12, 4 * v5);                // v10 就是count
      v14 = 0;
      v28 = 0;
      for ( i = 0i64; ; i = (unsigned int)(i + 1) )
      {
        v29 = i;
        if ( (unsigned int)i >= a4 )            // 传进多少组点 
          break;
        v14 += v10[i];                          // 累加所有组点
        v28 = v14;
      }
      if ( v14 > 0x4E2000 )
        goto LABEL_21;
      if ( v14 > 0xA )
      {
        v11 = (struct _POINTL *)AllocFreeTmpBuffer(8 * v14);
        v33 = v11;
      }
      if ( v11 )
      {
        v16 = 8i64 * v14;
        v17 = v35;
        if ( (char *)v35 + v16 < v35 || (unsigned __int64)v35 + v16 > MmUserProbeAddress )
          *(_BYTE *)MmUserProbeAddress = 0;
        memmove(v11, v17, v16);
      }
      else
      {
LABEL_21:
        PolyPolygonRgnInternal = 0i64;
        v31 = 0i64;
      }
      v18 = v27;
      if ( !PolyPolygonRgnInternal )
        goto LABEL_31;
      switch ( a5 )
      {
        case 1:
          if ( qword_1C02517E0 )
            v9 = qword_1C02517E0(a4, v27);
          if ( v9 >= 0 )
          {
            v19 = (__int64 (__fastcall *)(__int64, struct _POINTL *, unsigned int *, _QWORD, unsigned int))qword_1C02517E8;// win32kfull!GrePolyPolygon:
            goto LABEL_28;
          }
          goto LABEL_67;
        case 2:
          if ( qword_1C0251810 )
            v9 = qword_1C0251810(a4, v27);
          if ( v9 >= 0 )
          {
            v19 = (__int64 (__fastcall *)(__int64, struct _POINTL *, unsigned int *, _QWORD, unsigned int))qword_1C0251818;//  win32kfull!GrePolyPolyline:
LABEL_28:
            if ( v19 )
            {
              v20 = v19(v27, v11, v10, a4, v14);
LABEL_30:
              PolyPolygonRgnInternal = v20;
              goto LABEL_31;
            }
            goto LABEL_75;
          }
          goto LABEL_67;
        case 3:
          if ( qword_1C0251800 )
            v9 = qword_1C0251800(a4, v27);
          if ( v9 < 0 )
            goto LABEL_67;
          v22 = (__int64 (__fastcall *)(__int64, struct _POINTL *, _QWORD))qword_1C0251808;// win32kfull!GrePolyBezier:
          break;
        case 4:
          if ( qword_1C0251830 )
            v9 = qword_1C0251830(a4, v27);
          if ( v9 < 0 )
            goto LABEL_67;
          v22 = (__int64 (__fastcall *)(__int64, struct _POINTL *, _QWORD))qword_1C0251838;// win32kfull!GrePolylineTo
          break;
        case 5:
          if ( qword_1C0251820 )
            v9 = qword_1C0251820(a4, v27);
          if ( v9 >= 0 )
          {
            v22 = (__int64 (__fastcall *)(__int64, struct _POINTL *, _QWORD))qword_1C0251828;// win32kfull!GrePolylineTo
            break;
          }
          break;
        case 6:
          PolyPolygonRgnInternal = (__int64)GreCreatePolyPolygonRgnInternal(v11, (__int64)v10, a4, v27, v14);
          goto LABEL_31;
        default:
LABEL_67:
          PolyPolygonRgnInternal = 0i64;
LABEL_31:
          if ( v11 && v11 != &v37 )
            FreeTmpBuffer((char *)v11);
          if ( v10 != &v26 )
            Win32FreePool(v10, v18);
          return PolyPolygonRgnInternal;
      }
      if ( v22 )
      {
        v20 = v22(v27, v11, v26);
        goto LABEL_30;
      }
LABEL_75:
      v20 = 0;
      goto LABEL_30;
    }
    return 0i64;
  }
  return 0i64;
}

相关