ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NtGdiPolyPolyDraw内核函数逆向分析

2022-04-23 17:02:41  阅读:201  来源: 互联网

标签:__ 逆向 int v10 v16 QWORD 内核 NtGdiPolyPolyDraw DWORD


0x00前言

分析文件是win11 21h2 的win32kbase.sys 驱动里面的NtGdiPolyPolyDraw 内核函数

0x01NtGdiPolyPolyDraw流程

NtGdiPolyPolyDraw 一共接收5个参数

__int64 __fastcall NtGdiPolyPolyDraw(
__int64 a1, 3环hdc句柄
void *a2, POINT数组
void *a3, POINT数组长度
unsigned int a4  多少组POINT数组
, int a5)type 不同调用不同处理函数

第一步判断a5是不是等于2 如果是就调用NtGdiFastPolyPolyline  返回失败 直接返回函数

 

 接着会调用GrePolyPolyline

 

只有当a4的值大于1 才会去申请内存存放这些数组 循环累加数组有多少个点

 

 a5 决定调用什么函数处理点

 

 

 默认是4 会去调用GrePolylineTo 它又会去调用 EPATHOBJ::bPolyLineTo   生成点

 

 EPATHOBJ::addpoints  实现

 

 关键的是EPATHOBJ::createrec  完成点赋值的

__int64 __fastcall EPATHOBJ::createrec(
        EPATHOBJ *this,
        struct EXFORMOBJ *a2,
        struct _PATHDATAL *a3,
        struct _POINTFIX *a4)
{
  EXFORMOBJ *v6; // r11
  __int64 v8; // r10
  struct PATHALLOC *v9; // r15
  __int64 v10; // rbx
  unsigned __int64 v11; // rcx
  unsigned __int64 v12; // rax
  unsigned int v13; // r12d
  int v14; // r8d
  __int64 v16; // rdi
  __int64 v17; // rax
  struct _POINTFIX *v18; // rcx
  struct _POINTFIX *v19; // rdx
  _DWORD *v20; // rdx
  __int64 v21; // rcx
  __int64 v22; // r8
  _DWORD *v23; // rax
  int v24; // ecx
  int v25; // ecx
  _QWORD *v26; // rax
  __int64 v28; // rax
  struct PATHALLOC *v29; // rax
  __int64 v30; // [rsp+40h] [rbp-38h]

