文章編號:11115時間:2024-09-30人氣:
標 題: MFC逆向初級研究(1)作 者: 北斗之搖光時 間: 2007-03-15 17:14 鏈 接:詳細信息: 【文章標題】: MFC逆向初級研究(1)【文章作者】: 北斗之搖光【作者郵箱】: 【下載地址】: 自己搜索下載【作者聲明】: 只是感興趣,沒有其他目的。 失誤之處敬請諸位大俠賜教!--------------------------------------------------------------------------------【詳細過程】引言本文主要針對微軟的VC++6.0中使用MFC產生的EXE文件的逆向研究,我曾經使用微軟的Visual Studio 2005編譯了一個EXE文件,通過IDA反匯編以后發現該文件與VC++6.0產生的文件還是有所區別,因此特別在此聲明一下。 文中主要使用了IDA pro 5.0和在看雪()下載的OllyICE作為工具對目標文件進行反匯編。 在此也感謝看雪論壇的各位的無私奉獻,在研究過程的中的困難多通過各位的帖子得到了幫助。 逆向的關鍵我認為逆向的關鍵主要是要弄明白目標文件的算法和實現過程,在Window操作系統下,軟件的實現過程就體現在其對Window消息的處理,而軟件的算法則包含在處理的具體過程中。 對于通過SDK編寫的傳統的Windows應用程序基本都具備幾個共同的特征:WinMain函數、WinProc函數、窗口注冊、消息循環。 對于這類目標文件的分析主要集中的WinProc的分析上,WinProc的函數地址獲得一般是通過窗口注冊函數中的參數獲得。 (由于我對于這類文件沒有具體逆向過,所以只是大概的說說,有不對的地方請各位不要客氣,盡管拍磚)而使用MFC(Microsoft Function Class)顧名思義,該類庫主要封裝了大部分的Windows API函數所以在代碼中看不到原本的SDK編程中的消息循環、窗口過程函數等等東西,所有這些封裝在相應的中,讓程序員能夠專著與處理過程與算法。 這種做法于逆向而言有好處也有壞處:壞處就是加大了對于MFC產生的EXE文件的逆向難度,讓許多的和我一樣的菜鳥迷失在匯編代碼中找不找北了,基本主要就靠猜測實現過程中用到了那些函數,然后對文件導入表的函數下斷點來尋找我們所需要的處理過程;好處就是這樣的做法使得EXE文件中主要都是目標程序的Window消息處理流程以及算法,而且dll中的大部分函數的功能都能在MSDN中查到。 如果能夠通過對目標文件的分析得到這個Window消息處理流程和算法架構,基本上我們就可以重寫整個軟件;要做到上面的目標,首先我們要對MFC有所了解,推薦沒有基礎的兄弟們讀讀候俊杰的《深入淺出MFC》。 該書在逆向過程中完全可以作為一本參考書,讓你能通過源代碼了解實現過程,網上有很多該書的電子版下載。 一個逆向MFC產生的EXE文件的例子下面我們就通過一個具體的例子來學習一下如何從目標文件中挖到我們需要的東西。 首先我們來產生一個需要的EXE文件。 在此我假定各位對MFC有過一定的使用經驗,畢竟逆向分析才是本文的重點。 1.產生例子所需要的目標文件:我們通過VC++6.0的向導來產生一個名為ReverseMFC的工程,這個工程的設置情況如下: Application type of fff:Dialog-Based Application targeting:Win32Classes to be created:Application: CFffApp in ReverseMFC.h and : CFffDlg in ReverseMFCDlg.h and : + Uses shared DLL implementation () + Localizable Text in:中文[中國]直接編譯以后就能夠運行,為了確定我們是否正確的分析的整個目標文件,在該對話框中加入一個我們自定義的按鈕如下,對于該按鈕的處理函數如下設定為:AfxMessageBox(I find it!,MB_OK);編譯后就得到了我們需要的目標文件。 現在我們得到了所需要的目標文件,在IDA中載入該文件。 在此我們最好是產生Release版本的EXE文件,畢竟所有的發布軟件都是Release版本的。 2.具體分析在IDA中按Ctrl+S找到段,該段主要存儲了目標文件的類運行時創建信息、MessageMap信息、MessageEntry信息、虛函數表、RTTI數據(如果編譯選項中選擇了支持RTTI的話)。 在到達段后我們可以看到這樣的代碼,對數據進行格式轉換后可以得到如下圖所示的數據。 C0 ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?C0 ; Segment type: Pure C0 ; Segment permissions: C0 _rdatasegment para public DATA C0 assume cs:_C0 ;org C0 off_4021C0dd offset sub_; DATA XREF: sub_C4 dd offset dword_C8 dword_4021C8dd 111h ; DATA XREF: C4CC dd D0 dd D4 dd D8 dd DC dd offset CWinApp::OnHelp(void)E0 dd E4 dd E8 dd EC dd F0 dd F4 dd F8 off_4021F8dd offset CWinApp::GetRuntimeClass(void)F8 ; DATA XREF: unknown_libname_1-56FC dd offset sub_ dd offset nullsub_ dd offset nullsub_ dd offset nullsub_C dd offset CCmdTarget::OnCmdMsg(uint,int,void *,AFX_CMDHANDLERINFO *)其中的off_4021C0就是一個MessageMap數據;dword_4021C8就是MessageMap所指的MessageEntry數據;off_4021F8就是一個類的虛函數表的開始位置。 那么具體這些數據時那個類的相關數據呢?如此判斷的依據是什么?首先我們知道MessageEntry是的數據結構定義如下,而且以6個0表示整個數組的結束。 struct AFX_MSGMAP_ENTRY{UINT nMessage; // windows messageUINT nCode;// control code or WM_NOTIFY codeUINT nID;// control ID (or 0 for windows messages)UINT nLastID;// used for entries specifying a range of control idsUINT nSig; // signature type (action) or pointer to message #AFX_PMSG pfn;// routine to call (or special value)};因此我們有理由假設dword_4021C8就是MessageMap所指的MessageEntry數據。 而MessageMap數據結構定義如下:struct AFX_MSGMAP{#ifdef _AFXDLLconst AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();#elseconst AFX_MSGMAP* pBaseMap;#endifconst AFX_MSGMAP_ENTRY* lpEntries;};off_4021C0的兩個數據中第二個數據恰恰就是我們前面假設為MessageEntry的指針,跟入其第一個數據,我們看到如下的代碼 ; *************** S U B R O U T I N E *************************************** sub_proc near ; DATA XREF: :off_4021C0 mov eax, ds:AFX_MSGMAP const sub_endp恰恰是一個返回基類的MessageMap的函數。 因此我們也同樣有理由假設off_4021C0就是一個MessageMap數據。 對于虛函數表的假設是如何被證明呢?首先我們要知道關于虛函數表的一點知識:虛函數表由虛函數的地址組成,表中函數地址的順序和它們第一次出現的順序(即在類定義的順序)一致。 若有重載的函數,則替換掉基類函數的地址。 通過這個我們可以知道MFC中虛函數表中的函數順序必然是先按照CObject->CCmdtarget->。 。 。 。 這個類繼承順序中的虛函數順序來處理虛函數表中的函數順序的。 只要證明這個我們假設的虛函數中的函數順序與上面提到的知識相符合則有理由說明我們的假設成立。 首先來看CObject中虛函數的順序,在查看CObject的聲明文件后得到了這個類的虛函數順序:virtual CRuntimeClass* GetRuntimeClass() const;virtual ~CObject();// virtual destructors are necessaryvirtual void Serialize(CArchive& ar);#if defined(_DEBUG) || defined(_AFXDLL)// Diagnostic Supportvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;再來查看CCmdtarget的虛函數順序,在查看CObject的聲明文件后得到了這個類的虛函數順序:DECLARE_DYNAMIC(CCmdTarget);virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo);#ifndef _AFX_NO_OLE_SUPPORT// called when last OLE reference is releasedvirtual void OnFinalRelease();#endif#ifndef _AFX_NO_OLE_SUPPORT// called before dispatching to an automation handler functionvirtual BOOL IsInvokeAllowed(DISPID dispid);virtual BOOL GetDispatchIID(IID* pIID);virtual UINT GetTypeInfoCount();virtual CTypeLibCache* GetTypeLibCache();virtual HRESULT GetTypeLib(LCID lcid, LPTYPELIB* ppTypeLib);之所以還要列出DECLARE_DYNAMIC(CCmdTarget);是因為這個宏的定義如下:#define DECLARE_DYNAMIC(class_name) \protected: \static CRuntimeClass* PASCAL _GetBaseClass(); \public: \static const AFX_DATA CRuntimeClass class##class_name; \virtual CRuntimeClass* GetRuntimeClass() const; \這個virtual CRuntimeClass* GetRuntimeClass() const; 覆蓋掉了一開始的CObject的相對應函數。 依次按照類的順序對照下來,就可以知道該表確實是虛函數表。 同時,對應的GetMessageMap虛函數的位置上跟入后,可以得到如下代碼 ; *************** S U B R O U T I N E *************************************** sub_proc near ; DATA XREF: mov eax, offset off_ sub_endp恰恰是返回了我們之前假設的MessageMap的地址。 --------------------------------------------------------------------------------【版權聲明】: 本文原創于看雪技術論壇, 轉載請注明作者并保持文章的完整, 謝謝!
VC6.0, VisualC++2010, Visual Studio的區別VC6.0,全稱Microsoft Visual C++ 6.0.三者的中,VC6最老,幾乎是上世紀90年代的玩意了。 超期服役到WindowsXP。 兼容性差。 Visual C++2010是一個運行時庫(Run time library),用于支持游戲等。 此外,Visual C++ 2010 Express是一款編譯器。 比VC+6.0要先進。 但是大部分人沒有用過。 Visual Studio, 全稱Microsoft Visual Studio。 是當今微軟提供的,最先進的編譯器。 最新版本VS2015可以編譯Windows 10應用程序。 Visual Studio當今(2016年7月28日)最新穩定版本為Microsoft Visual Studio 分為3個版本Visual StudioTeam Services 收費版本,適于團隊開發。 Visual Studio Community 面向60億人民群眾的免費開發工具Visual Studio Code重新定義了 Code 編輯。 編寫現代 Web 程序和云程序。 免費。 備注: *VC6最小最簡潔,只要十幾M。 而Visual Studio至少7個G. *VC6寫的程序可以從Windows XP 開到Win10. 而Visual Studio的程序需要運行時庫,否則會發生“Runtime Library Runtime Error”。 不能在WinXP運行。 當然你可以在編譯選項設置他們,但會增加程序體積.
Microsoft Visual C++ Redistributable Package是Visual C++的運行時組件和庫,很多軟件,尤其是游戲所必須的 Microsoft VC++ 的環境軟件,這些游戲就是用VC+編寫的,所以安裝很多大型游戲的時候,它也會幫你安裝這些軟件。
如果要卸載的話可以選擇9.0.0之前版本的Visual C++,因為此版本之前的庫絕大多數是為2010年之前的軟件提供API,若卸載了不會影響絕大多數近期更新的軟件,但是不否認有新軟件還需要的特例,所以只有在必須的時候才選擇卸載。
程序編譯版本不一樣需要的運行組件版本也不一樣,所以不建議刪除,但是刪除之后也可以到微軟的官網上下載,再次安裝。
Microsoft Visual C++,(簡稱Visual C++、MSVC、VC++或VC)是Microsoft公司推出的以C++語言為基礎的開發Windows環境程序,面向對象的可視化集成編程系統。
它不但具有程序框架自動生成、靈活方便的類管理、代碼編寫和界面設計集成交互操作、可開發多種程序等優點,而且通過的設置就可使其生成的程序框架支持數據庫接口、OLE2.0,WinSock網絡。
Microsoft Visual C++ 6.0,簡稱VC6.0,是微軟于1998年推出的一款C++編譯器,集成了MFC 6.0,包含標準版(Standard Edition)、專業版(Professional Edition)與企業版(Enterprise Edition)[2]。 發行至今一直被廣泛地用于大大小小的項目開發。
Microsoft Visual C++ 6.0對windows7和windows8的兼容性較差。 在Windows7使用VC6.0只需要忽略兼容性提示即可正常使用,但是在Windows8(含Windows8.1)使用VC6.0則需要改原文件名并改兼容性才能正常使用。
在Windows10的第一個版本也可以正常使用VC6.0,但Windows10系統升級更新后中文版VC6.0無法正常使用,提示“0xc”的錯誤,需要將原文件替換為英文版或者漢化版才能正常使用。
不同的地方很多,具體你可以看msdn上的vs2013的對于C++部分的改進。
我想你的VC++指的應該是VC6.0。
相比來說VC6.0太老了。
在VS2013里使用的是最新的標準,也有好多新的特性,也更安全。
本文檔介紹 Visual Studio 2013 中的 Visual C++ 中新增和增強的功能。
有關 Visual Studio 2013 中其他附加內容的信息,請參見 Visual Studio 2013 中的新增功能。
改進的 ISO C/C++ 標準支持 編譯器支持以下 ISO C++11 語言功能:函數模板的默認模板參數。
委托構造函數顯式轉換運算符。
初始值設定項列表和統一初始化。
原始字符串文本。
可變參數模板。
別名模板。
已刪除的函數。
非靜態數據成員初始值設定項 (NSDMI)。
默認的函數。
* 支持以下 ISO C99 語言功能:_Bool 復合文本。
指定的初始值設定項。
組合帶有代碼的聲明。
字符串文本轉換為可修改的值可通過使用新編譯器選項 /Zc:strictStrings 禁用。
在 C++98 中,已棄用從字符串文本轉換至 char *(和將寬字符串文本轉換為 wchar_t *)。
在 C++11 中,已將轉換完全移除。
雖然編譯器可以嚴格遵循該標準,但提供了 /Zc:strictStrings 選項,以便你控制轉換。
默認情況下,該選項是關閉的。
注意,當你在調試模式下使用此選項,STL 將無法編譯。
rvalue/lvalue 引用轉換。
通過 rvalue 引用,C++11 可清晰地區分 lvalue 和 rvalue。
過去,在特定強制轉換方案中,Visual C++ 編譯器不提供此功能。
已添加新編譯器選項(/Zc:rvalueCast),以使編譯器與 C++ 語言的工作文件相符,(請參見第 5.4 節,[]/1)。
未指定選項時,該默認行為與 Visual Studio 2012 中的相同。
說明* 默認功能下,不支持使用 =default 逐一請求成員移動構造函數和移動賦值運算符。
C99 庫為下列標頭中缺少的函數添加了聲明和實現:math.h、ctype.h、wctype.h、stdio.h、stdlib.h 和 wchar.h。
同樣添加的還有新標頭 complex.h、stdbool.h、fenv.h 和 inttypes.h,以及在這些新標頭中聲明的所有功能的實現。
還有新的 C++ 包裝器標頭(ccomplex、cfenv、cinttypes、ctgmath),并且更新了許多其他內容(ccomplex、cctype、clocale、cmath、cstdint、cstdio、cstring、cwchar和 cwctype)。
有關更多信息,請參見 Visual Studio 2013 中的 C99 庫支持。
標準模板庫支持 C++11 顯式轉換運算符、初始值設定項列表、范圍枚舉和 variadic 模板。
現在所有容器都支持 C++11 細化的元素要求。
支持這些 C++14 功能: “透明運算符函子”less<>、greater<>、plus<>、multiplies<> 等。
make_unique
因為VC6太經典,太成功了。 vc6很適合做底層,運行速度也很快。 相同的程序功能對比如下:1.高版本vs編譯的程序如果需要800M內存,20M磁盤空間,運行速度1秒的話,2.使用vc6可以將所需內存降到100M,磁盤空間降低到5M,運行速度<0.5秒。 3.安裝包你keyi 比較以下,vs動則x個G,vc6精簡版只有25M,即使完整版也只有200多M。 4.高版本vs增加了很多華麗的東西,為了減少編寫代碼的工作量,但是也阻斷了程序員了解操作系統底層。 這就好比使用現代化的工具蓋樓,【開發】速度加快了,但是不清楚大樓的組成成分。 而vc6則需要自己一磚一瓦地來蓋樓,開發者對每個零件都很清楚。 這就是為什么我們現代化的大樓只有70年的使用壽命,而北京紫禁城可以屹立數百年乃至上千年不倒。 建議題主看一下64k編程大賽的作品【國外的一個考驗編程者能力、技巧、運行優化 水平的大賽,參賽作品大小不能超過64K,還要呈現很多畫面內容】。 相信你會感到驚奇的。
內容聲明:
1、本站收錄的內容來源于大數據收集,版權歸原網站所有!
2、本站收錄的內容若侵害到您的利益,請聯系我們進行刪除處理!
3、本站不接受違法信息,如您發現違法內容,請聯系我們進行舉報處理!
4、本文地址:http://m.sycxjdsbhs.com/article/7eeeb21df83f690f6864.html,復制請保留版權鏈接!
概述在Python中,str.split,函數是一個強大的工具,用于根據指定的分隔符將字符串拆分為多個子字符串,它在字符串處理和數據解析等各種任務中非常有用,基礎語法str.split,函數的語法如下,str.split,sep=None,maxsplit=,1,sep,可選參數,指定分隔符,默認情況下,它將字符串按照空格字符拆分...。
技術教程 2024-09-28 17:42:10
為了確保應用程序在所有支持的方向下都能提供良好的用戶體驗,測試應用程序中的模擬器是至關重要的,模擬器模擬器是一種軟件工具,它可以模擬實際設備的行為,它允許開發人員在不擁有實際設備的情況下測試他們的應用程序,有很多不同的模擬器可用,每個模擬器都有自己的優點和缺點,以下是一些最流行的模擬器,Android模擬器iOS模擬器WindowsP...。
最新資訊 2024-09-25 20:16:28
鼠標跟蹤文字,激活閱讀體驗導言鼠標跟蹤文字,MTF,是一種數字文本技術,允許讀者在光標移動時突出顯示文本,這種交互式功能增強了閱讀體驗,讓文字仿佛具有生命,身臨其境,本文將探討MTF的功能和好處,并提供關閉它的方法,鼠標跟蹤文字的功能MTF的主要功能是通過光標運動來突出顯示文本,當讀者將光標懸停在單詞或句子上時,它會被高亮顯示,使其比...。
技術教程 2024-09-24 18:47:33
在網頁設計中,div,塊級元素,是用于創建和管理內容布局的基礎元素之一,它提供了一種靈活的方法來組織和顯示文本、圖像和交互式元素,當div的內容超過其可用空間時,需要使用滾動條來瀏覽內容樣式來實現滾動條,以下是如何實現水平和垂直滾動條,水平滾動條<,divstyle=overflow,x,scroll,>,<,p>,這...。
技術教程 2024-09-23 04:14:21
在當今快節奏的商業環境中,企業必須不斷尋找提高運營效率的方法,自動化流程是一個強大的工具,可以幫助企業節省時間、金錢并提高準確性,自動化的優勢節省時間,自動化流程可以幫助企業節省寶貴的時間,通過消除手動任務,企業可以將員工從繁瑣、重復性的任務中解放出來,從而專注于更重要的工作,節省金錢,自動化流程還可以幫助企業節省資金,通過減少對人員...。
互聯網資訊 2024-09-16 16:52:09
語法錯誤是計算機程序中的一種錯誤,它違反了編程語言的語法規則,語法錯誤會導致程序無法編譯或運行,并且會產生錯誤消息,語法錯誤通常很容易檢測到,可以通過仔細檢查程序中的代碼來發現,語法錯誤的常見類型缺少分號,分號是C、Java和Python等編程語言中語句結束的標志,如果缺少分號,程序將無法編譯或運行,括號不匹配,括號用于將代碼分組,如...。
互聯網資訊 2024-09-15 01:22:06
定義單選按鈕,又稱單選框,是一種用于在一組選項中只能選擇一個選項的控件,它通常由一個圓圈或方框以及一個標簽組成,標簽表示選項的詳細信息,特性互斥,同一組中的單選按鈕互斥,這意味著一次只能選擇一個選項,可見標簽,單選按鈕的標簽清晰可見,以便用戶能夠輕松識別選項,單擊激活,單選按鈕通過單擊激活,選中它將取消選中其他同組的單選按鈕,表單提交...。
最新資訊 2024-09-14 17:47:00
簡介RANK函數用于在指定范圍內對一組數據進行排名,并將排名結果返回為一個包含排名值的數組,它廣泛應用于數據分析、統計和排名系統中,可以幫助我們輕松地識別最大值、最小值或指定范圍內的相對位置,語法RANK函數的語法如下,RANK,number,range,[order],number,要進行排名的數字或單元格引用,range,要從中進...。
互聯網資訊 2024-09-12 12:50:02
PHP是一款開源的web開發語言,擁有一個龐大而活躍的社區,為PHP開發人員提供豐富的資源和支持,文檔PHP社區維護著大量的官方文檔,包括,語言手冊,全面介紹PHP語法、函數和類框架手冊,指導使用流行的PHP框架,如Laravel和Symfony擴展文檔,列出可用擴展及其用法這些文檔由PHP團隊維護,并不斷更新,以反映語言和框架的最新...。
技術教程 2024-09-12 02:27:23
Java是一種廣泛使用的高級編程語言,用于開發各種應用程序,從桌面軟件到移動應用程序,它是現代編程中的基石,擁有龐大的開發者社區和大量的資源,黑馬Java培訓優勢系統化學習,黑馬的Java課程按照循序漸進的順序設計,涵蓋了Java編程的基礎知識到高級概念,實戰項目驅動,您將通過動手實踐項目掌握Java技術,解決實際問題并構建自己的應用...。
互聯網資訊 2024-09-11 11:40:19
深入剖析、實戰案例、專家建議Windows網絡編程一直是一個復雜且具有挑戰性的話題,但是,有了正確的指導,即使是最復雜的任務也能變得容易掌握,這就是,Windows網絡編程權威指南,誕生的原因,這本書由Windows網絡編程專家撰寫,提供了對Windows網絡編程的全面而深入的介紹,它涵蓋了從基礎概念到高級技術的所有內容,包括,Win...。
本站公告 2024-09-10 12:03:16
引言多線程編程是Java編程的重要組成部分,它允許程序同時執行多個任務,通過利用多線程,開發人員可以顯著提高應用程序的性能和響應能力,Java多線程的實現方式在Java中,可以通過以下方式創建和管理線程,實現Runnable接口,創建一個實現Runnable接口的類,該接口包含一個run,方法,該方法定義了線程執行的任務,擴展Thr...。
最新資訊 2024-09-06 10:03:26