MMOwned - World of Warcraft Exploits, Hacks, Bots and Guides

Homepage Register FAQ Members Mark Forums Read Advertise Marketplace FPSowned
Go Back   MMOwned - World of Warcraft Exploits, Hacks, Bots and Guides > World of Warcraft > Bots and Programs > WoW Memory Editing
Reload this Page Proof of Concept: dwFindPattern TLS [C#]
WoW Memory Editing WoW Memory Editing for learning purposes only.

Reply
 
LinkBack Thread Tools
Proof of Concept: dwFindPattern TLS [C#]
(#1)
Old
Shynd's Avatar
Shynd is Offline
Master Sergeant
Rep Power: 1
Reputation: 18
Shynd is on a distinguished road
 
Posts: 73
Join Date: May 2008
Proof of Concept: dwFindPattern TLS [C#] - 05-30-2008

Truth be told, ever since WoW!Sharp, I haven't hacked/disassembled/whatever WoW in any way, shape, or form (except for writing a teleporter for an EMU server, big whoop). I've never worked with TLS--nor am I even really sure what it stands for, to be honest--before today, but I've kinda decided that I want to try to catch up with the whole scene.

I've read almost every thread I could get my hands on over the past 24-48 hours, and have compiled and run many, many different PoCs or examples. From what I can tell, the first step in making a bot--or anything, really--is to find the s_curMgr, which allows you to loop through loaded objects (including your character?). I've seen people left in the dust when their "TLS Pointer" is outdated due to client updates, so I set out to solve that problem--or, at the very least, make it easier to solve. Enter: dom1n1k's dwFindPattern (external C# version).

([Only registered and activated users can see links. ])
Code:
using System;
using System.Collections.Generic;
using System.Text;
using MemoryLib;

namespace ExternalFindPattern
{
	class Program
	{
		static void Main(string[] args)
		{
			DateTime now = DateTime.Now; //used for testing how long it takes to find the tls pointer
			System.Diagnostics.Process.EnterDebugMode(); //gives our program debug permissions

			//open wow for read/write
			IntPtr hProcess = Memory.OpenProcess(Memory.GetProcessIdByProcessName("wow.exe"));
			//if open process was successful
			if (hProcess != IntPtr.Zero)
			{
				//search for the code pattern that we want (in this case, WoW TLS)
				uint tlscode = dwFindPattern(hProcess, 0x410000, 0x400000,
					"EB 02 33 00 64 8B 15 2C 00 00 00 8B 0D 00 00 00 00 8B 0C 8A",
					"xxx?xxxxxxxxx????xxx");

				//read Kynox's g_clientConnection from memory
				uint g_clientConnection = Memory.ReadUInt(hProcess, Memory.ReadUInt(hProcess, (tlscode + 0x16)));
				//first, the offset for the curMgr inside g_clientConnection is read,
				//then s_curMgr is read from g_clientConnection + that offset (which may change version to version,
				//I honestly don't know)
				uint s_curMgr = Memory.ReadUInt(hProcess, (g_clientConnection + Memory.ReadInt(hProcess, tlscode + 0x22)));

				//output to console
				Console.WriteLine("TLS code: 0x{0:X08}ng_clientConnection: 0x{1:X08}ns_curMgr: 0x{2:X08}", tlscode, g_clientConnection, s_curMgr);

				Memory.CloseHandle(hProcess);
			}

			//tell user how long it took to find and get what we wanted
			TimeSpan timer = DateTime.Now.Subtract(now);
			Console.WriteLine("nnTime taken: {0}msnnPlease press [ENTER] to continue...", timer.Milliseconds);
			Console.ReadLine();
		}

		#region dwFindPattern
		//blatantly adapted/copied from dom1n1k :)
		static bool bDataCompare(byte[] data, int index, byte[] pattern, string mask)
		{
			if (pattern.Length != mask.Length) return false;

			for (int i = 0; i < pattern.Length; i++)
				if (mask[i] == 'x' && (data[index + i] != pattern[i]))
					return false;

			return true;
		}

		//blatantly adapted/copied from dom1n1k :)
		static uint dwFindPattern(IntPtr hProcess, uint start, int length, string _pattern, string mask, char delimiter)
		{
			string[] p = _pattern.Split(delimiter);
			byte[] pattern = new byte[p.Length];
			for (int i = 0; i < p.Length; i++)
				pattern[i] = Convert.ToByte(p[i], 16);

			const int bytestoread = 1024;

			int index = 0;
			byte[] buf;

			if (bytestoread > length)
			{
				buf = new byte[length];
				Memory.ReadMemory(hProcess, start, ref buf);
				for (int i = 0; i < (buf.Length - pattern.Length); i++)
					if (bDataCompare(buf, i, pattern, mask))
						return (uint)(start + i);
			}
			else
			{
				while (index < length)
				{
					buf = new byte[bytestoread + pattern.Length];
					Memory.ReadMemory(hProcess, start + index, ref buf);
					for (int i = 0; i < bytestoread; i++)
						if (bDataCompare(buf, i, pattern, mask))
							return (uint)(start + index + i);

					index += bytestoread;
				}
			}

			return uint.MaxValue;
		}

		static uint dwFindPattern(IntPtr hProcess, uint start, int length, string _pattern, string mask)
		{
			return dwFindPattern(hProcess, start, length, _pattern, mask, ' ');
		}
		#endregion
	}
}
Now then, this serves two purposes:
  • Gives a program the ability to look for patterns (useful for making your program either update itself or completely ignore client version) without injecting anything into the client.
  • Finds Kynox's g_clientConnection and, subsequently, the s_curMgr externally, allowing the program to loop through loaded objects, regardless (hopefully?) of client version.

In order to use this in the leechtastic, copy+paste way, you'll need my MemoryLib class library, located [Only registered and activated users can see links. ]. Source is included, though it's a bit rough around the edges and nowhere near finished (I've worked on it for a few hours here or there for nearly a year).



Kynox, Bobbysing, UnknOwned: you guys have been doing this longer than I have, so, please, point out what I'm doing wrong, what I could be doing better, and/or any suggestions you might have, up to and including what should be my next step, in your opinion, towards a bot. I've got a few ideas of my own, but I'm really in over my head with information, at the moment. If you wouldn't mind helping me learn what it is I need to learn, I'd love the opportunity to pick your brain(s) about certain things. Let me know.



Anyway, there's my first contribution with (hopefully) more to come as I learn and feel more comfortable. See the second post in this thread for a better explanation of what's going on in my code.




CREDITS:
dom1n1k
Kynox
bobbysing
Anyone else that I forgot: I'm sorry. I've read a lot of threads and gleaned a lot of information from many different sources. Please, let me know if I've forgotten anyone.

Last edited by Shynd; 05-31-2008 at 01:02 PM. Reason: added credits
Reply With Quote

Donate to remove ads.
Further explanation...
(#2)
Old
Shynd's Avatar
Shynd is Offline
Master Sergeant
Rep Power: 1
Reputation: 18
Shynd is on a distinguished road
 
Posts: 73
Join Date: May 2008
Further explanation... - 05-30-2008

Okay, on line 21:
Code:
uint tlscode = dwFindPattern(hProcess, 0x410000, 0x400000,
	"EB 02 33 00 64 8B 15 2C 00 00 00 8B 0D 00 00 00 00 8B 0C 8A",
	"xxx?xxxxxxxxx????xxx");
This searches for what I've determined to be the easiest portion of WoW game code from which to glean the largest amount of information. In 2.4.2, it looks a bit like this:
Code:
00778D1B  |. 6A 00              PUSH 0                                   ; /Arg1 = 00000000
00778D1D  |. 8BC8               MOV ECX,EAX                              ; |
00778D1F  |. E8 ECE8FFFF        CALL <Wow.CGCurMgr_C>                    ; Wow.00777610
00778D24  |. EB 02              JMP SHORT Wow.00778D28
00778D26     33C0               XOR EAX,EAX
00778D28     64:8B15 2C000000   MOV EDX,DWORD PTR FS:[2C]
00778D2F  |. 8B0D 84AAE800      MOV ECX,DWORD PTR DS:[E8AA84]
00778D35  |. 8B0C8A             MOV ECX,DWORD PTR DS:[EDX+ECX*4]
00778D38  |. 8B15 B095D400      MOV EDX,DWORD PTR DS:[D495B0]
00778D3E  |. 8981 10000000      MOV DWORD PTR DS:[ECX+10],EAX
00778D44  |. 8982 18220000      MOV DWORD PTR DS:[EDX+2218],EAX
00778D4A  |. A1 B095D400        MOV EAX,DWORD PTR DS:[D495B0]
Line 21 should find the pattern that starts at 0x00778D24, or JMP SHORT Wow.00778D28. That is where we will start gathering information.

Line 26 has two memory reads on it. In simplistic terms, it looks more or less like so: [[0x00778D24 + 0x16]] = g_clientConnection. It reads from tlscode+0x16 (0x00778D3A), which contains 0x00D495B0, and then reads from 0xD495B0 to get the address of g_clientConnection. My hope is that the pointer to g_clientConnection will always be 0x16 bytes from where my pattern is found and, therefore, will update itself with each new client.

Line 30 has two more memory reads on it. [g_clientConnection + [tlscode+0x22]] = s_curMgr. Basically, I'm not taking chances that the offset from g_clientConnection to the s_curMgr pointer will always stay the same, so I read the offset from memory at tlscode+0x22 (0x00778D46). Hopefully this will solve some client update issues, as well, though it's less likely. Never hurts to be safe, though.

Seriously, I have no idea if any of this helps in any way, as I've never had things break during a client update (seeing as I'm starting from scratch with today as my first day). All I'm trying to do is fix problems I've had happen to me in other games when clients update and hope that WoW will act the same way. I'm sure someone will correct me if I'm wrong--in fact, I'm hoping for it .


Afterthought: an image says a thousand words?
Reply With Quote
(#3)
Old
kynox's Avatar
kynox is Offline
Creator of the ME fix

Rep Power: 5
Reputation: 513
kynox is a glorious beacon of lightkynox is a glorious beacon of lightkynox is a glorious beacon of lightkynox is a glorious beacon of lightkynox is a glorious beacon of lightkynox is a glorious beacon of light
 
Posts: 238
Join Date: Dec 2006
Location: Raping your Stack
05-30-2008

Nice work dude!


Do not PM me about the ME fix or other ME questions
Reply With Quote
(#4)
Old
Shynd's Avatar
Shynd is Offline
Master Sergeant
Rep Power: 1
Reputation: 18
Shynd is on a distinguished road
 
Posts: 73
Join Date: May 2008
05-30-2008

Nothing you would change?
Reply With Quote
(#5)
Old
ShoniShilent is Offline
Site n00b.. (A leecher if I've been here for more than a month and can't earn 5 rep)
Rep Power: 1
Reputation: 3
ShoniShilent is an unknown quantity at this point
 
Posts: 43
Join Date: May 2008
05-30-2008

another location is here:


0077624E CC INT3
0077624F CC INT3
00776250 55 PUSH EBP
00776251 8BEC MOV EBP,ESP
00776253 A1 84AAE800 MOV EAX,DWORD PTR DS:[E8AA84]
00776258 64:8B0D 2C000000 MOV ECX,DWORD PTR FS:[2C]
0077625F 53 PUSH EBX
00776260 56 PUSH ESI
00776261 8B3481 MOV ESI,DWORD PTR DS:[ECX+EAX*4]
00776264 8B86 10000000 MOV EAX,DWORD PTR DS:[ESI+10]
0077626A 05 A8000000 ADD EAX,0A8
0077626F 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4]
00776272 A8 01 TEST AL,1
00776274 57 PUSH EDI


with the:

00776253 A1 84AAE800 MOV EAX,DWORD PTR DS:[E8AA84]
00776258 64:8B0D 2C000000 MOV ECX,DWORD PTR FS:[2C]

being the most important location.

theres a lot of stable (non-changing) code around that spot as well.

best,
Cal
Reply With Quote
(#6)
Old
Shynd's Avatar
Shynd is Offline
Master Sergeant
Rep Power: 1
Reputation: 18
Shynd is on a distinguished road
 
Posts: 73
Join Date: May 2008
05-31-2008

Here's a post I made on a website for a different game that may explain dwFindPattern usage better, for those of you who aren't already acquainted with it: [Only registered and activated users can see links. ]. You shouldn't have to register to view it.
Reply With Quote
Reply


Donate to remove ads.

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are On




Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO 3.1.0
vBulletin Skin developed by: vBStyles.com


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318