缓冲区溢出与无限循环

先上代码。

#define KEYVALUE_MAX_SIZE	512

HRESULT HvGetNonGreedyMatchBetweenBeginLabelAndEndLabel(const CHAR* szBeginLabel,const  CHAR* szEndLabel,const  CHAR* pszRetMsg, INT nRetMsgLen, CHAR* szJieQuReslut, INT nReslutLen )
{
	if ( NULL == szBeginLabel || NULL == szEndLabel || NULL == pszRetMsg || NULL == szJieQuReslut)
	{
		WrightLogEx("testIP" , "HvGetNonGreedyMatchBetweenBeginLabelAndEndLabel   point is NULL");
		return E_FAIL;
	}
	memset(szJieQuReslut, 0, nReslutLen);
	const char* pBegin = strstr( pszRetMsg , szBeginLabel );
	if (pBegin!=NULL)
	{
		pBegin+=strlen(szBeginLabel);
	}
	else
	{
		WrightLogEx("testIP" , "HvGetNonGreedyMatchBetweenBeginLabelAndEndLabel   can not find begin Label");
		return E_FAIL;
	}
	const char* pEnd=strstr(pBegin, szEndLabel);
	if ( NULL != pEnd )
	{
		if (pEnd - pBegin >= nReslutLen)
		{
			WrightLogEx("testIP" , "HvGetNonGreedyMatchBetweenBeginLabelAndEndLabel   can not find end Label");
			return E_FAIL;
		}
		memcpy( szJieQuReslut ,pBegin , pEnd-pBegin );
		return S_OK;
	}	
	return E_FAIL;
}
												
		
//无限循环的for循环。										
for (int i = 0; i < g_XmlCmdAppendInfoMap[iCmdIndex].iParamNum; i++)
{
	char szBeginLabel[128];
	char szEndLabel[128];	
	char szResult[128]={0};
	sprintf(szBeginLabel,"%s=[", *(&(g_XmlCmdAppendInfoMap[iCmdIndex].szParamName1) + i) );
	strcpy(szEndLabel, "]");
	if( S_OK == HvGetNonGreedyMatchBetweenBeginLabelAndEndLabel(szBeginLabel, szEndLabel, pszRetMsg, strlen(pszRetMsg), szResult, KEYVALUE_MAX_SIZE))
	{
		pElementRet->SetAttribute(
			*(&(g_XmlCmdAppendInfoMap[iCmdIndex].szParamName1) + i),//这里有个地址偏移访问,让属性位置想后移动
			szResult);
	}
	else
	{
		pElementRet->SetAttribute(
			*(&(g_XmlCmdAppendInfoMap[iCmdIndex].szParamName1) + i),//这里有个地址偏移访问,让属性位置想后移动
			"");
	}
}

why

今天为了扩充xml私有协议的字符串大小,把KEYVALUE_MAX_SIZE 宏由128改成512。

然后发现程序陷入一个函数里,永远没有返回的样子。

然后多次按alt + ctrl + break,一直断在一个for循环里面。然后跟进去单步调试,发现循环迭代子i,每次循环都是0,就一直在循环体出不来了。

然后围观上下文,发现蹊跷的地方在:

<pre name="code" class="cpp">HvGetNonGreedyMatchBetweenBeginLabelAndEndLabel函数的

 
memset(szJieQuReslut, 0, nReslutLen);,第一个可能越界的地方
<pre name="code" class="cpp">memcpy( szJieQuReslut ,pBegin , pEnd-pBegin );第二个可能越界的地方。
 尼玛,把szResult缓冲区越界清0了。 



注意下不安全的赋值。

另外私有协议传长的字符串,不应该走xml路线,然后又用固定长度的buf解析。最好直接走二进制。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值