找了好久才发现这个环境比较容易搭建分析...html
signed int __stdcall sub_7D0706CC(int src_addr, unsigned int count, int a3) { signed int result; // eax@2 int v4; // eax@3 unsigned __int8 v5; // al@3 unsigned int v6; // ebx@7 int v7; // ecx@7 int v8; // ST00_4@7 unsigned int v9; // eax@7 signed int v10; // eax@10 if ( *(_BYTE *)(src_addr + 10) & 0x20 ) { v4 = (*(_BYTE *)(src_addr + 6) + ((*(_BYTE *)(src_addr + 5) + (*(_BYTE *)(src_addr + 4) << 8)) << 8)) & 0xFFF; *(_DWORD *)a3 = (*(_BYTE *)(src_addr + 6) + ((*(_BYTE *)(src_addr + 5) + ((unsigned int)*(_BYTE *)(src_addr + 4) << 8)) << 8)) >> 12; *(_DWORD *)(a3 + 4) = v4; v5 = *(_BYTE *)(src_addr + 7); if ( (*(_BYTE *)(src_addr + 7) & 0xFu) > 8 ) v5 &= 0xF7u; if ( v5 & 0xF0 && v5 & 0xF ) { v6 = v5; v7 = v5 & 0xF; *(_QWORD *)(a3 + 16) = dword_7D0707F8[v7]; v8 = *(_DWORD *)(a3 + 16); *(_DWORD *)(a3 + 24) = dword_7D070838[v7]; *(_DWORD *)(a3 + 28) = MulDiv(v8, 9, 1000); v9 = (*(_BYTE *)(src_addr + 10) + ((*(_BYTE *)(src_addr + 9) + ((unsigned int)*(_BYTE *)(src_addr + 8) << 8)) << 8)) >> 6; *(_DWORD *)(a3 + 32) = v9; if ( v9 == 0x3FFFF ) *(_DWORD *)(a3 + 32) = 0; else *(_DWORD *)(a3 + 32) = 400 * v9; *(_DWORD *)(a3 + 40) = 2000; *(_DWORD *)(a3 + 36) = dword_7D070860[v6 >> 4]; v10 = (((unsigned int)*(_BYTE *)(src_addr + 11) >> 3) | 32 * (*(_BYTE *)(src_addr + 10) & 0x1F)) << 11; *(_DWORD *)(a3 + 8) = v10; if ( *(_BYTE *)(src_addr + 11) & 4 ) { if ( v10 > 40960 ) *(_DWORD *)(a3 + 8) = 40960; } *(_DWORD *)(a3 + 48) = count; //此处qmemcpy为出错指令,将src_addr处的内容复制count字节到堆中,觉得count未检查,致使溢出 //查看到此处src_addr的起始内容为0x000001B3 qmemcpy((void *)(a3 + 52), (const void *)src_addr, count); result = 1; } else { result = 0; } } else { result = 0; } return result; }
返回到x32dbg中调试到此函数上,发现src_addr处起始内容为0x000001B3,count为0x000000C3。数据结构
在poc.m2p文件中查找到“0x000001B3”,而且在“0x000001B3”偏移0xC3处后,内容为“0x00000100”,此时咱们并不知道这个十六进制序列有什么特殊含义,暂且看作一个开端标志。以后Google MPEG-2数据结构,发现“0x000001B3”为Video Sequence的起始标志,“0x00000100”为Picture Header的起始标志,因此此函数的功能就是将Video Sequence到Picture Header之间的内容复制到堆中,由于堆中空间不够,而致使的溢出错误。ide
最后咱们探究一下溢出的精确长度复制前的堆起始地址为0x027A6F64,出错时为0x027A7000,0x027A7000-0x027A6F64=0x9C,因此此处分配的堆空间大小为0x9C字节,而咱们实际复制的内容有0xC3字节,超出全部空间,致使溢出错误。函数