论坛首页 综合技术论坛

[Guide] How to make a Wow bot for complete newbs!

浏览 2578 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-03-22  

 

原文:http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/319172-guide-how-make-wow-bot-complete-newbs.html

 

[Guide] How to make a Wow bot for complete newbs! 

 

Hi! My name is Devon and I’m an alcoholic.
Actually I have about 10 days off work and my choices of entertainment was drinking my life away or writing an guide for complete newbs on how to make a bot. So I decided to do both. 

Moving on… 
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

嗨,我叫Devon,是个酒鬼。实事上我有十天可以不去工作,我可以选择的娱乐是借酒消愁或写一个指南给那些想自己做个游戏机器人的新手。所以,我决定两个都做。

开饭……
--Pre Introduction:--

I have spent a long time hopelessly searching the internet to learn everything I needed to know to make a bot. Well I failed miserably. But to my rescue came a kind person and helped me in my adventure to the stars (or at least the addresses of world of warcraft). He not only spent his time helping me by showing me stuff in the code I knew best but he also gave me great direction in where/what to search on the forums . Because of him I have this knowledge. Thank you ^_^ 

(I do not know if he wants to be named or not.)
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

我曾经花费了很长时间非常苦逼的在网上搜索如何做一个游戏机器人。结果我可悲的失败了。但这时一个高手横空出世拯救了我并为我指出了一条璀璨的星光大道(至少是通往魔兽的道路)。他不仅教我如何用我最擅长的语言去做这件事,而且指导我如何如何有效的搜索论坛。因为他我才掌握了现在的知识。感谢他,囧

(不知他是否羞涩于将自己的名字公布出来)


--Introduction:--
Okay so many of you newbies (such as myself) are probably wondering “How the **** do I make a bot”. Well let me start out by saying, you need to know at least some sort of computer language, whether it be C++, C#, Java, or the shit language I use Autoit (yeah, yeah …Scripting blah, blah, blah… Its shitty blah, blah, blah…Learn a real language blah, blah, blah. All in due time). If you do not know a language then you will not understand this at all. So please go learn a language. 

 

Okay, 很多新手(比如我)都曾经疑惑过“怎么他奶奶个甜甜圈的才能做一个游戏机器人呢?”。现在我来告诉你,你至少要懂一种计算机语言,不论哪种语言,C++JAVAC#或者我用的狗屎语言Autoit#此处为人们对这个脚本语言的轻蔑# 作者:老子没空学别的)。如果你一门语言都不会,那你肯定不会理解这篇文章。所以,赶快死开去补课。

On top of needing to know a language, you need to have a function that can read memory addresses. Whether you make it yourself or not is up to you.

 

作为必要条件,你选择的语言要有一个函数可以直接读取计算机的内存,不论你找个现成函数的或你自己来编写。

One last thing, I personally do not know everything as I have just started out. For example, I do not know very much about dlls, therefore I copy the memory function (from nomadmemory.au3) and a “getwowbase” function provided by my dear ol’ champ I spoke about in the Pre Introduction.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

最后,我并不是一个专家,我也是刚刚开始。比如,我并没多少关于DLL的知识,所以我从nomadmemory.au3Autoit脚本文件)直接复制了内存函数。Getwowbase这个函数是我前面提到的救星给我的。


Also, I will be using Autoit seeing as it is the code I am currently most skilled in and it is a fairly simple language so it should be simple enough to translate into your preferred code, but I will explain what is happening when necessary.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

我将会用Autoit这个我最拿手而且非常简单的语言来展开这篇教程。相信你能非常容易的转换为你擅长的语言。关键点我将做一些必要的解释。


So let’s get down to it.

终于可以坐下来开吃了。
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->


--Analogy (sounds like a good time to me)/Terms:--

So …*Deep Breath*… We can compare how we get info from World of Warcraft to our real world. Just like in real life, where there are many objects and creatures, there are many objects and creatures in Wow. We call these (because programmers aren’t creative) “WowObjects”. 
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

So…*深呼吸*… 我们可以比较一下魔兽世界和我们真实的世界。就如我们真实的生活中一样,在魔兽世界中同样有许多物体和生物。我们权且统称为(程序员通常都是没想像力的)“WowObjects.


So we say to ourselves we want something from this world and we want to know a characteristic of this “something”. I would first need to know what kind of thing this something is. For example, is it a person or is it a table? Is it human or is it a dog or a cat? Similar concept applies to Wow. We call this an “ObjectType”. There are 7 types of objects in Wow, listed below:

 

我们想从魔兽世界中得到某个对象并且得到这个对象的属性,首先我们要知道这个对象到底是个神马。比如神马到底是个人还是个桌子?是人类还是狗狗还是猫猫……?把这个概念引申到魔兽世界,我们称为”ObjectType(对象类型)WoW中主要有7种类型,如下:
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

Code:

1 - Items

2 - Contains

3 - NPC's

4 - Players

5 - GameObjects (Nodes etc)

6 - DynamicObjects (Spells and stuff)

7 - Corpses

