黑基网 首页 学院 编程开发 查看内容

Windows编程杂谈

2017-9-6 01:06| 投稿: xiaotiger |来自: 互联网

摘要: 注:这是一篇菜鸟级编程杂谈,如果您是大神,可以略过。从理论上说,任何一门语言都可以在任何一个系统上编程,只要找到该系统提供的ldquo;接口rdquo;和对系统内部机制有深入的了解就可以。正如c语言可以在windows下 ...

注:这是一篇菜鸟级编程杂谈,如果您是大神,可以略过。

从理论上说,任何一门语言都可以在任何一个系统上编程,只要找到该系统提供的“接口”和对系统内部机制有深入的了解就可以。正如c语言可以在windows下编程,也同样可以在Linux上使用一样。

 

 了解Windows 内部机制

  Windows 是一个“基于事件的,消息驱动的”操作系统。

在Windows下执行一个程序,只要用户进行了影响窗口的动作(如改变窗口大小或移动、单击鼠标等)该动作就会触发一个相应的“事件”。系统每次检测到一个事件时,就会给程序发送一个“消息”,从而使程序可以处理该事件。每个Windows 应用程序都是基于事件和消息的,而且包含一个主事件循环,它不停地、反复地检测是否有用户事件发生。每次检测到一个用户事件,程序就对该事件做出响应,处理完再等待下一个事件的发生。Windows 下的应用程序不断地重复这一过程,直至用户终止程序,用代码来描述实际上也就是一个消息处理过程的while循环语句。

  下面便简单介绍一下与 Windows 系统密切相关的几个基本概念:

  ⒈窗口:这是我要说的第一个概念。似乎是地球人都知道的事儿了,窗口是Windows本身以及Windows 环境下的应用程序的基本界面单位,但是很多人都误以为只有具有标题栏、状态栏、最大化、最小化按钮这样标准的方框才叫窗口。其实窗口的概念很广,例如按钮和对话框等也是窗口哦,只不过是一种特殊的窗口罢了。从用户的角度看,窗口就是显示在屏幕上的一个矩形区域,其外观独立于应用程序,事实上它就是生成该窗口的应用程序与用户间的直观接口;从应用程序的角度看,窗口是受其控制的一部分矩形屏幕区。应用程序生成并控制与窗口有关的一切内容,包括窗口的大小、风格、位置以及窗口内显示的内容等。用户打开一个应用程序后,程序将创建一个窗口,并在那里默默地等待用户的要求。每当用户选择窗口中的选项,程序即对此做出响应。

⒉程序:通常说的程序都是指一个能让计算机识别的文件,接触得最多的便是.exe型的可执行文件,这个不难理解。

⒊进程:说到进程,学过《操作系统》的人都很清楚,所谓进程就是应用程序的执行实例(或称一个执行程序)需要注意的是:进程是程序动态的描述,而上面说到的程序是静态的描述,两者有本质的区别。举个例子,从网上下载了一个adobe photoshop软件到C盘但没有运行,那个.exe 可执行文件叫做程序,它是一个二进制码的文件。一旦双击了exe文件图标运行程序,那个“正在运行着的ps”便称为进程,它在双击的那一刻被系统创建,当你关机或者在任务栏的图标上单击鼠标右键选“退出”时,进程便消亡,彻底结束了生命。进程经历了由“创建”到“消亡”的生命期,而程序自始至终存在于你的硬盘上,不管你的机器是否启动。

⒋线程:线程是进程中的一个执行单元,同一个进程中的各个线程对应于一组CPU指令、一组CPU寄存器以及一堆栈。进程本来就具有动态的含义,然而实质上是通过线程来执行体现的,从这个意义上说,Windows 中进程的动态性意义已经不是很明显了,只算是给程序所占的资源划定一个范围而已(个人观点),真正具有动态性意义的是线程。

⒌消息:我们几乎做每一个动作都会产生一个消息,鼠标被移动会产生WM_MOUSEMOVE消息,鼠标左键被按下会产生WM_LBUTTONDOWN的消息,鼠标右键按下便产生WM_RBUTTONDOWN消息等等。

⒍事件:从它的字面意思我们就可以明白它的含义,如在程序运行的过程中改变窗口的大小或者移动窗口等,都会触发相应的“事件”。