  v6 = a2;
  v8 = *((_QWORD *)this + 1);
  v30 = *(_QWORD *)(v8 + 24);                   // 是否已经有堆
  v9 = (struct PATHALLOC *)v30;
  LODWORD(v10) = 0;
  if ( v30 )
  {
    v11 = *(_QWORD *)(v30 + 8) + 24i64;         // 已经复制到多少地址
    v12 = v30 + *(unsigned int *)(v30 + 16);    // 当前地址
    if ( v12 > v11 )
      v10 = (__int64)(v12 - v11) >> 3;
  }
  v13 = *(_DWORD *)(v8 + 80) & 1;               // 调用是3  0或1
  v14 = *(_DWORD *)a3;
  if ( (v14 & 0x10) != 0 && (_DWORD)v10 )       // v14默认0
    LODWORD(v10) = 3 * (((unsigned int)v10 - v13) / 3) + v13;
  if ( (unsigned int)v10 < v13 + *((_DWORD *)a3 + 1) && (unsigned int)v10 < 8 )// 默认可以走
  {
    v29 = newpathalloc();                       // 默认0xFC0大小
    v9 = v29;
    if ( !v29 )
    {
      EngSetLastError(8u);
      EPATHOBJ::reinit(this);
      return 0i64;
    }
    *(_QWORD *)v29 = *(_QWORD *)(*((_QWORD *)this + 1) + 24i64);// 调试是0
    *(_QWORD *)(*((_QWORD *)this + 1) + 24i64) = v29;// 堆等于
    LODWORD(v10) = (unsigned int)((_DWORD)v29 + *((_DWORD *)v29 + 4) - *((_DWORD *)v29 + 2) - 24) >> 3;// (堆大小-30h)/8
    v14 = *(_DWORD *)a3;
    if ( (*(_DWORD *)a3 & 0x10) != 0 )
      LODWORD(v10) = 3 * (((unsigned int)v10 - v13) / 3) + v13;// 对齐
    v6 = a2;
  }
  if ( (unsigned int)v10 > v13 + *((_DWORD *)a3 + 1) )// 大于就当前要拷贝的长度
    LODWORD(v10) = v13 + *((_DWORD *)a3 + 1);
  v16 = *((_QWORD *)v9 + 1);                    // 堆+8 去地址
  *(_DWORD *)(v16 + 16) = v14 | 2;              // a3[0]
  *(_DWORD *)(v16 + 20) = v10;                  // 真实大小
  *(_QWORD *)v16 = 0i64;
  *(_QWORD *)(v16 + 8) = *(_QWORD *)(*((_QWORD *)this + 1) + 40i64);
  v17 = *((_QWORD *)this + 1);
  if ( v13 )
  {
    *(_QWORD *)(v16 + 24) = *(_QWORD *)(v17 + 64);
    LODWORD(v10) = v10 - 1;                     // v10是要复制的长度
    *(_DWORD *)(v16 + 16) |= *(_DWORD *)(*((_QWORD *)this + 1) + 80i64) & 5;
    *(_DWORD *)(*((_QWORD *)this + 1) + 80i64) &= 0xFFFFFFFA;
  }
  else
  {
    v28 = *(_QWORD *)(v17 + 40);
    if ( v28 )
      *(_DWORD *)(v28 + 16) &= ~2u;
  }
  v18 = (struct _POINTFIX *)(v16 + 8 * (v13 + 3i64));// 控制开始复制地址
  v19 = (struct _POINTFIX *)*((_QWORD *)a3 + 1);// point 地址
  if ( a4 )
  {
    vOffsetPoints(v18, v19, v10, a4->x, a4->y);
  }
  else if ( v6 )                                // a2不为空默认走的
  {
    EXFORMOBJ::bXformRound(v6, (struct _POINTL *)v19, (struct _POINTFIX *)(v16 + 8 * (v13 + 3i64)), (unsigned int)v10);
  }
  else
  {
    memmove(v18, v19, 8i64 * (unsigned int)v10);
  }
  *((_DWORD *)a3 + 1) -= v10;                   // 减去复制大小
  *((_QWORD *)a3 + 1) += 8i64 * (unsigned int)v10;// 增加复制地址
  *(_DWORD *)a3 &= 0xFFFFFFFA;
  v20 = (_DWORD *)(v16 + 24);
  v21 = *((_QWORD *)this + 1);
  if ( !*(_QWORD *)(v21 + 40) )
  {
    *(_DWORD *)(v21 + 56) = *v20;
    *(_DWORD *)(*((_QWORD *)this + 1) + 48i64) = *(_DWORD *)(*((_QWORD *)this + 1) + 56i64);
    *(_DWORD *)(*((_QWORD *)this + 1) + 60i64) = *(_DWORD *)(v16 + 28);
    *(_DWORD *)(*((_QWORD *)this + 1) + 52i64) = *(_DWORD *)(*((_QWORD *)this + 1) + 60i64);
    v21 = *((_QWORD *)this + 1);
  }
  if ( v13 + (_DWORD)v10 )
  {
    v22 = v13 + (unsigned int)v10;              // 复制的点数量
    do
    {
      v23 = (_DWORD *)*((_QWORD *)this + 1);
      v24 = *v20;
      if ( v23[12] > *v20 )                     // 大于20
      {
        v23[12] = v24;                          // this+48
      }
      else if ( v23[14] < v24 )
      {
        v23[14] = v24;
      }
      v25 = v20[1];                             // *(new+24)+4
      if ( v23[15] < v25 )
      {
        v23[15] = v25;
      }
      else if ( v23[13] > v25 )
      {
        v23[13] = v25;
      }
      v20 += 2;
      --v22;
    }
    while ( v22 );
    v21 = *((_QWORD *)this + 1);
  }
  v26 = *(_QWORD **)(v21 + 40);
  if ( v26 )
  {
    *v26 = v16;                                 // 申请的堆
    *(_QWORD *)(*((_QWORD *)this + 1) + 40i64) = v16;
  }
  else
  {
    *(_QWORD *)(v21 + 40) = v16;                // 保存堆
    *(_QWORD *)(*((_QWORD *)this + 1) + 32i64) = v16;
  }
  *((_QWORD *)v9 + 1) = v16 + 8 * (*(unsigned int *)(v16 + 20) + 3i64);// 复制的大小
  return 1i64;
}

 

标签:__,逆向,int,v10,v16,QWORD,内核,NtGdiPolyPolyDraw,DWORD
来源: https://www.cnblogs.com/feizianquan/p/16147315.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有