一个小型VC项目的开发

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情


2004年2月到7月,我们用VC6.0开发了一个小型项目。下面整理一下主要技术,希望各位同仁批评指正。

一、键盘挂钩程序

       在此之前,我做了一个键盘记录程序。是参考《编程技巧与维护》某一期的一片文章写的。使用了全局Hook技术,程序由keyexe.exe和keydll.dll两个文件组成,功能就是简单地记录击键字符和每次被激活窗口的标题及IE地址栏内容,存放到一个文件中,后来又增加了两个功能:在密码编辑框中有字符输入的时候,把屏幕截取下来,同时提示这是密码。
         Windows的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种反调函数(HOOK)的功能。这种挂接函数类似扩充中断驱动,系统产生的各种消息首先被送到各种挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交换控制权或将消息传递给下一个挂接函数以致最终达到窗口函数。WINDOWS系统的这种反调函数挂接方法虽然会略加影响到系统的运行效率,但在很多场合下是非常有用的。
         挂接函数可以是用来监控所有线程消息的全局性函数,也可以是单独监控某一线程的局部性函数。如果挂接函数是局部函数,可以将它放到一个.DLL动态链接库中,也可以放在一个局部模块中;如果挂接函数是全局的,那么必须将其放在一个.DLL 动态链接库中。
        在这个程序中,挂接了三种过滤函数:WH_CBT、WH_KEYBOARD 、WH_GETMESSAGE,实现的功能分别是:记录被激活的窗口标题,如果窗口类名是IE...则用FindWindowEx得到URL;记录击键字符;标记密码框的输入。
        上面提到过,keydll.dll要于用户在密码框中有输入时把整个屏幕截取下来。这个功能的实现,我是直接去网上寻找源代码,略加修改,使抓取的位图每个像素只有一个字节的数据。
        这就是我的程序的第一个版本。
        我写程序的时候,遇到一些问题就去网上找现成的源代码,懒得自己去钻研。问题解决了也很少再去分析这些源代码的原理。以至于

        我总是怀疑自己,虽然写了这么多程序,但真正属于自己的有多少呢?

二、进程隐藏

        我要使这个键盘记录函数在Windows2000的进程管理器中不可见,于是就用到了进程隐藏技术。
        Windows98下,只要把进程注册为系统服务,就达到了进程隐藏的目的,但在Windows2000下,问题变得比较麻烦。

 1、远程线程嵌入技术
        在Windows2000下隐藏进程,一种方法是远程线程技术。远程线程技术指的是通过在另一个运行的进程中创建远程线程的方法进入那个线程的内存地址空间。我们知道,在进程中,可以通过CreateThread函数创建线程,被创建的新线程与主线程(就是进程创建时被同时自动建立的那个线程)共享地址空间以及其他的资源。但是很少有人知道,通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程(注意:是远程进程!)的地址空间,所以,实际上,我们通过创建一个远程线程,进入了远程进程的内存地址空间,也就拥有了那个远程进程相当多的权限,例如启动一个dll线程,实际上我们可以随意篡改那个进程的数据。     

这样,把我们要实现的功能放在一个.dll中,然后用一个程序把这个.dll嵌入到一个正在运行的进程中去,在这个进程中启动我们的dll,我们的程序就作为一个线程在远程进程中得以运行。

 2、在同一进程运行两个程序
        我用到了冯越编写的Remote Run Library,它使得使得任意exe都可以在其他进程中以线程运行(当然,这里说的"任意"是有条件的,下面会讲到)。
        基础知识:每一个exe都有一个缺省加载基址,一般都是0x400000。如果实际加载基址和缺省基址相同,程序中的重定位表就不需要修正(fixup),否则,就必须修正重定位表;如果一个程序没有重定位表,而且如果程序不能在缺省基址处加载,那么程序将不能运行。举个例子,Windows95的最低加载基址是0x400000,你在Windows NT上开发了一个exe,指定其加载基址为0x10000,如果连接时让连接器剥离重定位表,那么他将无法在Windows95下运行。让“所有”的程序都能在其他进程空间跑,这里,“所有”的含义是所有那些“重定位表没有被剥离”的32位pe格式的可执行程序。对于Visual C++,这包括所有Debug版程序和以"/FIXED:NO"选项链接的Release版程序(Project Obtion中添加)。
        我们把先加载的exe称为宿主,后加载的exe称为客户。
        对于一般的程序:
       1)绝大多数程序的加载基址都是0x400000,这样,客户exe就很难保证加载到其缺省基址。解决办法只能是修正重定位表。如果,很不幸,这个exe的重定位表被剥离,这个exe就没法在其他进程空间跑。对于Visual C++,剥离重定位表是Release版exe的缺省设置。可以在工程文件的连接选项中加入"/FIXED:NO"来防止连接器剥离重定位表。
       2)很多程序都用隐性联接调用Windows API,而只用到kernel32.dll导出API的程序很少,因此这一点也很难保证。解决办法是重填导入表(import table)。
       另外,对于有界面的程序,光修正重定位表和导入表还不够。因为他们都会直接或间接用到GetModuleHandle和LoadResource这些函数。GetModuleHandle有个特点,如果传递给他的ModuleName为NULL,则返回宿主exe的模块句柄。LoadResource也类似,如果传递给他的模块句柄为NULL,则认为是宿主exe模块,类似的API还有一些,不一一列举。客户exe调用这些API显然会得到错误的结果。因此必须截获这些API做特殊处理。
       综合上面分析,要让两个程序共享一份进程空间,要做的工作有:
       1)打开进程边界:用WriteProcessMemory向宿主进程注入代码,用CreateRemoteThread启动远程代码;
       2)在远程代码中,加载客户exe,必要时修正重定位表和填充dll导入表。
       3)截获GetModuleHandle,LoadResource等API,在客户exe以缺省参数调用时返回客户exe的模块句柄,而不是宿主句柄。
        根据以上思路,冯越写了remote.dll,导出三个函数:RemoteRunA,RemoteRunW,和RemoteCall。
 
        对于上述的第一个技术远程线程技术,我的键盘记录程序无法利用。原因是实现全局钩子的dll必须由一个exe来调用,否则钩子无法钩到全局消息。于是我用“在同一进程运行两个程序”的技术写出了第二个版本。包含四个文件:Start.exe、remote.dll、KeyExe.exe、KeyDll.dll。Start.exe开机运行,通过调用remote.dll导出的函数RemoteRunA使KeyExe.exe嵌入进程explorer.exe,实现进程KeyExe.exe的隐藏。KeyExe.exe调用KeyDll.dll实现键盘全局钩子的调用。

 3、pe文件改写
        还有一种隐藏进程的技术就是改写pe文件。但是这种方法的限制很多,原因是微软对它的核心文件都做了保护,发现其代码被改写,马上恢复。
        微软提供了一个detours库(上面的remote.dll就用到了它),在这个库中,微软还提供了一些例子,其中一个是setdll,其功能是静态地把一个dll代码绝对地加入一个exe文件中,加入后这个exe文件大小会增加几个K。
       利用VC编写被写入exe文件的dll工程时,DllMain函数前需要有以下空函数代码:
       __declspec(dllexport) VOID WINAPI MydllFunction(VOID)
       {
         return;
       }
        这样dll才能成功地被setdll写入exe文件中。
        微软提供了这样一个矛,因为它有能够阻挡这个矛的盾。
        另外一种技术,就是把我们的代码写入pe文件的空隙中去,从而不会改变pe文件的大小;或者写入其他类型的文件如图片中。好高级好遥远哦!

三、开机自动启动

        注册表中自动启动比较隐蔽的设置有:
        1.Load注册键。位置:
HKEY_CURRENT_USER/Software/Microsoft/WindowsNT/Current/Version/Windows/load
        2.Userinit注册键。位置:
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/WindowsNT/CurrentVersion/Winlogon/Userinit。通常该注册键下面有一个userinit.exe,这个键允许指定用逗号分隔的多个程序,例如“userinit.exe,OSA.exe”(不含引号)。
        3.Explorer/Run注册键。位置:
HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/Run
和HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Policies/Exp lorer/Run
       4.RunServicesOnce注册键。RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序。RunServicesOnce注册键的位置是:HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/RunServicesOnce,和HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/RunServicesOnce
        5.其他。