⒎句柄:通常一个句柄就可以传递我们所要做的事情。有经验的读者肯定清楚,编写程序总是要和各种句柄打交道的,句柄是系统用来标识不同对象类型的工具,如窗口、菜单等,这些东西在系统中被视为不同类型的对象,用不同的句柄将他们区分开来。看看C++ 教材中是如何给句柄下定义的:“在Win32里,句柄是指向一个无值型对象(void *)的指针,是一个4字节长的数据”。句柄并不是一个真正意义上的指针。从结构上看,句柄的确是一个指针,尽管它没有指向用于存储某个对象的内存位置,而实际上句柄指向的是一个包含了对该对象进行的引用的位置。在编程时,只要抓住了对象的句柄就可以对该对象进行操作了(《一个简单木马程序的编写与伪装策略》中说到的对QQ密码的截获就是要找到QQ登陆窗口的句柄后才开始截密行动的)。下面再举个例子来说明句柄的运用:编一个程序,使QQ登陆窗口的号码框和密码框均变黑,相关代

码及解释:

void __fastcall Tform1::formCreate(TObject *Sender)

{

HWND hCurWindow,HC,HE;//定义三个窗口句柄变量,hCurWindow用于存放QQ用户登陆窗口的句柄,HC、HE分别存放

//号码框和密码框的句柄。

if((hCurWindow= FindWindow(NULL,"QQ用户登录"))!=0||(hCurWindow=FindWindow(NULL,"OICQ用户登录"))!=0)

{//很明显,调用FindWindow()函数去获得QQ登陆窗口的句柄

String str;

str.sprintf("0x%x",hCurWindow);

}

TCHAR wClassName[255];//类名变量

HC=GetWindow(hCurWindow, GW_CHILD);//得到号码框的句柄

HE=GetWindow(HC, GW_HWNDNEXT);//接着得到密码框的句柄

GetClassName(HE, wClassName, sizeof(wClassName));//得到类名

GetClassName(HC, wClassName, sizeof(wClassName));//得到类名

EnableWindow(HE,false);//使窗口失效

EnableWindow(HC,false);//使窗口失效

}

  以上代码在C++ Builder下编译通过,只要运行次程序,QQ登陆窗口的号码框和密码框马上变黑色,无非是EnableWindow()函数所起的作用。你还可以添加一个Timer控件,将上面的代码copy到void __fastcall Tform1::Timer1Timer

(TObject *Sender)函数中,并在后边加上这一句代码:

SendMessage(hCurWindow,WM_CLOSE,0,0); 使QQ一启动就关闭,让别人永远也用不了QQ,挺有趣儿的哦:).

⒏API与SDK:API是英文 Application Programming Interface 的简称,意为“应用程序接口”,泛指系统为应用程序提供的一系列接口函数。其实质是程序内的一套函数调用,在编程的时候可以直接调用,而不必知道其内部实现的过程,只知道它的原型和返回值就可以了,此外,手头经常放着一本“Windows API大全”之类的书也是必不可少的,不然你根本不知道哪些API是干什么用的,瞎编也编不出什么东西来。在后面我们会介绍调用API编程的例子,调用API编程工作虽然烦琐,但由于API函数都被封装在dll库里,程序只有在运行的时候才调用的,因此程序的体积小而且运行效率高。SDK是英文 Software Development Kit 的缩写,指“软件开发工具包”,在防火墙的设计中就经常涉及到SDK。有关基本的概念就谈这些,那些C/C++的基本语法、什么是面向对象等知识请大家查阅相关的书,此类书籍各大书店已汗牛充栋,不再多叙。下面直接谈谈语种和编程工具的选择问题,这也是初学者们最迷惑的问题。

