Main

Network Home

Related Sites
 - Diablo 1
 - Diablo 2 & Exp
 - Diablo Topsites
 - Diablo Top 200

Make Money By
Playing Video Games


Got Old Games?
SaySwap.COM
$5 Game Trades!


News
Topsites
MMORPGExposed
Forums
Cheats DB
Contribute
Donations
Admins Needed
Support
FilePlanet Login
Advertisers
Legal Info
Privacy Statement
Network FAQ
Contact Us

Diablo 1

Content - Expand

Diablo 2 & Exp Files

Versions & Patches
Demo
Items
Hacks 1.11b
Bots 1.11b
Utilities 1.11b
Mods
Wallpaper

D2 & D2x Archives

Cheats
Without Maphack!
Hacking Diablo 2
Packet Sending
D2 Clone Guide
Annihilus Guide
Hellfire Charm Guide
Inferno Charm Guide
Uber Boss Strategy
Standard of Heroes
Mercenary Guides
Character Guides
Program Guides
Horadric Cube
Gem Properties
Character Skills/Info
Uber Bosses Stats
D2 Quests
D2x Quests
Runes
Rune Words
MFing & The Pits
Rerolling Charms
Item Guides
Cast & Hit Rates
Wound-Strike-Blow
Item Pre/Suf
D2 Backup Disks
CD Errors/Fixes

Battle.Net Info

1.11b Updates
Your Own Server
CD-Key/Account Bans
BNet Connection Fix
System Lag Fixes
Got Hacked?
Realm Status
Realm Down Fix
B-Net Commands

Diablo 2 Info

Diablo 2 Story
Diablo 2 Shrines
Diablo 2 Item Info
Diablo 2 Town & Act
Diablo 2 NPC's
Diablo 2 Inventory
Diablo 2 Multiplayer

Diablo 2 Exp Info

D2x Story
D2x Crafted Items
D2x Jewels
D2x Charms
D2x Controls
D2x NPC's
D2x Monsters

Game Info & FAQ's

D2x New Features
D2x Requirements
Blizzard D2x FAQ

Important Links

Blizzard.com
Battle.Net

 
Affiliates

Affiliate with us?





Hacking Diablo 2

by: Jan Miller

Requirements

-C Language basic knowledge
-x88 intel ASM basics
-Windows API / Windows programming basic knowledge
-OllyDbg (You can get it here: http://www.ollydbg.de/ - but if you don't have it yet, you might aswell just skip this paper for the moment *g*)

.. and most importantly: Diablo II: Lord of Destruction with v1.11 Patch


General Introduction

This paper is going to be the first of a series of papers I plan to publish in the future. The series of papers has been designed for "regular coders" that are at interest to enhance their knowledge in the field of game-hacking. That means: IF you're already an experienced game-hacker, this paper might be quite a bore for you ;-). I plan on increasing the difficulty with the upcoming papers, so essentially my readers can grow and increase their qualities while we walk the road. I will also do my best at keeping the language as clear and straightforward as possible.
--

OK, now that we've got that stuff out of the way, let's get things 'rollin. Today we will take a deeper look at the red life-ball that displays your life when hovering the mouse above it. We will essentially try to reverse engineer Diablo II functions along the way - figure out how everything works - and to finish it off, write a hack that will ALWAYS display the life above the red life ball! :-) This may seem like alot of work at first, but hopefully you will get the catch sooner or later. "Reverse engineering" isn't that hard, if you take your time and make sensable assumptions. In the end, you're basically re-constructing a crime, sort-of like Sherlock holmes :-).


Chapter I - The Theory

Why do we need to find an entrypoint? Well, Diablo II has a few million lines of code, so we should try to imagine how the code-flow in Diablo II will probably be looking like, that draws the "Life: Min/Max" text above the red ball. In the end, all Diablo II functions will boil down to the basic system functions, so they will be our entry-point.

First, let's use our well-functional brain and gather some basic information, before starting (note: Using a moment of silence to think about the problem before tackling it, will be referred to as the "zen approach").


What do we know about text-drawing in Diablo II?

1) Diablo II is an international game that is sold in asian countries aswell. We assume that they handle strings in UNICODE format, to support countries such as "Korea"
2) In order for Diablo II to draw a text at a specific location, it needs to gather infos about the text it is drawing and where it is drawing. The infos gathered will be: "String length", "Screen Dimensions", "Text Color", etc.

What do we know about the red ball?

