黑客编程——Windows机制、API编程简介、Windows 网络.pdf

上传人:qwe****56 文档编号:70015170 上传时间:2023-01-14 格式:PDF 页数:14 大小:346.78KB
返回 下载 相关 举报
黑客编程——Windows机制、API编程简介、Windows 网络.pdf_第1页
第1页 / 共14页
黑客编程——Windows机制、API编程简介、Windows 网络.pdf_第2页
第2页 / 共14页
点击查看更多>>
资源描述

《黑客编程——Windows机制、API编程简介、Windows 网络.pdf》由会员分享,可在线阅读,更多相关《黑客编程——Windows机制、API编程简介、Windows 网络.pdf(14页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

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

2、处理过程的 while 循环语句。下面便简单介绍一下与 Windows 系统密切相关的几个基本概念:1:窗口:这是我要说的第一个概念。窗口是 Windows 本身以及 Windows 环境下的应用程序的基本界面单位,但是很多人都误以为只有具有 标题栏、状态栏、最大化、最小化按钮这样标准的方框才叫窗口。其实窗口的概念很广,例如按钮和对话框等也是窗口,只不过是一种特殊化 窗口罢了。从用户的角度看,窗口就是显示在屏幕上的一个矩形区域,其外观独立于应用程序,事实上它就是生成该窗口的应用程序与用户间的直观 接口;从应用程序的角度看,窗口是受其控制的一部分矩形屏幕区。应用程序生成并控制与窗口有关的一切内容

3、,包括窗口的大小、风格、位 置以及窗口内显示的内容等。用户打开一个应用程序后,程序将创建一个窗口,并在那里默默地等待用户的要求。每当用户选择窗口中的选 项,程序即对此做出响应。2:程序:通常说的程序都是指一个能让计算机识别的文件,接触得最多的便是.exe 型的可执行文件.3:进程:说到进程,学过操作系统的人都很清楚,所谓进程就是应用程序的执行实例(或称一个执行程序)需要注意的是:进程是 程序动态的描述,而上面说到的程序是静态的描述,两者有本质的区别。举个例子,从网上 Down 了一个瑞星杀毒软件到 C 盘但没有运行,那 个.exe 可执行文件叫做程序,它是一个二进制码的文件。一旦双击了exe

4、文件图标运行程序,那个“正在运行着的瑞星杀毒”便称为进程,它 在双击的那一刻被系统创建,当你关机或者在任务栏的图标上单击鼠标右键选“退出”时,进程便消亡,彻底结束了生命。进程经历了由“创 建”到“消亡”的生命期,而程序自始至终存在于你的硬盘上,不管你的机器是否启动。4:线程:线程是进程中的一个执行单元,同一个进程中的各个线程对应于一组 CPU 指令、一组 CPU 寄存器以及一堆栈。进程本来就具有动态 的含义,然而实质上是通过线程来执行体现的,从这个意义上说,Windows 中进程的动态性意义已经不是很明显了,只算是给程序所占的资源 划定一个范围而已,真正具有动态性意义的是线程。5:消息:我们几

5、乎做每一个动作都会产生一个消息,鼠标被移动会产生 WM_MOUSEMOVE消息,鼠标左键被按下会产生 WM_LBUTTONDOWN 的消 息,鼠标右键按下便产生 WM_RBUTTONDOWN 消息等等。所有的这些都可以通过GetMessage,SendMessage 等函数得到.6:事件:如在程序运行的过程中改变窗口的大小或者移动窗口等,都会触发相应的“事件”。7:句柄:单单一个“柄”字便可以解释它的意思了,我们天气热摇扇子的时候只要抓住扇柄便可以控制整个扇子的运动了,在程序中也 差不多是这个意思。通常一个句柄就可以传递我们所要做的事情。有经验的成员肯定清楚,编写程序总是要和各种句柄打交道的,

6、句柄是 系统用来标识不同对象类型的工具,如窗口、菜单等,这些东西在系统中被视为不同类型的对象,用不同的句柄将他们区分开来。C+教材中给句柄下的定义是:“在 Win32 里,句柄是指向一个无值型对象(void*)的指针,是一个 4 字节长的数据”。从结构 上看,句柄的确是一个指针,尽管它没有指向用于存储某个对象的内存位置,而实际上句柄指向的是一个包含了对该对象进行的引用的位置。在编程时,只要抓住了对象的句柄就可以对该对象进行操作了.8:API 与 SDK:API 是英文 Application Programming Interface 的简称,意为“应用程序接口”,泛指系统为应用程序提供的一系

7、列接 口函数。其实质是程序内的一套函数调用,在编程的时候可以直接调用,而不必知道其内部实现的过程,只知道它的原型和返回值就可以 了.SDK 是英文 Software Development Kit 的缩写,指“软件开发工具包”,在防火墙的设计中就经常涉及到 SDK。第二节 Win API 编程简介 下面介绍一下 WIN API.我们需要自己编写一个工具时,必然会用到很多操作 windows 和控制 windows 的函数,这些函数就是 windows API.API 是 Application Progamming Interface 的缩写.就是说 API 是一系列已经定义的在windows

8、 内部的函数,是应用程序和系统之间的 桥梁,应用程序通过调用 API 来请求系统完成一系列的任务.窗口,菜单,文件操作等都是通过API 实现的.WIN32 API 就是 WINDOWS 32 位平台的应用程序接口.现在可视化编程工具提供了大量控件,他们代替了 API 的功能.这些控件都是构建 在 WIN32 API 之上的.是封装了的 API 函数集合.但是对于比较复杂和特殊功能(想我们的黑客编程)来说,就必须用 API 函数来实现.WIN API 存放在动态链接库(DLL)中,在 98 系统中,有 32 位的 GDI32.DLL,KERNEL32.DLL,16 位的 GDI.EXE,KRNL

9、386.EXE.API 就存放在这些 动态链接库中.木马和后门其实就是使用了文件操作函数,这里做简要介绍:删除文件:BOOL DeleteFile(LPCTSH lpFileName)复制文件:BOOL CopyFile()移动文件:BOOL MoveFile()等等 具体的 API 可以上网自己去查看,有很多介绍 API 的书籍.第三节 Windows 网络协议 首先介绍一下网络协议:网络协议是网络上所有设备之间通信规则的集合,他定义了通信时信息必须采用的格式和这些格式的意义.大多数 网络协议都采用分层体系结,每一层都建立在他的下层之上,向他的上一层提供服务,而把如何实现这一服务的细节对上层

10、加以屏蔽.一台设备上 的第 N 层与另一台设备上的第 N 层进行通信的规则就是第 N 曾协议.在网络上的个层之间中存在着许多协议,接受方和发送方同层的协议必须一致,否则,一方就无法识别另一方发出的信息.网络协议使网络上的设备各种设备能相互交换信息.常用的协议有:TCP/IP 协议,IPX/SPX 歇息等等.在局域网中常用的 IPX/SPX 协议.而访问INTERNET,就必须添加 TCP/IP 协议.TCP/IP 协议是传输控制协议/互联网络协议.他规范了网络上所有设备的通信,尤其是一个主机与另一个主机之间的数据往来格式以及传送 方式.在网络的各层中还存在着许多协议,下面列出部分网络协议规范:

11、ARP 地址解析协议 SNMP 网络管理协议 BOOTP 让无盘站从一个中心服务器上获得 IP 地址 DHCP 动态主机配置协议 下面介绍网络 7 层协议在 WINDOWS 的实现:7 层协议 WIN 系统 _ 7 应用层 7 应用程序 _ 6 表示层 6 WINSOCK API(DLL)_ 5 会话层 5 SPI(DLL)_ 4 传输层 4 TDI(VXD,SYS)_ 3 网络层 3 NDIS(VXD,SYS)_ 2 数据链路层 2 网卡驱动程序(VXD,SYS)_ 1 物理层 1 网卡 _ 相信这个映射图可以让大家比较清楚了解他们的对应关系 TCP 协议图示 应用程序协议 HTTP FTP

12、 TELNET 传输协议 TCP UDP 网际协议 IP 物理层协议 网卡 IP 协议保证数据的传输,TCP 协议保证数据传输的质量.TCP/IP 协议基于四层结构:应用层,传输层,网络层,接口层,数据在传输时每通过一层就要在数据上加个头,其中的数据供接受端同层使用,在 接收端,每经过一层就把头去掉,来保证传输数据格式的一致.TCP 头部结构:16 位源端口号 16 位目的端口号 _ 32 位序列号 _ 32 位确认号 _ 4 位首部长度+6 位保留字 6 位标志 16 位窗口大小 _ 16 位效验和 16 位紧急数据偏移量 _ 数据段 _ IP 头部结构:4 位 IP 版本号 4 位首部长度

13、 8 位服务类型 16 位总长度 _ 16 位标示 3 位标志和偏移 _ 8 位生存时间 8 位协议 16 位 IP 首部效验和 _ 32 位源 IP 地址 _ 32 位目的 IP 地址 _ TCP 头和数据 _ 第四节 关于服务器和客户端编程 在网络编程中,最常用和最基础的就是 WINSOCK.现在我们讨论 WINDOWS 下的SOCKET 编程.大凡在 WIN32 平台上的 WINSOCK 编程都要经过下列步骤:定义变量-获得 WINDOCK 版本-加载 WINSOCK 库-初始化-创建套接字-设置套接字选项-关闭套接字-卸载 WINSOCK 库-释放资源 下面介绍 WINSOCK C/S

14、 的建立过程:服务器 客户端 _ 1 初始化 WSA 1 初始化 WSA _ 2 建立一个 SOCKET 2 建立一个 SOCKET _ 3 绑定 SOCKET 3 连接到服务器 _ 4 在指定的端口监听 4 发送和接受数据 _ 5 接受一个连接 5 断开连接 _-6 发送和接受数据 _ 7 断开连接 _ 大家注意,在 VC 中进行 WINSOCK 编程时,需要引入如下两个库文件:WINSOCK.H(这个是WINSOCK API 的头文件,WIN2K 以上支持 WINSOCK2,所以 可以用 WINSOCK2.H);Ws2_32.lib(WINSOCK API 连接库文件).使用方式如下:#i

15、nclude#pragma comment(lib,ws2_32.lib)下面我们通过具体的代码演示服务器和客户端的工作流程:首先,建立一个 WSADATA 结构,通常用 wsaData WSADATA wsaData;然后,调用WSAStartup函数,这个函数是连接应用程序与winsock.dll的第一个调用.其中,第一个参数是 WINSOCK 版本号,第二个参数是指向 WSADATA 的指针.该函数返回一个 INT 型值,通过检查这个值来确定初始化是否成功.调用格式如下:WSAStartup(MAKEWORD(2,2),&wsaData),其中 MAKEWORD(2,2)表示使用 WIN

16、SOCK2 版本.wsaData 用来存储系统传回的关于 WINSOCK 的资料.if(iResuit=WSAStartup(MAKEWORD(2,2),&wsaData)!=0)printf(WSAStartup failed:%d,GetLastError();/返回值不等与 0,说明初始化失败 ExitProcess();/退出程序 应用程序在完成对请求的 SOCKET 库使用后,要调用 WSACleanup 函数来接触 SOCKET 库的绑定,并且释放资源.注意 WSAStartup 初始化后,必须建立一个 SOCKET 结构来保存 SOCKET 句柄.下面我们建立一个 SOCKET.

17、首先我们建立一个 m_socket 的 SOCKET 句柄,接着调用 socket()函数,函数返回值保存在m_socket 中.我们使用 AF_INFE,SOCK_STREAM,IPPROTO_TCP 三个参数.第一个表示地址族,AF_INFE 表示 TCP/IP 族,第二个表示服务类型,在 WINSOCK2中,SOCKET 支持以下三种类型;SOCK_STREAM 流式套接字 SOCK_DGRAM 数据报套接字 SOCK_RAW 原始套接字 第三个参数表示协议:IPPROTO_UDP UDP 协议 用于无连接数据报套接字 IPPROTO_TCP TCP 协议 用于流式套接字 IPPROTO

18、_ICMP ICMP 协议用于原始套接字 m_socket=socket(AF_INFE,SOCK_STREAM,IPPROTO_TCP);/创建 TCP 协议 以下代码用于检查返回值是否有错误:if(m_scoket=INVALID_SOCKET)prinrf(Error at socket():%dn,GetLastError();WSACleanup();/释放资源 return;说明,如果 socket()调用失败,他将返回 INVALID_SOCKET.为了服务器能接受一个连接,他必须绑定一个网络地址,下面的代码展示如何绑定一个已经初始化的 IP 和端口的 Socket.客户端程序用

19、这个 IP 地址和端口来连接服务器.sockaddr_in service;service.sin_family=AF_INET;/INTERNET 地址族 service.sin_addr.s_addr=inet_addr(127.0.0.1);/将要绑定的本地 IP 地址 service.sin_port=htons(27015);/27015 将要绑定的端口 下面我们调用 BIND 函数,把 SOCKET 和 SOCKADDR 以参数的形式传入,并检查错误.if(bind(m_socket,(SOCKADDR*)&SERVICE,sizeof(service)=SOCKET_ERROR)

20、printf(bind()failed.n);closesocket(m_socket);return;当绑定完成后,服务器必须建立一个监听队列,以接受客户端的请求.listen()使服务器进入监听状态,该函数调用成功返回 0,否则返回 SOCKET_ERROR.代码如下:if(listen(m_socket,1)=SOCKET-ERROR)printf(error listening on socket.n);服务器端调用完 LISTEN()后,如果此时客户端调用 CONNECT()函数,服务器端必须在调用ACCEPT().这样服务器和客户端才算正式完成通信程序的 连接动作.一旦服务器开始监

21、听,我们就要指定一个句柄来表示利用 ACCEPT()函数接受的连接,这个句柄是用来发送和接受数据的表示.建立一个 SOCKET 句柄 Socket AcceptSocket 然后利用无限循环来检测是否有连接传入.一但有连接请求,ACCEPT()函数就会被调用,并且返回这次连接的句柄.printf(waitong for a client to connect.n);while(1)AcceptSocket=SOCKET_ERROR;while(AcceptSocket=SOCKET_ERROR)AcceptSocket=accept(m_socket,NULL,NULL);下面看客户端端代码:

22、sockaddr_in clientService;clientService.sin_family=AF_INET;/INTERNET 地址族 clientService.sin_addr.s_addr=inet_addr(127.0.0.1);/将要绑定的本地 IP 地址 clientService.sin_port=htons(27015);/27015 将要绑定的端口 下面调用 CONNECT()函数:if(connect(m_socket,(SOCKADDR*)&clientService,sizeof(clientService)=SOCKET_ERROR)printf(Faile

23、d to connect.n);WSACleanup();return;/如果调用失败清理退出 /调 用 成功继续读写数据 _ 到这里,服务器和客户端的基本流程介绍完毕,下面我们介绍数据交换.send():int send SOCKET s,/指定发送端套接字 const char FAR?*buf,/指明一个存放应用程序要发送的数据的缓冲区 int len,/实际要发送的数据字节数 int flags /一般设置为 0;C/S 都用 SEND 函数向 TCP 连接的另一端发送数据.recv():int recv SOCKET s,/指定发送端套接字 char FAR?*buf,/指明一个缓冲

24、区 存放 RECC 受到的数据 int len,/指明 BUF 的长度 int flags /一般设置为 0 ;C/S 都使用 RECV 函数从 TCP 连接的另一端接受数据 _ 下面将完整的程序代码提供如下,大家可直接编译运行 首先看客户端的代码:#include#include#pragma comment(lib,ws2_32.lib)void main()/初始化 Winsock.WSADATA wsaData;int iResult=WSAStartup(MAKEWORD(2,2),&wsaData);if(iResult!=NO_ERROR)printf(Error at WSAS

25、tartup()n);/建立 socket socket.SOCKET client;client=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(client=INVALID_SOCKET)printf(Error at socket():%ldn,WSAGetLastError();WSACleanup();return;/连接到服务器.sockaddr_in clientService;clientService.sin_family=AF_INET;clientService.sin_addr.s_addr=inet_addr(127.0.0.1)

26、;clientService.sin_port=htons(27015);if(connect(client,(SOCKADDR*)&clientService,sizeof(clientService)=SOCKET_ERROR)printf(Failed to connect.n);WSACleanup();return;/发送并接收数据.int bytesSent;int bytesRecv=SOCKET_ERROR;char sendbuf32=Client:Sending data.;char recvbuf32=;bytesSent=send(client,sendbuf,strl

27、en(sendbuf),0);printf(Bytes Sent:%ldn,bytesSent);while(bytesRecv=SOCKET_ERROR)bytesRecv=recv(client,recvbuf,32,0);if(bytesRecv=0|bytesRecv=WSAECONNRESET)printf(Connection Closed.n);break;if(bytesRecv 0)return;printf(Bytes Recv:%ldn,bytesRecv);return;下面是服务器端代码:#include#include#pragma comment(lib,ws2_

28、32.lib)void main()/初始化 WSADATA wsaData;int iResult=WSAStartup(MAKEWORD(2,2),&wsaData);if(iResult!=NO_ERROR)printf(Error at WSAStartup()n);/建立 socket SOCKET server;server=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(server=INVALID_SOCKET)printf(Error at socket():%ldn,WSAGetLastError();WSACleanup();retu

29、rn;/绑定 socket sockaddr_in service;service.sin_family=AF_INET;service.sin_addr.s_addr=inet_addr(127.0.0.1);service.sin_port=htons(27015);if(bind(server,(SOCKADDR*)&service,sizeof(service)=SOCKET_ERROR)printf(bind()failed.n);closesocket(server);return;/监听 socket if(listen(server,1)=SOCKET_ERROR)printf

30、(Error listening on socket.n);/接受连接 SOCKET AcceptSocket;printf(Waiting for a client to connect.n);while(1)AcceptSocket=SOCKET_ERROR;while(AcceptSocket=SOCKET_ERROR)AcceptSocket=accept(server,NULL,NULL);printf(Client Connected.n);server=AcceptSocket;break;/发送接受数据 int bytesSent;int bytesRecv=SOCKET_ER

31、ROR;char sendbuf32=Server:Sending Data.;char recvbuf32=;bytesRecv=recv(server,recvbuf,32,0);printf(Bytes Recv:%ldn,bytesRecv);bytesSent=send(server,sendbuf,strlen(sendbuf),0);printf(Bytes Sent:%ldn,bytesSent);return;本程序仅仅描述了同步的情况!第五节 多线程编程介绍 对于多线程的基本概念,我不在赘述,是个只要学习过一门编程语言就应该多进程和线程有个基本的了解.这里重点介绍一下如何实

32、现多线程.通常一个程序的主线程有操作系统创建,如果想让其创建额外的线程,可以调用 CreateThread()函数来完成.函数原形如下:HANDLE CreateThread()LPSECURITY_ATTRIBUTES LPThreadAttributes,/指向 SECURITY_ATTRIBUTES 的指针 SIZE_T dwStackSize,/表示线程为自己所用堆栈分配的地址空间的大小 系统缺省值为 0 LPTHREAD_START-TOUTINE lpStartAddress,/表示新线程开始执行时代码所在函数的地址 即线程函数名 LPVOID lpParameter,/是传入线程

33、函数的参数 DWORD dwCreationFlags,/指定控制线程创建的附加标志 取 0线程立即执行 取 CREATE_SUSPENDED 线程挂起 LPDWORD lpThreadld /是个 DWORD 类型的地址,返回赋给该新线程的 ID 线程函数 lpParameter 必须有以下原形:DWORD WINAPI XXXThreadFun(LPVOID lpParameter)return(0);_ 下面我们来创建一个线程:#include#include DWORD WINAPI ThreadFunc(LPVOID lpParam)/线程函数,跟普通的函数没什么两样 printf(

34、Parameter=%d.,*(DWORD*)lpParam);return 0;VOID main(VOID)DWORD dwThreadId,dwThrdParam=1;HANDLE hThread;hThread=CreateThread(NULL,0,ThreadFunc,&dwThrdParam,0,&dwThreadId);if(hThread=NULL)printf(CreateThread failed(%d)n,GetLastError();else _getch();CloseHandle(hThread);关于线程同步的问题,这里就不再讲解,请大家自己查阅资料,不查阅以后可能会有困难啊.培养一下各位的自己动手能力.

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com