编程语言以及工具的选择:

 目前的编程语言那么多,有c、c++、c#、java、汇编、html等等,甚至有人将vc、c++ builder也列为两种不同的语言!只要学得精,一门就够了。从实用的角度来讲,C++ 是最好的选择(个人意见,其实每一种语言都很好),而VC和C++ Builder是其相应开发工具的两大主流,小编极力推荐初学者使用C++ Builder,因为很容易上手,如果一下子就用VC的话,也许会打击你的自信心:)。

  促进编程能力提高的途径

  ⒈读程序:在你没有阅读过一份完整的源代码之前,你别指望能写出有多好的程序来!这是对每一位初学者的忠告也是警告,而且必须具备一定的语言基础知识,这里的基础知识主要是指语法知识,最起码要能读懂别人的程序的每一行意思。有没有程序的设计思想,在这个时期并不重要,只要具备一定的语法基础就可以了,思想可以通过阅读完别人的源程序后分析得来。记得在大一学习C语言的时候,我们都很重视语法的学习,整天都看教材、做练习,而且赶在老师的讲课前预习,课后又复习巩固,将一些语法点记得滚瓜烂熟,可后来一到做课程设计的时候,坐在电脑面前无从下手了,不断的问自己:“?语法都会了呀,怎么还是做不出程序来?”相信很多人都像小编以前那样,错误地以为学会了语法就等于掌握了编程。编程的能力包括经验、技巧、耐心等几个因素,而并非想象中的那样简单,更不要以为编程就是简简单单的写程序!其实学一门语言并不需要刻意去记那些条条框框的语法,在看代码的时候,遇到了不明白的地方再去查相关的资料,一点一点补充基础知识再配合源程序的思路,这时的理解才是最深刻的。好的代码是百读不厌的,比如Shotgun的那道构造洪水Ping攻击的代码,我至少读了20遍。

⒉写程序:小编认为一切从借鉴开始,先是修改别人的程序,等到有了一定的程度再写出属于自己的程序。刚开始写程序,不要奢望一下子写出很出色的程序来,编程贵在动手,只要你动手去写了,就算只有一句“printf(“Hello!”);”也是一次进步!此外,还要依照自身的能力循序渐进地写,开始的时候写一点功能简单的、篇幅短小的代码,力求简洁、完整,“麻雀虽小,但五脏俱全”,然后在此基础上进行扩充,一点一点添加功能。

编程的几个小技巧

  以下的几个小技巧,虽然对于编程高手来说这是在玩小孩子把戏,但对于一位初学者,掌握以下几个技巧,容易编写出有趣的程序,培养你对编程的兴趣。

  技巧⒈学会修改注册表。

相信大家都知道当浏览了一些网页恶意代码,IE标题、默认主页等被改得面目全非,这就是通过改动注册表来更改系统设置的例子。Windows中的注册表是个好东西,它是windows系统的灵魂,是许多软件记录数据的地方(当然也包括windows本身)。windows通过它记录大量的数据,然后在下一次启动时再读取相应的数据来设置系统。通过控制注册表就可以控制整个系统,所以很多的黑客程序都在注册表上动手脚(尤其是木马程序和作恶剧程序),学会修改注册表可以实现一些有趣而强大的功能。我们完全可以通过编程来操作注册表,达到与手动更改注册表编辑器产生一样的效果。“超级兔子”中的大部分功能就是通过修改注册表来完成的。操作注册表有专门的API函数,大家可以参考有关资料,下面小编以C++ Builder为例说明如何在程序中操作注册表:

程序二:编程修改IE标题内容

新建一个工程,在Unit1.h文件中包含Registry单元:

#include

然后就可以在.cpp文件操作注册表了,接着来!在窗体的OnCreate()里加入以下代码(你可以在try{}里面加入任何操作注册表的代码):

TRegistry* Registry;

Registry = new TRegistry();创建一个TRegistry类型的对象Registry,用于修改注册表。

