近日发现PPStream在播放MP3文件格式存在缓冲区溢出,
原因在于PPStream在播放MP3文件时会自动构造lrc文件路径,查找其对应歌词文件。
溢出出现在构造lrc文件时,没有对缓冲区大小进行检查,故过长的文件名会造成溢出。

该文件会出现在在播放列表中。
跟踪到列表文件为C:\Documents and Settings\Administrator\Application Data\PPStream\MediaList\PlayList\默认播放列表.XML

代码:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Medias>
<PLF Name="123.mp3" NamePinYin="123.mp3" ExtName=".mp3" Duration="4:43" FileSize="2269530">
C:\Documents and Settings\Administrator\桌面\123.mp3</PLF>
</Medias>
</Root>
可以看到这里可以修改文件名任意长度,但在拼组歌词路径时,并非根据此处的文件名来操作的,而且程序会检查文件的有效性,
所以只能利用windows的MAX_PATH bytes。

函数代码很多且多为不相关内容,只贴关键了,看起来方便。

代码:
具体代码如下:
.text:1005D0DC                 lea     eax, [ebp+strLrcName]
.text:1005D0E2                 push    offset aLrcS_lrc   ; "\\lrc\\%s.lrc"
.text:1005D0E7                 push    eax             ; int
.text:1005D0E8                 call    Cstring::Format    ; 拼组lrc文件名

构造结果为"\\lrc\\%s.lrc,下面会拼组lrc的绝对路径。

.text:1005D11A                 mov     ebx, [ebp+strLrcName]
.text:1005D120                 lea     eax, [ebp+FileName]
.text:1005D126                 push    ebx      ; char *
.text:1005D127                 push    eax      ; char *
.text:1005D128                 call    _strcat    ; strcat,这里拼组lrc的绝对路径,没有检查目的缓冲区大小,发生了溢出.

溢出之前ESP的情况:
…
…
0012FC74  |0250C1C0
0012FC78  |0000000E
0012FC7C  |7E822871  // 这里有个key
0012FC80  |0012FCAC  Pointer to next SEH record
0012FC84  |100DE65F  SE handler
0012FC88  |00000007
0012FC8C  |0012FCB8
0012FC90  |10065F21  RETURN to POWERP~1.10065F21 from POWERP~1.1005CBEF    // 函数返回地址
0012FC94  |01C34DA8

溢出之后ESP的情况:
…
…
0012FC74   41414141
0012FC78   41414141
0012FC7C   41414141   // 把key给覆盖掉了
0012FC80   41414141  Pointer to next SEH record
0012FC84   41414141  SE handler
0012FC88   41414141
0012FC8C   41414141
0012FC90   41414141    // 原返回地址
0012FC94   41414141


如果覆盖至返回地址,在函数返回之前检查cookie时会出错。
1005D1C9  |.  8B4D F4       mov ecx,dword ptr ss:[ebp-C]            
1005D1CC  |.  5F            pop edi
1005D1CD  |.  5E            pop esi
1005D1CE  |.  64:890D 00000>mov dword ptr fs:[0],ecx
1005D1D5  |.  8B4D F0       mov ecx,dword ptr ss:[ebp-10]
1005D1D8  |.  5B            pop ebx
1005D1D9  |.  E8 E1220500   call 100AF4BF                            ;  Check
1005D1DE  |.  C9            leave
1005D1DF  \.  C3            retn
        所以我想到的是覆盖到SEH或者coockie之前,然后观察程序是否有异常产生,结果失败。
        本人刚刚学习,了解的很少,所以将东西贴出来,如果有大侠指点那是再好不过了。