2012-02-11 61 views
1

我从来没有做过任何C++/COM工作,所以我试图劫持现有的解决方案,并将其改变为我的需要。该项目是用VC 6编写和成功编译的,现在我正试图在2010年使用它。我必须更改几个引用才能编译它,但由于某种原因,我生成的dll会导致异常我的系统(原始工作正常)。对错误进行一些研究,看起来好像我在尝试声明char数组时发生缓冲区溢出。当声明char阵列时缓冲区溢出

bool CFile::simpleWrite(char* cData) 
{ 
    try{ 

     // temp result variable 
     BOOL bResult = 0; 

     // file handle 
     HANDLE hFile = INVALID_HANDLE_VALUE; 

     // get the CMain singleton 
     CMain* m_pMain = CMain::GetInstance(); 

     // this point gets synchronization to ensure we get unique file name... 
     char cDirFilename[MAX_PATH + 1]; 
     GetLogFileName(cDirFilename, MAX_PATH); 

     // sanity check 
     if(strcmp(cDirFilename, "c:\\") == 0) assert(0); 

     // try and create a file 
     hFile = CreateFile(cDirFilename, GENERIC_WRITE, FILE_SHARE_READ,NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

     // if have a good file handle 
     if(hFile != INVALID_HANDLE_VALUE){ 

      size_t lenFileData = strlen(cData) + 72; 
      char* cFileData = new char[lenFileData]; 
      _snprintf(cFileData, lenFileData, "<?xml version=\"1.0\"?>\r\n<RootElement>\r\n%s</RootElement>\r\n\0", cData); 
... 

这里是cData的声明/赋值(调用方法中的cXML)。

char cXML[EVENT_LOG_MAX_MESSAGE]; 
// get the CMain singleton 
CMain* pMain = CMain::GetInstance(); 

long lThreadID = GetCurrentThreadId(); 

// put the parameters into XML format 
pMain->BuildXML(cXML, EVENT_LOG_MAX_MESSAGE,errLogLevel,userActivityID,methodName,lineNumber,className,AppID,errorDescription,errorID,lThreadID); 

// write the data to file 
if(!simpleWrite(cXML)) 
... 

BuildXML正在做一个_snprintf到cXML并返回它。

这是从我的电话到一些VC文件的堆栈跟踪。

Test.dll!_heap_alloc_base(unsigned int size) Line 55 C 
Test.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 431 + 0x9 bytes C++ 
Test.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 239 + 0x19 bytes C++ 
Test.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine) Line 302 + 0x1d bytes C++ 
Test.dll!malloc(unsigned int nSize) Line 56 + 0x15 bytes C++ 
Test.dll!operator new(unsigned int size) Line 59 + 0x9 bytes C++ 
Test.dll!operator new[](unsigned int count) Line 6 + 0x9 bytes C++ 
Test.dll!CFile::simpleWrite(char * cData) Line 87 + 0xc bytes C++ 

我确定有一些愚蠢的基本错误,但我似乎无法弄清楚。

+0

你能提供更多关于'cData'的信息吗? – 2012-02-11 21:06:07

+1

72是英文数字。程序员使用256.代码片段当然完全没有意义。 – 2012-02-11 21:45:33

+0

我添加了一些关于cData的更多细节,但只是想提醒一下,这个项目编译并运行良好,当它内置在VS 6中时。此代码已使用了好几年,并且自2007年以来一直未修改。 – JStinebaugh 2012-02-12 02:04:48

回答

0

您的错误很可能是最终破坏堆的其他地方。我注意到你在这里使用strlen而不添加一个用于终止零。看看你的代码,看看你是否使用strlen来分配内存并在某处进行复制,因为我认为你通过分配一个字节太少来破坏堆,然后对它进行strcpy'ing。

+1

有一个想法;看看你在哪里分配cData并复制到它。你是否有机会做cData = new char [strlen(oldString)]; strcpy(cData,oldString)? 这将导致堆损坏,因为终止0将覆盖缓冲区的末尾。 – Tobias 2012-02-11 21:36:39

0

正如我所怀疑的,这完全是我自己的愚蠢。这个COM应用程序有一个我不知道的依赖关系。从来没有看到任何试图在进程监视器中查找它的东西,并且该项目显然具有用于编译目的的文件的本地副本。感谢您的输入。