From: http://www.mmowned.com/forums/world-...e-objects.html (Excellent guide. After you’re done, go check it out)

(作者推荐的网文,E文)

After we find out our type of world object (say for example a human) how would we know which human it is seeing as there are billions in the world. Well, as I’m sure you already know, this is the reason people have names. So this means if we know a person’s name we can find even more details about that person. Names in Wowmemory are called “GUIDs” (Globally Unique Id) which is in sense a tag to identify an object. 
当我们知道了一个对象的类型后(比如类型是人类),但世界上有几十亿人,我得到的这个神马人类到底是谁?这就是为什么我们每个人都要有一个名字。这个名字在wowMemory中被称作“GUIDs(Globally Unique ID, 全局唯一标识),用于唯一标识一个对象。


After this we have “Descriptors” which Describe (man these programmers are so clever) a WowObject. They kind of act like adjectives in the real world. For example in the real world if you asked someone how they’re health was they would say “good” or “bad”. Well in the programming world we don’t use adjectives, we use numbers. So if we had a Descriptor offset for our health it would tell us “health = 100%” or “health = 0% (you dead!)”

 

接着我们有了另一个概念“描述符(Descriptors)”,用于描述(这些程序员们太特么聪明勒)一个对象的状态。它有点象我们真实生活中的形容词。比如真实世界中你问某人的健康情况,他通常会回答你“很好”或“不怎么样”。但在程序的世界我们不用形容词,而是用数字。所以如果你有一个标识符去描述你的健康(血量),它通常会告诉你“血量=100% 血量=0%(挂了)”。

So for good measure and a little over kill I bring you another example analogy.

分寸上似乎有点信息过量,下面是对提到的概念的一个形象类比:


WorldObject - Rick is describing an “object” that he says is a part of this world. 
ObjectType - He says it’s a dog.
Guid - The dog’s name is Alfred
 
Descriptor – Alfred is happy

<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

世界对象 WorldObject -瑞克在描述一个对象,它是这个世界的一部分。

对象类型 ObjectType -他说这个对象是狗狗。

全局唯一标识 Guid -狗狗的名字叫Alfred。

描述符 Descriptor -Alfred很快乐。

(I will go into further detail about these things later)

(稍后我会深入这些概念)

So now that you get the idea behind it let’s see how they actually work in programming. 

现在让我们走入这些概念的背后去看看在程序的世界它们是怎么工作的。

--Memory:--

Now to be thorough, I’m going to explain a little bit about how memory works. Memory or RAM (Random Access Memory) or the little stick you shove into your motherboard to make your computer run, acts as a way to store information from running programs. Think of it as like little cubby holes that stores 1byte of information (generally an regular int is 4 bytes) that your program might need later. 

 

为了让你彻底理解,我先解释下系统内存是如何工作的。内存或RAM(随机存储器)或那根你强插在主板上让计算机运行的条子,用于存储运行中的程序信息。想象成N多个存储一个字节数据的小房间(通常一个整型数据有四个字节,占四个小房间^_^),存储着你的程序运行中会用到的数据信息。

Well, each little cubby hole has an address so that the program can find that information. This address is called a hexadecimal (or hex for short) and it looks something like this “ 0x000000”. This address uses 16 symbols for each digit (0-9 and A-F), so if we increment 0x000009 by 1 it would be 0x00000A. 

 

每一个小房间都有一个唯一的地址,你的程序可以通过这个地址访问这个小房间里的数据。这个地址被称为“hexadecimal”,简称为hex。看上去象这样:0x000000。就是十六进制数啦,用16个字符表示(09 AF),所以0x000000 + 1 = 0x00000A

Memory Cubby Hole picture:

示例图片:
<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="图片_x0020_0" o:spid="_x0000_i1025" type="#_x0000_t75" alt="memorycubbyholes.jpg" style="width:396.75pt;height:186pt;visibility:visible; mso-wrap-style:square" mce_style="width:396.75pt;height:186pt;visibility:visible; mso-wrap-style:square"> <v:imagedata src="file:///C:\DOCUME~1\qwang\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg" mce_src="file:///C:\DOCUME~1\qwang\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg" o:title="memorycubbyholes" /> </v:shape><![endif]--><!--[if !vml]-->memorycubbyholes.jpg<!--[endif]-->

Example math: 

示例计算:

1. 0xF + 0xF = 0x1E
 

2. 0x5 * 0x5 = 0x19

3. 0xBEAD – 0x4321 = 0x7B8C
 

4. 0xBEAD + 0x4321 = 0x101CE
 

5. 0x10000 – 0x1 = 0xFFFF
 


--Offsets:--

Offsets in Wow memory reading are used to take an address, change it, and get a new address with (possibly) more information. For example, say I found my player at a dynamic address (the address changes each time the game loads) and I had a function called “GetPlayersAddress()” that returned the dynamic address to me. I could then use a static offset (always stays the same) to get an address that contains the value of, say, my health. 