四、SMTP/POP3协议

        程序需要发送邮件和接收邮件,我稍微了解了一下SMTP协议和POP3协议,然后在网上找到了PJ Naughter编写的CPop3Connection类和CSMTPConnection类,直接利用它们。为使邮件附件传送完整,又增加了一个附件的CRC验证检查机制。还修改了PJ Naughter编写的程序“Demo app for CSMTPConnection MFC class”。感谢PJN!!!
 

        另外,还用到了API函数拦截,也是参考网上现有的源代码...... -_-


        纵观整个程序开发过程,最大的失误是软件工程思想用得不够。由于各方面的原因,我们边写代码边设计,很多时间都在补窟窿。

        写到这里,不想写了,等有兴趣的时候再说吧,抱歉 ^_^

 


键盘被按动的声响
淹没了我心碎的音律

就像流年匆匆而过
我们也就成了被删除的过客

VC++开发数据库应用程序  用VC++开发数据库应用程序1、 概述   1、1 Visual C++开发数据库技术的特点  Visual C++提供了多种多样的数据库访问技术——ODBC API、MFC ODBC、DAO、OLE DB、ADO等。这些技术各有自己的特点,它们提供了简单、灵活、访问速度快、可扩展性好的开发技术。  简单性   Visual C++中提供了MFC类库、ATL模板类以及AppWizard、Cl 阅读详情

相关推荐

C++项目实战:一小时搭建属于你的小型FTP服务器

FTP服务器是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务。 FTP是File Transfer Protocol( 文件传输协议 )。顾名思义,就是专门用来传输文件的协议。简单地说,支持FTP协议的服务器就是FTP服务器。 这是一个用C++编写的小型FTP服务器源代码,VC6.0下顺利编译,界面是英文的。 项目结构展示: 源码展示: 这个小型的FT...

1876

C++项目实例案例

C++项目实例案例,本资源提供29个项目开发实例,用于提高vc++编程能力(密码:www.cctry.com)

VC实现小型矢量图形系统的开发

导读:   大家学习了VC的MFC的一些基础知识后,如果能用VC开发一个比较实用的软件,对熟悉VC各方面编程和面向对象的软件设计和开发都是很有帮助的。   本文旨在通过对一个作者自己开发小型矢量图形系统全面讲述而达到让读者了解一个小软件从设计到实现的阶段的解决的问题。同时也从界面和功能上对MFC和Windows系统功能的挖掘,同样,对于学习计算机图形学的读者,也可以看到本文有很多对图形学

xu的blog 2310

VC++项目开发案例精粹

VC++项目开发案例精粹,包含VC++项目开发案例精粹pdf和相关章节代码

VC++写的一个最简单的工程项目

学习C++很久了,但确一直没用工程自建头文件的方法写多少程序,正好课程需要,写了一个最简单的工程。自建头文件的小程序。 (一) 建 *.h文件 #ifndef _MYMATH_H #define _MYMATH_H bool isTriangle(int a, int b, int c);//是否能构成三角形 #endif (二)编写*.h头文件中声明的函数的源文件*.cpp #

Code is to be happy 2773

VC小例子(整理)