The most important fact about the life being drawn above the red ball is that the text is centered. The life of a player is variable, so the string length of the "Life: Min/Max" string will be variable aswell. So, in order for Diablo II to draw that string, it needs to somehow calculate its string-length - that is definate!

OK, so in this case I will use the fact that Diablo II needs to calculate the string length as our approach to get an entrypoint into a code-location that is near the "Draw Life to screen" function. This is the code-flow that I am assuming:
 
-> Diablo II gets mouse info
-> Diablo II checks if mouse is hovering the life ball
-> Diablo II calculates the players life
-> Diablo II sets up the output string (we will probably see a referrence to d2lang.dll here, as the Prefix may be "Life", "Leben" or any other language-dependent output)
-> Diablo II will print the string to the screen
---> Diablo II will calculate the string length in here, somewhere (THIS IS OUR ENTRYPOINT!!)

So basically, we will be breaking into Diablo II's code very deeply and use the stack to "walk back" to the callee functions. More to that later!


Chapter II - The Approach

So, fire up Diablo II and join a singleplayer game. That's my "preferred" environment for Diablo II reversing, as you will not "timeout" from a game if it's paused for too long (unlike battle.net, where you will be booted from the server for missing ping responses).

Alright, after you joined a singleplayer game and successfully attached OllyDbg to Diablo II, let your mouse hover over the life-bar so Diablo II's code passes the "IsMouseHoveringBall" check and actually draws the life. As soon as your mouse is hovered above the life-ball, use alt-tab to tab back to olly (be sure to not move your mouse before tabbing out of Diablo II). This is necessary, because we want Diablo II to save our mouse-position above the ball. The next time we maximize Diablo II the "IsMouseHoveringBall" check will pass and the code location's we breakpointed will be executed.

We will now try to find the "string-length" function as suggested in Chapter I and set an execution breakpoint there. You should have Diablo II minimized with your mouse hovering over the life-ball with ollydbg attached to the process before following these steps.

1) Press ALT-E to open the module list of Diablo II (lists all .dll files that Diablo II is using)
2) Find d2lang.dll and select it. Now Press CTRL-N to get a list of imported/exported function names
3) Find the mangled "strlen(UNICODE)" function and set an execution breakpoint (F2)

Image Example

4) Now we are ready to maximize Diablo II, do so. You should be breaking at the strlen function now. Obviously, this function is being called by many different functions in Diablo, so you should press F9 (run) so many times until you actually see the "Life: Current/Max" string in the ECX register (used as parameter, if you take a close look at the function). You should eventually end up looking at something like this:

Image Example

Note: It displays "Leben" instead of "Life" in the screenshot, because I am using the german d2lang.dll

5) Now take a look at the stack, it should be looking like this:

Image Example

As we can see, the d2lang.strlen(UNICODE) function is being called by D2Win.6F8EDFB9, which is probably inside the "TextDraw" function (we are making this assumption, based on the code-flow we created in Chapter I). We can also see, that the *supposed* "TextDraw" function is being called by a function in D2CLIENT (the second return address in the stack, see picture above).

6) Right-click the second return address in the stack and select the "Follow in Disassembler" option in the drop-down menu. You should now be at this code location:

Image Example

As you see, I've commented it abit. At this point (now that we know where the "TextDraw" for the life-ball hover-text is called) you should clear the breakpoint on the string function and set a new one abit futher above the new code location we found and repeat the process of maximizing Diablo II and breaking at the new location you chose. Do that until you understand what is going on and can make judgements about what the code is actually doing.

On a side note: We can derrive from the analysis of the d2lang.#10005 function call, that the function has this syntax:

typedef wchar_t* (__stdcall* fnGetLangStringByID) (DWORD dwID)

7) Now that we know what function actually draws the text, let's investigate how Diablo II actually gets the players life. Clear all your current execution breakpoints and make a new one at d2client.6FADD6C0 (the first instruction of the "DrawLifeAboveLifeBall" function). Restart the entire process (press F9 to let d2 execute itself, maximize d2 and then move your mouse over the life ball so olly breaks) so we can get a fresh start.

8) Now that we breaked at d2client.6FADD6C0 let's follow the code-flow and learn how Diablo II gets the players life. To do this, it'd be a good idea to get the hex-value of your current (and max) life. In this case, the hex value is: 0x2C (45 decimal). IF you really don't know what you're doing, you just follow the code flow by single-stepping (with F7) until the EAX register (which holds the return value of a function) returns our life, which is 0x2D (all values in ollydbg are displayed in hexadecimal). The first referrence of our current life is found here:

Image Example

As you can see in the image, EAX holds the value 0x2D00 and is (a few instructions later) shifted to the right by 8 bits, which would result in 0x2D. IF you remember, our current life is 0x2D! BINGO!

We can now derrive from the analysis the following functions:

typedef DWORD (__fastcall* fnGetOwnPlayerStat) (DWORD StatID) //d2client.6FADCCC0 param passed in EAX!
typedef DWORD (__stdcall* fnGetMaxLifeFromUnit) (unit* ptrToUnit) //d2common.#10907

As you know, __stdcall passes the parameter on stack and __fastcall passes the first two parameters in ECX and EDX, the rest on stack. ODDLY enough though, the "GetOwnPlayerStat" function passes the parameter in the EAX register, which is very uncommon. This is the case, because Blizzard changed their compiler settings to call functions in a very optimized way (MSVC++ 7.0 might've been the cause). The only way we can actually call the function is to build a "wrapper" that adjusts the parameters for us. You'd call "GetOwnPlayerStat" like this:

DWORD __declspec(naked) __fastcall GetOwnPlayerStatWrapper(DWORD StatID) {
__asm { mov eax, ecx //first parameter is in ECX, so we move it to EAX, as the D2 function requires it
call fnGeOwnPlayerStat
ret
}
}

9) Now that we have completed the analysis, let's move on to our actual goal: Making a hack that always enables the life display above the life-bar, irregardless if the mouse is hovering. We're taking the same approach as in step 5) - we will breakpoint at the first instruction of the "DrawLifeAboveLifeBall" function, let olly break at it, and check out the stack as to who is calling us. Then we will investigate at -what condition- we are being called. It turns out, that actually the function is called *no matter where our mouse is located* - so the conditional check has to be somewhere between the first instruction (d2client.6FADD6C0) and the call that gets our current life (d2client.6FADD742). A little "guessing work" will make us come up with these results:

Image Example

10) Now that we know where the actual check happens, we can circumvent it easily. A possibility to do so is to add an unconditional jump at d2client.6FADD710, as shown in the image:

Image Example


Chapter III - Writing the hack

Basically, to make the hack that displays the life above the life-bar at all times, we have to only change 2 bytes in Diablo II's code. We need to write 0x2BEB at d2client.6FADD6C0. You could achieve that by changing the memory protection of that memory page to EXECUTE_READ_WRITE and calling WriteProcessMemory - or just simply overwriting the location. Your .dll file could look like this (very dirty code):

BOOL WINAPI DllMain(HINSTANCE hDll,DWORD dwReason,LPVOID lpReserved)
{
	switch (dwReason) {
  case DLL_PROCESS_ATTACH:
  	*(WORD*)&0x6FADD6C0 = 0x2BEB;
//enable life display above life-bar at all times

  	break;
  case DLL_PROCESS_DETACH:
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  default:
  	break;
	}
	return TRUE;
}

This would actually do the job. Detectability is another issue, but that is not the aim of this essay. We might address that in another future edition.




Top Links

Webmasters: Make Money Online By Automating Your Website & More - Secrets Shared VIA Blog

World Of Warcraft Gold - Strategies You Might Not Know About

Sponsored Links
Topsites

Recent Forum Activity
Statistics
The Time Is:
9/21/14 9:11:08pm
Your IP Is:
54.87.93.1


Network
Network Main
Extreme-Gamerz.Org
Gamegate2k.Com
GG2k Fourms
Topsites - NEW

RPG
-Diablo 1
-Diablo 2
  -Lord Of Destruction
-Diablo Top 200 List

Action
-Half-Life
  -Counter-Strike
  -Day Of Defeat
  -Firearms
-Half-Life 2
-Freelancer
-IGI 1: Project IGI
-IGI 2: Covert Strike
-Medal Of Honor: AA
  -MOH: Spearhead
  -MOH: Breakthrough
-Unreal
  -Unreal Tournament
  -UT 2003
  -Unreal 2
-RTC Wolfenstein
  -Enemy Territory

Strategy
-Starcraft
  -Brood War
-Warcraft
  -Warcraft 2
  -Warcraft 3
  -Frozen Throne
  -World Of Warcraft
Advert

Layout,Images, and Content copyright to Gamegate2k.Com and its Owner
May not be reproduced in part or whole without permission.  See the Disclaimer for more info.
Page Loaded In: 0.56 | Design: DigitalIceDesigns.Com | Marketing: Rob Malon [Dot] Com