偏移量(不知翻译是否准确)是去读取魔兽世界内存地址,改变它,计算出一个新址以得到更多信息。比如,我控制的游戏人物有一个动态地址(因为每次游戏运行加载到内存的区域是不同的)但我有一个程序函数(比如:GetPlayerAddress())可以得到这个动态地址。我就可以使用一个偏移量(这个偏移量永远都一样)去得到一个新地址,以获取更多的信息,比如“血量”。

(译者:可以理解为,当你得到一个角色的地内存地址后,固定的偏移值指向固定的信息,比如人物的血量等)


For Example, say my dynamic address (remember this changes) was 0x000001 and my offset was 0x5. My new address would be 0x000006.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

比如:如果我得到一个动态地址:0x000001 和一个偏移量0x5,那么新址就是0x000001+0x5=0x000006


Now the nice thing about this forum is they have a little area called the dump thread which we will be using since I will not be going into how to actually get these offsets for yourself by reverse engineering Wow. It’s a little too complicate for me at this time.
在作者发贴的这个论坛,有个专门的版块叫dump thread专门罗列了这些偏移值。
--GettingWowBase:—

Now for any bot reading the memory that Wow uses, you will need to know the base address. This is done (from what I’ve seen) by calling a function that uses a couple of dlls to check the memory for wow.exe. I do understand how this works, I just don’t know enough about dlls to be able to code it myself. ^_^
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

任何一个想要读取魔兽世界内存数据的机器人,你要获取它的起始地址。这个工作已经完成,我可以直接调用一个函数配合若干DLL动太链接文件去查找内存中的wow.exe。我明白它是如何工作的,但我并不熟悉DLL所以我没法自己写出一个这样的函数,囧


So my recommendation would be to search google for a function to get base address of wow in your language of choice.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

你可以在google上搜索,你所擅长的语言的相关函数。


This is the code in Autoit:

下面的代码是用Autoit写的:
(created by IceFire32 (unless refuted XD))

Code:

 

Func GETWOWBASEADDRESS($PID)

 

         $HSNAP = DllCall("Kernel32.dll", "HANDLE", "CreateToolhelp32Snapshot", "DWORD", 8, "DWORD", $PID)

 

         $STMODULE = DllStructCreate("DWORD dwSize;DWORD th32ModuleID;DWORD th32ProcessID;" & "DWORD GlblcntUsage;DWORD ProccntUsage;ptr modBaseAddr;" & "DWORD modBaseSize;HANDLE hModule;WCHAR szModule[256];" & "WCHAR szExePath[260]")

 

         DllStructSetData($STMODULE, "dwSize", DllStructGetSize($STMODULE))

 

         $RET = DllCall("Kernel32.dll", "BOOLEAN", "Module32FirstW", "HANDLE", $HSNAP[0], "ptr", DllStructGetPtr($STMODULE))

 

         IF ($RET[0] = False) Then

                 DllCall("Kernel32.dll", "BOOLEAN", "CloseHandle", "HANDLE", $HSNAP[0])

                 Return 0

         Else

                 $RET[0] = True

                 Do

                          If DllStructGetData($STMODULE, "szModule") = "Wow.exe" Then

 

                                   DllCall("Kernel32.dll", "BOOLEAN", "CloseHandle", "HANDLE", $HSNAP[0])

 

                                   Return DllStructGetData($STMODULE, "modBaseAddr")

                          EndIf

                          $RET = DllCall("Kernel32.dll", "BOOLEAN", "Module32NextW", "HANDLE", $HSNAP[0], "ptr", DllStructGetPtr($STMODULE))

                 Until $RET[0] = False

         EndIf

EndFunc   ;==>GETWOWBASEADDRESS

--ObjectManager:—

This is where we get into the juicy stuff. With an object manager, it will search through the memory to find a player memory location. And using some offsets, we can find most things we want to know about our player or any other object for that matter.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

下面是我们感兴趣的部分了。使用对象管理器,去搜索内存,找到游戏角色在内存中的地址。然后使用偏移量,我们就可以得到大多数我们想得到的并于这个角色的信息。


So first thing we need to do is get a couple of addresses and offsets from the latest patch dump thread that the mmowned community was nice enough to share with us.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

那么我们首先要做的就是得到几个地址和偏移量从最新的patch dump thread,这是mmowned这个社区分享给我们的。


http://www.mmowned.com/forums/world-...mp-thread.html
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

Code:

; We make them Global so that every function can access them and Constant so they cannot be changed by the program

;注释:定义这些变量为全局变量,以使所有函数可以访问。定义这些变量为固定变量,以使它们不会被我们的程序更改。

 

;The first 2 are you create you manager from the baseaddress wow

;注释: 用下面两个变量(wow起始地址)去创建管理器

Global Const $ClientConnection = 0x8BF1A8

Global Const $CurMgrOffset = 0x462C

;The next one is to get the address of your first object ONLY

;注释:下面的偏移量去得到第一个对象

Global Const $FirstObjectOffset = 0xB4

line-height: 9pt; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-color: initi

   发表时间:2012-03-22  
X,被SB网站截断了
去我博客看吧:http://zeroblue.iteye.com/admin/blogs/1461469
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics