vc6 ado执行缓冲区溢出

时间:2014-02-14 19:11:32

标签: visual-c++ ado buffer-overflow vc6

所以我在生产中遇到了一个问题,似乎是通过Service Pack升级暴露出来的。它似乎是ado _ConnectionPtr对象的Execute方法中的某种缓冲区溢出。以下代码产生缓冲区溢出:

char szStatement[600];
sprintf(szStatement, "UPDATE ROUTING_MASTER SET CNTNR_WGT_EST = %g WHERE CNTNR_ID = '%s'", 
                         spLineItem->CntnrItemsWeight, (LPCTSTR) spLineItem->ContainerID);

m_spCN->Execute(szStatement,&var,adCmdText);

在execute方法之后,它会遍历我的一个成员变量(_bstr_t),下次应用程序尝试访问被践踏的成员变量时,它会抛出异常。我可以告诉它被践踏,因为我在监视窗口中有我的成员变量,并且在Execute方法完成后立即看到成员变量已经改变(m_bstrDate):

enter image description here

var在头文件中声明为:

variant_t var;
BOOL m_bUseStorePutCntnr;
_bstr_t m_bstrDate, m_bstrTime;

似乎对& var的赋值正是这样做的,因为如果我将其更改为以下内容则不会践踏我的成员变量:

m_spCN->Execute(szStatement, NULL, adCmdText);

我不确定这是否与Service Pack有关,因为我在我的开发环境中也看到了这一点,而visual studio在下次必须访问该成员变量时会继续运行。

知道为什么会导致缓冲区溢出?

1 个答案:

答案 0 :(得分:0)

我没有使用ADO环境设置的Visual C / C ++ v6.0,因此我无法验证下面写的任何内容。

但很明显,使用Execute方法的第二个参数传递的保留内存块的地址不够大。

我在MSDN中找不到类_ConnectionPtr,也没有找到此类的方法Execute。但我找到了页面ADO interface _ConnectionPtr。根据此页面,方法Execute的原型是:

_RecordsetPtr Connection :: Execute (_bstr_t CommandText, VARIANT * RecordsAffected, long Options)

所以第二个参数是指向结构VARIANT的指针。

但是您已将成员变量var定义为类variant_t的对象,该对象封装了 VARIANT 结构。

我100%认为结构 VARIANT 的大小与类 variant_t 的大小不同。

您应该可以通过插入代码来验证:

TRACE("Size of VARIANT is %u and size of variant_t is %u\n",sizeof(VARIANT),sizeof(variant_t));

我的结论:

您将错误的对象传递给方法Execute

您的应用程序应该可以使用 VARIANT 替换头文件 variant_t ,并且可能使用

清除结构的所有字节
memset(&var,0,sizeof(var));

在调用方法Execute之前,虽然我非常确定这不是真的需要。

如果您想另外使用 variant_t 类,您还必须定义 VARIANT 结构并将其附加到 variant_t 对象。< / p>

这意味着你需要在头文件中:

VARIANT var;
variant_t RecordsAffected;

在源文件中:

memset(&var,0,sizeof(var));   // Most likely not really needed.
m_spCN->Execute(szStatement,&var,adCmdText);
RecordsAffected.Attach(&var);

如果我在代码片段上犯了错误,请告诉我,我根本无法测试,以及我的答案中的任何其他错误信息。