用啥软件来查看一个用Microsoft Visual C++ 6.0 编写的程序的源代码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用啥软件来查看一个用Microsoft Visual C++ 6.0 编写的程序的源代码相关的知识,希望对你有一定的参考价值。
现在软件是exe的 我要怎么打开去源代码,去修改里面的代码,有什么软件
能不能提供个下载地址 谢谢了
作 者: 北斗之摇光
时 间: 2007-03-15 17:14
链 接: http://bbs.pediy.com/showthread.php?t=41087
详细信息:
【文章标题】: MFC逆向初级研究(1)
【文章作者】: 北斗之摇光
【作者邮箱】: hardlywhen@hotmail.com
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
引言
本文主要针对微软的VC++6.0中使用MFC产生的EXE文件的逆向研究,我曾经使用微软的Visual Studio 2005编译了一
个EXE文件,通过IDA反汇编以后发现该文件与VC++6.0产生的文件还是有所区别,因此特别在此声明一下。文中主要使用了I
DA pro 5.0和在看雪(www.pediy.com)下载的OllyICE作为工具对目标文件进行反汇编。在此也感谢看雪论坛的各位的无私奉
献,在研究过程的中的困难多通过各位的帖子得到了帮助。
逆向的关键
我认为逆向的关键主要是要弄明白目标文件的算法和实现过程,在Window操作系统下,软件的实现过程就体现在其
对Window消息的处理,而软件的算法则包含在处理的具体过程中。对于通过SDK编写的"传统"的Windows应用程序基本都具备
几个共同的特征:WinMain函数、WinProc函数、窗口注册、消息循环。对于这类目标文件的分析主要集中的WinProc的分析上
,WinProc的函数地址获得一般是通过窗口注册函数中的参数获得。(由于我对于这类文件没有具体逆向过,所以只是大概的
说说,有不对的地方请各位不要客气,尽管拍砖)
而使用MFC(Microsoft Function Class)顾名思义,该类库主要封装了大部分的Windows API函数所以在代码中看
不到原本的SDK编程中的消息循环、窗口过程函数等等东西,所有这些封装在相应的mfcxx.dll中,让程序员能够专著与处理
过程与算法。这种做法于逆向而言有好处也有坏处:
坏处就是加大了对于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:
Win32
Classes to be created:
Application: CFffApp in ReverseMFC.h and ReverseMFC.cpp
Dialog: CFffDlg in ReverseMFCDlg.h and ReverseMFCDlg.cpp
Features:
+ Uses shared DLL implementation (MFC42.DLL)
+ Localizable text in:
中文[中国]
直接编译以后就能够运行,为了确定我们是否正确的分析的整个目标文件,在该对话框中加入一个我们自定义的按钮如
下,对于该按钮的处理函数如下设定为:
AfxMessageBox("I find it!",MB_OK);编译后就得到了我们需要的目标文件。
现在我们得到了所需要的目标文件,在IDA中载入该文件。在此我们最好是产生Release版本的EXE文件,毕竟所有的发
布软件都是Release版本的。
2.具体分析
在IDA中按Ctrl+S找到.rdata段,该段主要存储了目标文件的类运行时创建信息、MessageMap信息、MessageEntry信息、
虚函数表、RTTI数据(如果编译选项中选择了支持RTTI的话)。
在到达.rdata段后我们可以看到这样的代码,对数据进行格式转换后可以得到如下图所示的数据。
.rdata:004021C0 ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?
.rdata:004021C0
.rdata:004021C0 ; Segment type: Pure data
.rdata:004021C0 ; Segment permissions: Read
.rdata:004021C0 _rdata segment para public 'DATA' use32
.rdata:004021C0 assume cs:_rdata
.rdata:004021C0 ;org 4021C0h
.rdata:004021C0 off_4021C0 dd offset sub_401000 ; DATA XREF: sub_401010o
.rdata:004021C4 dd offset dword_4021C8
.rdata:004021C8 dword_4021C8 dd 111h ; DATA XREF: .rdata:004021C4o
.rdata:004021CC dd 0
.rdata:004021D0 dd 0E146h
.rdata:004021D4 dd 0E146h
.rdata:004021D8 dd 0Ch
.rdata:004021DC dd offset CWinApp::OnHelp(void)
.rdata:004021E0 dd 0
.rdata:004021E4 dd 0
.rdata:004021E8 dd 0
.rdata:004021EC dd 0
.rdata:004021F0 dd 0
.rdata:004021F4 dd 0
.rdata:004021F8 off_4021F8 dd offset CWinApp::GetRuntimeClass(void)
.rdata:004021F8 ; DATA XREF: unknown_libname_1-56o
.rdata:004021FC dd offset sub_401040
.rdata:00402200 dd offset nullsub_2
.rdata:00402204 dd offset nullsub_3
.rdata:00402208 dd offset nullsub_2
.rdata:0040220C 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 message
UINT nCode; // control code or WM_NOTIFY code
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT 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 _AFXDLL
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
#else
const AFX_MSGMAP* pBaseMap;
#endif
const AFX_MSGMAP_ENTRY* lpEntries;
;
off_4021C0的两个数据中第二个数据恰恰就是我们前面假设为MessageEntry的指针,跟入其第一个数据,我们看到如下的代
码:
.text:00401000 ; *************** S U B R O U T I N E ***************************************
.text:00401000
.text:00401000
.text:00401000 sub_401000 proc near ; DATA XREF: .rdata:off_4021C0o
.text:00401000 mov eax, ds:AFX_MSGMAP const CWinApp::messageMap
.text:00401005 retn
.text:00401005
.text:00401005 sub_401000 endp
恰恰是一个返回基类的MessageMap的函数。因此我们也同样有理由假设"off_4021C0就是一个MessageMap数据"。
对于虚函数表的假设是如何被证明呢?首先我们要知道关于虚函数表的一点知识:虚函数表由虚函数的地址组成,表中函数
地址的顺序和它们第一次出现的顺序(即在类定义的顺序)一致。若有重载的函数,则替换掉基类函数的地址。通过这个我
们可以知道MFC中虚函数表中的函数顺序必然是先按照CObject->CCmdtarget->。。。。这个类继承顺序中的虚函数顺序来处
理虚函数表中的函数顺序的。只要证明这个我们"假设的虚函数"中的函数顺序与上面提到的知识相符合则有理由说明我们的
假设成立。
首先来看CObject中虚函数的顺序,在查看CObject的声明文件后得到了这个类的虚函数顺序:
virtual CRuntimeClass* GetRuntimeClass() const;
virtual ~CObject(); // virtual destructors are necessary
virtual void Serialize(CArchive& ar);
#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
virtual 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 released
virtual void OnFinalRelease();
#endif
#ifndef _AFX_NO_OLE_SUPPORT
// called before dispatching to an automation handler function
virtual 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虚函数的位置上跟入后,可以得到如下代码:
.text:00401010 ; *************** S U B R O U T I N E ***************************************
.text:00401010
.text:00401010
.text:00401010 sub_401010 proc near ; DATA XREF: .rdata:00402228o
.text:00401010 mov eax, offset off_4021C0
.text:00401015 retn
.text:00401015
.text:00401015 sub_401010 endp
恰恰是返回了我们之前假设的MessageMap的地址。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢! 参考技术A 基本不大可能,exe程序是编译后的2进制代码,编译器在编译过程中已经优化和去除了很多信息,很难反编译得到原始的cpp代码。要是都让你查看到了原代码,那人家还怎么赚钱啊!O(∩_∩)O~
给你推荐一个最好的方法,去找程序作者要代码吧 .
如果真的想的话步骤如下:
首先,看这个exe文件是否加壳了,如果这个exe加壳了,你要先去壳.
其次,反编译到汇编语言.
最后,编译生成c++代码.
但是这样做是很费时费力的事情,同时也不一定就能够成功的呢~~~ 所以,一般而言,你还是不要想的啦。。。。。 参考技术B 用这个软件编写的 当然是用这个VC6.0软件打开了 在迅雷上找找 肯定有的 也可以用EVC4 VS2005本回答被提问者采纳 参考技术C 我没理解错误的话你是想改EXE文件的源码吧?这是不可能完成的任务! 参考技术D 我觉得楼主十分可爱,有前途。
bin文件用啥软件打开
bin文件用什么软件打开
bin文件打开方法如下:1、首先打开此电脑,点击查看,勾选文件扩展名。
2、右键点击bin文件,选择重命名,修改文件后缀,尝试txt、jpg、zip、pdf等常见格式。
3、系统提示改变扩展名可能导致文件不可用,点击是,然后打开文件,如果不能打开或打开为乱码,代表未找到正确格式。
4、继续修改后缀名称尝试打开,当后缀正确时即可打开。 参考技术A
bin文件是由来自不同公司的磁盘映像开发和编辑应用中创建的磁盘镜像文件。这些文件的内容是二进制形式,从一个磁盘,这个输出文件复制。可以包括图片、游戏、音频甚至是编程器用来刷芯片(ROM)的内容。
工具/材料:Notepad++、bin文件。
1、首先在桌面上,选中“bin文件”快捷方式。
2、再者在桌面上,右键选择“打开”选项。
3、接着在该界面上,选中“Notepad++”程序。
4、再者在该界面上,点击“确定”。
5、最后在“Notepad++”界面上,展示bin文件内容。
参考技术B bin二进制文件,其用途依系统或应用而定
。
也就是说,一般来讲是机器代码,汇编语言编译后的结果,(DOS下汇编语言编译后与.com文件相类似),用debug、WINHEX,U_EDIT等软件打开(通常不一定能看得懂是些什么除非精通汇编语言)
所有的文件,
无论后缀名是什么,
一律分为两种格式.
text
和
binary.
一种文件格式binary的缩写。一个后缀名为.bin的文件,
只是想表明它是binary格式.,但并不表明它与某种应用程序有必然的联系性.
。
比如虚拟光驱文件常用.bin作为后缀,但并不意味着所有.bin文件都是虚拟光驱文件。
Linux下安装BIN文件的方法:
1.先赋予权限:
chmod
777
*.bin
2.开始安装:
./*.bin
(注意
我在前面加上了两个字符)
好了
剩下的就和Windows一样了
XP下运行BIN文件的方法:
1、首先用notepad(记事本)打开后缀名为CUE的文件,其内有后缀名为BIN的文件的文件名;
2、然后将后缀名为BIN文件的文件名更改成CUE文件中指名的文件名;
3、下载Daemon
Tools(虚拟光驱)安装,即可打开。
虚拟光盘文件常用.bin作为后缀,
但并不意味着所有.bin文件都是虚拟光盘.
如果你的daemon无法正常安装它.
说明它很可能不是虚拟光盘.
另外在软件的安装后文件夹中大部分软件或服务器软件都有个
bin
文件夹
因为
bin
(binary)其中文意思既是:二进制
里面存放的一般是可执行的二进制文件,所以我们通常使用较大型的软件时都会发现有这个名称的文件夹, 参考技术C 要知道你是在什么地方看到或获取的文件,例如: 1 如果是在一个程序的安装目录中,则一般属于该程序的数据文件,用户无法直接打开; 2 如果是下载的BIOS升级程序,则BIN文件就是BIOS的更新数据,使用更新程序指定该文件即可 3 如果是很大的文件,也有可能是虚拟光驱的光盘镜像文件,可以用DAEMON TOOLS等程序虚拟成光驱 …… 参考文献:英雄不问出身 文件必须问出处本回答被提问者采纳 参考技术D 首先: 为了确定“.bin”文件是否真的是PE光盘镜像文件。 在这个文件上点击鼠标右键--->选择用记事本程序打开。 注意:如果本来此文件就有几百M,请不要用记事板打开测试这个文件! 如果打开后是乱码!则证明这个文件可能就是PE光盘镜像文件!
以上是关于用啥软件来查看一个用Microsoft Visual C++ 6.0 编写的程序的源代码的主要内容,如果未能解决你的问题,请参考以下文章