try{

Registry->RootKey = HKEY_CURRENT_USER;//设置主键,这是必不可少的,设置好主键后,就可以操作这个主

//键下所有的键值了。

if( Registry->OpenKey("Software\Microsoft\Internet Explorer\Main",FALSE))//调用OpenKey()

//打开.

//括号里所指的键

{

Registry->WriteString("Window Title",”台湾是中国的一部分,世界上只有一个中国!”);

//调用WriteString()往注册表里写入IE标题

Registry->CloseKey();//关闭该键

}

else

{//如果打开失败的话

Registry->CreateKey("Software\Microsoft\Internet Explorer\Main");//就调用CreateKey()

//新建上述键

Registry->WriteString("Window Title","编程杂谈");//再写入//IE标

//题内容

Registry->CloseKey();//最后关闭该键,这个也不能忽视,它跟上面的OpenKey成对使用的}//End of try

__finally

{//要是出错,跳到这里处理

Registry->CloseKey();//关闭所要打开的键

delete Registry;//销毁Registry对象,释放资源。

}

  编译运行上面的代码就可以将IE的标题改为“编程杂谈”了。

  技巧⒉调用API编程

  API是系统在DLL里为我们提供的程序接口,可以直接调用的。

程序三:调用API函数隐藏Windows的任务栏:

HWND WndHandle;//定义句柄类型变量

WndHandle=FindWindow("Shell_TrayWnd",NULL);//调用API函数FindWindow()获得任务栏的句柄

ShowWindow(WndHandle,SW_HIDE);//再调用API函数ShowWindow()隐藏任务栏

在上面调用API函数FindWindow()和ShowWindow()的过程中,只要我们知道函数的

名字和括号里的参数是什么就行了,至于实现的过程不必理会,也轮不到我们这些菜鸟去理会:学会

调用API,你可以写出功能强大的程序来,这一技巧对于初学者来说是必须掌握的

技巧⒊多线程编程技术

它是进程内部的一个执行单元(如一个函数等),编写多线程应用程序是指使程序在运行时创建多个线程并发地运行于同一个进程中。很多蠕虫病毒不就是三线程的技术嘛,病毒的工作效率如此之高是与它的多线程技术分不开的。

使用多线程技术编程有如下优点:

  ①提高CPU的利用率。由于多线程并发运行,可以使用户在做一件事情的时候还可以做另外一件事。特别是在多个CPU的情况下,更可以充分地利用硬件资源的优势:将一个大任务分成几个小任务,由不同的CPU来合作完成。

②采用多线程技术,可以设置每个线程的优先级,调整工作的进度。

清楚了使用多线程技术的优势之后,下面便来谈谈如何在C++ Builder环境下开发多线程的应用程序,在C++Builder 环境中,通过 TThread 类就可以很方便地编写多线程应用程序(但不能直接使用,因此要派生新类),

具体流程如下:

  从TThread 类派生出一个新的线程类->创建线程对象->设置线程对象的属性项->挂起或唤醒线程(根据具体情况操作)->结束线程。要说明一点的是:在应用程序中要合理地设置线程的优先级。不要因为某些线程的优先级很高而使其他一些线程因为等不到CPU的处理时间而被“饿死”,也不要因为线程的级别都差不多而导致的频繁切换花费大量的CPU时间。

技巧⒋让程序实现后台监控

  众多木马程序都很注意自身的后台监控本领,也就是隐身技术,面对不同的系统要施展不同的对策才能实现。很多杀毒程序就采用了这种后台监控技术,使程序随着系统的启动而运行,然后在后台悄悄地监视系统的一举一动,一发现有不对路的程序就把它“揪”出来示众。实现程序的后台监控技术有如下几个关键:

①正常运行时,不显示程序的窗体;

②系统每次启动都自动运行程序一次;

③程序图标不显示在任务栏上;

④不显示在按Ctrl+Alt+Del 调出的任务列表中;

⑤通过热键可以调出隐藏的窗体

  实现方法:对于①,要不显示窗体,我们可以编辑WinMain函数,设置ShowMainform值为False就可以隐藏程序的窗体了。参考代码:Application->ShowMainform = false ;对于②,可以利用技巧1所介绍的方法修改注册表,键值如下:HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun ,使用的是WriteString()方法。这是冰河等多种旧木马惯用的启动手段之一(当然还有文件关联、注入dll等方法);对于③,要使程序图标不显示在任务栏上,也很简单,调用API函数SetWindowLong 可以让程序运行后不出现在任务栏里,不过要放在窗体的OnCreate()里面。代码如下:

SetWindowLong(Application->Handle,GWL_EXstyle,WS_EX_TOOLWINDOW);

对于④,调用RegisterServiceProcess API 函数将程序注册成为一个服务模式程序,让它运行在较高的优先级下,就不会出现在程序列表中,对于⑤,要先定义捕获Windows消息WM_HOTKEY的钩子函数,然后向Windows 加入一个全局原子,并保留其句柄,最后向Windows登记热键,这个可以调用API函数RegisterHotKey来实现。

 

小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册黑基账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!

本文出自:http://www.toutiao.com/a6461844449302413838/

免责声明:本文由投稿者转载自互联网,版权归原作者所有,文中所述不代表本站观点,若有侵权或转载等不当之处请联系我们处理,让我们一起为维护良好的互联网秩序而努力!联系方式见网站首页右下角。


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论


新出炉

返回顶部