1添加状态栏图片 继承CStatusBar类,重新DrawItem函数 void CBitmapStatusBar::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { UINT nID,nStyle; int nWidth; GetPaneInfo(lpDrawItemStruct->itemID, nID, nStyle, nWidth);

jiht594的专栏 4595

一些开源项目及相关网站介绍

介绍:介绍一下用VC++/MFC写的最好的开源项目。 Sourceforge.net中有许多高质量的VC++开源项目,我列举了一些可以作为VC++程序员的参考。 正文: VC++、MFC中最好的开源项目 作者:Sudhir Mangla VC++、MFC中最好的开源项目 作者:Sudhir Mangla 改编:http://www.okbase.net/home

天道酬勤 2万+

我的开源项目:JPEG分析器

本文介绍一个自己的开源小项目:JPEG分析器。JPEG全称是 Joint Photographic Experts Group(联合图像专家小组),是当今使用最为广泛的图像编码标准。我这个项目规模不大,主要可以用来学习JPEG编码标准。结合着源代码看的话效果比较好。它支持将JPEG解码为像素数据(YUV或者RGB)。同时支持输出DCT系数等参数。使用VC 2010的MFC开发完成。用到了开源工程...

雷霄骅(leixiaohua1020)的专栏 1529

VC++实现基于MFC的Web服务器程序:打造简易Web服务解决方案

VC++实现基于MFC的Web服务器程序:打造简易Web服务解决方案 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在现代软件开发领域,Web服务器的构建是一个基础且至关重要的环节。今天,我们为您介绍一个开源项目——VC++实现基于MFC的Web服务器程序。这是一个使用VC 6.0编写的C++语言,基于MFC框架的简单Web服务器程序。通过MFC的强大功能,该程序能实...

gitblog_06752的博客 800

转载

<br />100个vc项目开发:二、一步一点设计音乐播放器 [源码解读]<br /> <br />文章作者: July<br />软件来源:开源<br />==================<br />1.有不正之处,恳请指正。<br />2.本文贴出的是关键实现代码部分,只做粗略展示。<br />3.转载,请注明出处。谢谢。<br />---------<br />一、先画对话框,IDD_MYPLAYER_DIALOG,界面如图:<br /><br /> <br />二、然后,对话框相关处理完成后,

GLF1164991381的专栏 512

深入体验VC++项目开发源码

管西京编著,2011年7月第一版,清华大学出版社,《深入体验VC++项目开发》源代码;内含10个案例代码。

VC++几个项目实例代码

VC++4个和数据库连接的管理系统项目代码

VC开发的简单的helloword

主要就是利用VC开发简单的helloword

VC开发的WCAD项目:打造个性化的AutoCAD软件

随着制造业、建筑业和各类设计领域对精确绘图和设计需求的不断增长,CAD(Computer-Aided Design,计算机辅助设计)软件已成为工程技术人员不可或缺的工具。CAD软件能够提供更为精确、高效的设计解决方案,极大地提高了设计与绘图的质量和速度。从市场需求的角度来看,具备定制化功能、能与多种设备和系统兼容的CAD软件,受到了更多企业的青睐。这些软件不仅需要支持从简单的二维绘图到复杂的三维建模,还必须提供与其他工程软件协同工作的能力。

weixin_42591908的博客 793

VC 小型矢量图形系统开发的实现

大家学习了VC的MFC的一些基础知识后,如果能用VC开发一个比较实用的软件,对熟悉VC各方面编程和面向对象的软件设计和开发都是很有帮助的。 本文旨在通过对一个作者自己开发小型矢量图形系统全面讲述而达到让读者了解一个小软件从设计到实现的阶段的解决的问题。同时也从界面和功能上对MFC和Windows系统功能的挖掘,同样,对于学习计算机图形学的读者,也可以看到本文有很多对图形学算法和实现的有益探讨。

long0801的博客 1482

原创开源项目TinyFC: 一个模仿大型类库MFC的小型类库(VB6实现)

此开源项目结合SDK和VC中MFC方式的优点,针对开发小型,特别是迷你型小应用程序的需求而设计.此开源项目的创立和维护,是基于以下几方面的需求:一,一些项目的主体程序原本使用SDK方式开发,直接调用windows api创建用户界面的软件项目,受制于SDK开发方式的弱点,开发周期较长,开发难度较高. 由于这类项目不适合采用大型类库MFC开发,甚至本身开发语言就不是VC,所以目前比较常见的做法是单独为具体的项目写一堆类模块封装,代码通用性不强,可重用性自然也不强二,使用VB6开发的一些项目,需要使用VB6开发

bcrun的专栏 2048

C语言编译器VC6.0下载 | 简单高效的开发工具,助力学习与项目开发

如果你是零基础的初学者,可以选择那些专门为初学者设计的课程,这类课程通常会从最基础的编程知识开始讲解,并逐步引导学生掌握复杂的编程技能。反之,如果你已经有一定的编程基础,那么可以选择那些针对进阶者的课程,深入学习特定领域的技能,例如人工智能、数据科学、游戏开发等。对于C语言的学习者而言,VC6.0不仅可以帮助他们快速编写、调试代码,还能通过其内置的编译功能进行程序性能分析,是一个非常适合学习的编程工具。无论你是想转行,还是希望提升自己的职业能力,选择一个合适的编程培训班都是至关重要的。

epvikz_073的博客 312
上一篇: 又是一年
下一篇: 装机
Wolfe
博客等级 码龄25年 15粉丝 19原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值