D2Template

This forum is for discussions on how to edit what can not be edited through the txt files, needless to say this isn't about battle net hacking.

Moderators: Nefarius, Havvoric

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

D2Template

Post by kidpaddle94 » Mon Feb 23, 2015 3:20 pm

D2Template
D2Template is a project that was developed in order to help modders getting started into advanced code editing on Diablo II. D2Template provides a basic and relatively simple C++ source code, ready to be injected in-game in order to achieve advanced edits using your own injected source code. The template itself does not achieve any edit. It only provides you a starter kit for you to make your own edits. That is, the template itself is version independent, until you add code to it of course.

This is a community project, and therefore, any improvement suggestion is welcome. Anything I consider to be a valuable addition/modification will be added to the distributed version, with credits given nonetheless.
** WARNING **

There is currently no documentation available for this project. I currently don't have any time for this, and likely never will in a near future. That is, you are free to use this template and mess around with it, but do not message me any question about it, I will not reply. I do hope some more advanced users, that use this template for their project will write the documentation, but meanwhile, you are on your own. What you do with this template is up to you and only concerns you, but any question should still follow the site's rules.
What does the template include exactly?

To start off, a patcher. This is pretty much the basic of basics, as you need to inject your code into the game at some point, right? You do not need to get into complicated memory patching coding, the template does it for you. Then you have some various utility files, for pointers importing from the game's library, variables declaration, etc.

What do I need to use this template?

The template was created and compiled with Visual Studio 2012, so it is better if you get Visual Studio 2012 (or just Visual C++ 2012). It is in theory possible to get the template to work with any other IDE but you will not get any support on this from me. Tutorials/Modified templates for other IDE are welcome.

What should I know before using this template?

First of all, get started with the basics of C/C++. Get used to the syntax, practice by creating basic programs, get at least a basic knowledge of the language. Next, get used with the IDE you're going to use to work with this template. And finally, basic ASM knowledge can also help you a lot.
Last edited by kidpaddle94 on Thu Mar 30, 2017 10:59 pm, edited 9 times in total.

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Mon Feb 23, 2015 3:20 pm

Documentation
D2Template core documentation [ WIP ]
User submitted tutorials

Plugins/Utilities/Etc

( Currently none available )
Last edited by kidpaddle94 on Tue Jun 23, 2015 4:38 pm, edited 8 times in total.

User avatar
kingpin
Retired Admin
Cherub
Posts: 10954
Joined: Sat Jan 11, 2003 12:51 pm
Contact:
Sweden

Hand-picked

Re: D2Template

Post by kingpin » Mon Feb 23, 2015 3:56 pm

Be aware that use visual studio 2012 will make your project not winxp compatible.

If you have patches up your visual studio 2012 to latest patch you can make it winxp compatible with some restrictions, you can read about it here

To keep full xp compability I would suggest go back to compile it with visual studio 2010 instead.

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Mon Feb 23, 2015 9:37 pm

kingpin" wrote:Be aware that use visual studio 2012 will make your project not winxp compatible.

If you have patches up your visual studio 2012 to latest patch you can make it winxp compatible with some restrictions, you can read about it here

To keep full xp compability I would suggest go back to compile it with visual studio 2010 instead.
The source code itself doesn't have any 2012 dependent code, actually I was using 2010 edition myself not long ago. Besides, Windows XP is no longer supported by Microsoft, and we keep seeing more and more programs that ditch the XP compatibility. I myself recently upgraded to Windows 7 a few months ago, for this reason. I think it's time to move on.

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Mon Feb 23, 2015 9:49 pm

Injection Methods
Here you will find various injection methods, that will allow you to load your compiled template in-game. You're welcome to post your own, and have it added to this post.

PlugY 10.00 By Yohann

Version: 1.09D to 1.13c
Type: External Plugin

For more information & downloading, see this thread
The source code for this plugin is also available. (see the previously linked thread)

Once you have PlugY installed, you can have it load your compiled code, via the configuration file, PlugY.ini.
See the setting named "DllToLoad" under the [GENERAL] section of the configuration file, and add your dll there:

Code: Select all

[GENERAL]
//...
DllToLoad=D2Template.dll
//...
------------------------------------------------------------------------------

D2Mod By SVR

Version: 1.10F
Type: External Plugin

To download D2Mod, click here
For information, installation instructions, see this thread

Once you have D2Mod installed and configured, all you have to do is add the following to your D2Mod.ini configuration file, under the [D2MOD] section

Code: Select all

D2Template=D2Template.dll
------------------------------------------------------------------------------------

D2SE By SeltSamuel

Version: 1.09 to 1.13c
Type: Launcher Replacement

To download and get more information about D2SE, see this thread
Once you have installed D2SE and got your mod plugin ready to go, open up your mod's configuration file, D2SE.ini, and under the [Protected] section, add the following:

Code: Select all

ModDll1=D2Template.dll
---------------------------------------------------------------------------------------

Modified D2Win By Kidpaddle94

Version: 1.13c
Type: Game Library Replacement

Click here to download

This one replaces D2Win.dll with a modified one. This one has been patched to load D2Template.dll. The patch is done at the end of the MPQ loading routine, D2Win.#10086. This one is meant to be used on 1.13c only as it is a 1.13c D2Win.dll


---------------------------------------------------------------------------------------

Modified Fog By Kidpaddle94

Version: 1.13c
Type: Game Library Replacement

Click here to download

This one replaces Fog.dll with a modified one. This one has been patched to load D2Template.dll. The patch replaces an unused Fog ordinal, Fog.#10082. This is one of the very first calls in game.exe. This one is meant to be used on 1.13c only as it is a 1.13c Fog.dll
Last edited by kidpaddle94 on Thu Mar 30, 2017 9:40 pm, edited 7 times in total.

User avatar
Xibalba
Dark Alliance Beta Test
Champion of the Light
Posts: 283
Joined: Thu Aug 29, 2013 2:38 pm
Location: Skyrim

Re: D2Template

Post by Xibalba » Mon Feb 23, 2015 9:56 pm

Good news :) Its better than injecting from D2Win. Ill try with plugy soon (i hope)
Life is too short to drive boring cars.

User avatar
Mnw1995
Junior Member
Paladin
Posts: 100
Joined: Sat Apr 02, 2011 6:28 pm

Re: D2Template

Post by Mnw1995 » Mon Feb 23, 2015 10:15 pm

On 1.10 it can also be loaded by D2Mod.dll..

User avatar
kingpin
Retired Admin
Cherub
Posts: 10954
Joined: Sat Jan 11, 2003 12:51 pm
Contact:
Sweden

Hand-picked

Re: D2Template

Post by kingpin » Mon Feb 23, 2015 11:16 pm

also inject the dll from d2win is better then plugy do (d2gfx.dll) because injection in d2win.dll is the earliest you should do it. because loadmpq function (where I inject my d2win.dll hardcoded dll load) is called directly from game.exe instead of at later point as d2gfx.dll is.

But, if you already using d2mod/plugy there is no reason to use hardcoded dll load yourself. that's just extra work you don't need to do.

User avatar
seltsamuel
Posts: 80
Joined: Sat Feb 10, 2007 8:52 am

Re: D2Template

Post by seltsamuel » Mon Feb 23, 2015 11:27 pm

Hi,

D2SE loads it in every D2 Version.

Greetings

Seltsamuel

User avatar
Mnw1995
Junior Member
Paladin
Posts: 100
Joined: Sat Apr 02, 2011 6:28 pm

Re: D2Template

Post by Mnw1995 » Tue Feb 24, 2015 11:24 am

seltsamuel" wrote:Hi,

D2SE loads it in every D2 Version.

Greetings

Seltsamuel
It does..

Sadly, it also generates this error at game startup:

Image

This is why I asked you to change the loading code a little bit in the next version of D2SE ;)

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Tue Feb 24, 2015 2:33 pm

Mnw1995" wrote:It does..

Sadly, it also generates this error at game startup:

This is why I asked you to change the loading code a little bit in the next version of D2SE ;)
As far as I remember, D2SE calls a pre-defined ordinal once it loads the library. If it fails to call it, this errors pops.
I guess it's for initializing stuff, but that's unnecessary and undocumented. That's one of the reasons my project no longer uses D2SE (unless an update is done and fixes these kind of annoyances)

User avatar
seltsamuel
Posts: 80
Joined: Sat Feb 10, 2007 8:52 am

Re: D2Template

Post by seltsamuel » Tue Feb 24, 2015 6:37 pm

Hi,

no looks as you are trying to use D2SE dll loader.. this calls functions specific to the d2se modsystem that is used by my mod but is unreleased until now..
What you want to use is the custom dll loader.. which calls no ordinal or function of the dll but you have to write the dll selfiniting (on attach).
The next D2SE Version will have a enhanced dll loader with more features but using the custom loader should be enough for now to fire up upto 3 custom dlls.

Greetings

Seltsamuel

User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

Re: D2Template

Post by Necrolis » Tue Feb 24, 2015 6:49 pm

Run build->clean your project and delete the sdf file before you package, strips away 95%+ of the size, also you shouldn't really include the suo file but that doesn't matter.
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

User avatar
Mnw1995
Junior Member
Paladin
Posts: 100
Joined: Sat Apr 02, 2011 6:28 pm

Re: D2Template

Post by Mnw1995 » Tue Feb 24, 2015 7:00 pm

seltsamuel" wrote:Hi,

no looks as you are trying to use D2SE dll loader.. this calls functions specific to the d2se modsystem that is used by my mod but is unreleased until now..
What you want to use is the custom dll loader.. which calls no ordinal or function of the dll but you have to write the dll selfiniting (on attach).
The next D2SE Version will have a enhanced dll loader with more features but using the custom loader should be enough for now to fire up upto 3 custom dlls.

Greetings

Seltsamuel
So either the dll is not selfiniting or I am too dumb to set up the .ini..

When I use it like this

Code: Select all

#D2SE 1=load and init D2SE on startup
ModUseD2SE=0
#Name of the D2SE Mod dll 32 Chars maximum
D2SEDllName=D2Exp.dll
my dll is not loaded..


And when I use it like this

Code: Select all

#D2SE 1=load and init D2SE on startup
ModUseD2SE=1
#Name of the D2SE Mod dll 32 Chars maximum
D2SEDllName=D2Exp.dll
my dll is loaded, but the error appears


Well, I can use D2Mod to load my dll until the next version of D2SE will be released ;)

User avatar
kingpin
Retired Admin
Cherub
Posts: 10954
Joined: Sat Jan 11, 2003 12:51 pm
Contact:
Sweden

Hand-picked

Re: D2Template

Post by kingpin » Tue Feb 24, 2015 8:15 pm

Are you running winxp or win7?

If you are running winxp, are you compile the code with visual studio 2012 or newer?

I notice my code could load the dll in it's own, but with d2se it do seems it inject the dll differently as I had issues with dreamland to work with d2se (with vs studio 2012, even patched up and setup to support winxp).

I fixed the issues by go back to use visual studio 2010. Then d2se could load it fine.

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Wed Feb 25, 2015 2:32 am

Necrolis" wrote:Run build->clean your project and delete the sdf file before you package, strips away 95%+ of the size, also you shouldn't really include the suo file but that doesn't matter.
Yeah, I do know that, I just uploaded the whole folder in a rush. Will update and hopefully add some basic documentation on Thursday.

User avatar
seltsamuel
Posts: 80
Joined: Sat Feb 10, 2007 8:52 am

Re: D2Template

Post by seltsamuel » Thu Feb 26, 2015 3:46 pm

Hi,

@kidpaddle94
my bad .. seems like this entry is not in the D2SE_SETUP.ini template in the documentation . but used in some plugins:
D2SE understands additional this lines for up to 3 custom .dll each mod.

ModDll1=mydll1.dll
ModDll2=mydll2.dll
ModDll3=mydll3.dll

The .dll must be selfiniting meaning patch the gamefiles and install the hooks on DLL_ATTACH (D2SE at this point has already load and inited all game .dll files and used modsystems. mpq system is inited/loaded and ready for usage.. no line of d2 is executed yet)

Example for selfinit:

DWORD WINAPI Selfinit(PVOID pvParam)
{
return ModInit(); // do whatever your code needs to install hooks and patch code.
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpvReserved)
{
DWORD IdHolder;

switch (fdwReason)
{
// If we are attaching to a process
case DLL_PROCESS_ATTACH: //do nothing wild here!!! use the thread or collisiondanger.
CreateThread(NULL, 0, Selfinit, NULL, 0, &IdHolder);
break;

case DLL_PROCESS_DETACH:
Uninstall_mymod(); //whatever your modifications need to get uninstalled
break;
};

//Return success
return TRUE; // this is important else loading dll will fail!
}


@kingpin
D2SE loads the dll as every other windows programm does too.. how did you try to use d2se to load your dll?

At the moment im working on a complete D2SE rewrite that will have groundbreaking new functions too.. for example to load all dlls from inside mpq and to render ASLR useless so old mods will work again under all windows versions (no random reallocation).. for this i replace the entire windows dll loader with own code that i try to get compatible with the one windows uses (still hitting my head on some things but i make progress)

Greetings

Seltsamuel

User avatar
Mnw1995
Junior Member
Paladin
Posts: 100
Joined: Sat Apr 02, 2011 6:28 pm

Re: D2Template

Post by Mnw1995 » Thu Feb 26, 2015 10:38 pm

seltsamuel" wrote:Hi,

@kidpaddle94
my bad .. seems like this entry is not in the D2SE_SETUP.ini template in the documentation . but used in some plugins:
D2SE understands additional this lines for up to 3 custom .dll each mod.

ModDll1=mydll1.dll
ModDll2=mydll2.dll
ModDll3=mydll3.dll

Greetings

Seltsamuel
I've really missed that you added those lines... Works like a charm now ;) Thanks!

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Fri Feb 27, 2015 4:34 pm

D2SE has been added to injection methods

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Fri Feb 27, 2015 5:22 pm

Overview of Core Files
D2Template comes with a few core files. This here is meant to explain what these files are meant to do, how and why they're meant to be used (or not used in some cases...).
DLLmain.cpp & DLLmain.h

These two files are the heart of the template. They contain the module entry point function (often referred to as DllMain), the patching code, the basic includes and definitions, etc. You shouldn't need to edit these two files at all, and shouldn't do so unless you know what you're doing. Chances are, if you get to a point where you need to edit these files, you will be at a point where you know what you're doing. (or at least I hope so).

D2Constants.h

This file is meant to declare all constants values you will be using in your code. Sometimes, using names instead of raw numbers is more convenient. This also has the advantage of making your code more flexible, as if this value needed to change for any reason, you would only have one place to edit, rather than having to edit every single places where you used this constant (that's what would happen if you used raw numbers)

The file already contains an example, probably some of the most used constants, the unit types

Code: Select all

enum D2C_UnitTypes
{
	UNIT_PLAYER,					//0x00 Players
	UNIT_MONSTER,					//0x01 Monsters
	UNIT_OBJECT,					//0x02 Objects
	UNIT_MISSILE,					//0x03 Missiles
	UNIT_ITEM,						//0x04 Items
	UNIT_TILE						//0x05 Tiles
};
With these constants declared, you could now replace the following code

Code: Select all

if (pUnit->dwUnitType == 0) // checks if unit is player type
Using your declared constant

Code: Select all

if (pUnit->dwUnitType == UNIT_PLAYER)
D2Structs.h, D2DataTables.h & D2PacketDef.h

As you add more and more code, you will get to see the game uses a various amount of structures, to represent various entities. Be it unit entities, game entities, they are all handled as structure pointers. You will need to declare these structures, in order to use them in your code. This file is meant to do so. The template ships with a few examples by default, although due to the fact structs often have their layout changed between versions, they were left empty.

D2DataTables and D2PacketDef are only an expansion to D2Structs.h, in order to keep your code a little more organized.

D2Ptrs.h

This file here allows you to import pointers from the original game's libraries. Be it function pointers to call within your own code, variable pointers to read data from the game within your code, or just address pointers for inline asm functions, this is all declared in this file.

D2Vars.h

This file is meant to declare your own global variables, not much more to say about it.

D2Patch.h & D2PatchConst.h

You should only be editing D2Patch.h here, unless you know what you're doing. D2PatchConst only defines a few constants for the patcher and you shouldn't need to edit it. D2Patch is where you will add your patches. This is how you actually implement your changes into the game. After all, we need to patch the game's code at some point to have our code executed, right?

TemplateIncludes.h

This is where you add any additional includes. As you add more source files to your code, you will likely need to include new headers. This is where it's done.

User avatar
Xibalba
Dark Alliance Beta Test
Champion of the Light
Posts: 283
Joined: Thu Aug 29, 2013 2:38 pm
Location: Skyrim

Re: D2Template

Post by Xibalba » Fri Feb 27, 2015 5:52 pm

Thanks! Really helpful. Cant wait for the other 2 guides.
Life is too short to drive boring cars.

User avatar
Lurix
Dark Alliance Beta Test
Champion of the Light
Posts: 496
Joined: Tue Aug 31, 2010 9:30 am
Location: Birmingham, UK
Bulgaria

Re: D2Template

Post by Lurix » Sat Mar 14, 2015 9:01 am

I have a few questions, before I start using the template.
As those are like my first steps in coding.
1) Do I need to make some edits to the template files, based on which D2Version I want to use?
From what I understand I should modify the D2Patch.h file?
2) As I advance in time, is every single code stored into one single DLL file? Or I can controll that?
3) Like I said, it`s like my first steps, so I`m going to try with something easy, like I will follow Joel`s Tutorial coming with D2External, for creating new usable items, but I`m not completely sure where to start from.

User avatar
devurandom
Forum Regular
Angel
Posts: 897
Joined: Sat Mar 07, 2015 9:07 pm
United States of America

Re: D2Template

Post by devurandom » Sat Apr 04, 2015 8:57 am

kidpaddle94" wrote: Besides, Windows XP is no longer supported by Microsoft, and we keep seeing more and more programs that ditch the XP compatibility. I myself recently upgraded to Windows 7 a few months ago, for this reason. I think it's time to move on.
Still using XP here. Have no reason to upgrade since XP POS systems are supported until 2019. By then I'll move to linux for Desktop OS.
Assembly Reference | 1.13d Code Edits | UVLoD | BaseMod Plugin

Fiat paper money is the most elaborate and well devised form of slavery the world has ever seen..

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: D2Template

Post by kidpaddle94 » Tue Jun 23, 2015 4:39 pm

Declaring code patches

Declaring code patches is the basic of the template. After all, we need to inject our code into the game code flow at some point if we want it to be executed, right? This is done by patching the executable's memory to change it's flow. The template does this for you, all you have to do is setup an array of patches declarations, which is done in D2Patch.h
Structure of the patch array

The structure of patch definitions should look like this:

Code: Select all

{ DLL, OFFSET, PATCH DATA, RELATIVE (bool), SIZE }
Now let's take a closer look at what every part of the array defines.

DLL: This defines in which of the game's library this patch should be applied. This is needed so that the template's patcher can retrieve the said library's base address (as the patcher uses relative addresses patch definitions, to keep compatibility in case of reallocation). The dll name definitions are found in DLLmain.h. It is also possible to extend this in order to have it patch custom libraries that are not defined in the original template but you shouldn't attempt this unless you know what you're doing.

Code: Select all

enum D2TEMPLATE_DLL_FILES
{
	D2DLL_BINKW32,
	D2DLL_BNCLIENT,
	D2DLL_D2CLIENT,
	D2DLL_D2CMP,
	D2DLL_D2COMMON,
	D2DLL_D2DDRAW,
	D2DLL_D2DIRECT3D,
	D2DLL_D2GAME,
	D2DLL_D2GDI,
	D2DLL_D2GFX,
	D2DLL_D2GLIDE,
	D2DLL_D2LANG,
	D2DLL_D2LAUNCH,
	D2DLL_D2MCPCLIENT,
	D2DLL_D2MULTI,
	D2DLL_D2NET,
	D2DLL_D2SOUND,
	D2DLL_D2WIN,
	D2DLL_FOG,
	D2DLL_GLIDE3X,
	D2DLL_IJL11,
	D2DLL_SMACKW32,
	D2DLL_STORM,
	D2DLL_PLUGY,
	D2DLL_D2SERVER,
	D2DLL_INVALID
};
OFFSET: This is the relative address at which the patch should be applied. Example, you want to patch something at D2Game.0x6FC25000, assuming the base address is 0x6FC20000, you would then set this part of the array as 0x5000.

SIZE: This here defines the number of bytes to patch. Setting this to 0 will make it patch a DWORD. You should use non-zero values only when you want to make big repetitive patches, such as nop blocks. Example:

Code: Select all

{D2DLL_D2CLIENT, 0x9A6F1, (DWORD)PATCH_NOPBLOCK, FALSE, 0x34},
This patch would look like this once applied:

Code: Select all

6FB4A6F1    90              NOP
6FB4A6F2    90              NOP
6FB4A6F3    90              NOP
6FB4A6F4    90              NOP
6FB4A6F5    90              NOP
6FB4A6F6    90              NOP
6FB4A6F7    90              NOP
6FB4A6F8    90              NOP
6FB4A6F9    90              NOP
6FB4A6FA    90              NOP
6FB4A6FB    90              NOP
6FB4A6FC    90              NOP
6FB4A6FD    90              NOP
6FB4A6FE    90              NOP
6FB4A6FF    90              NOP
6FB4A700    90              NOP
6FB4A701    90              NOP
6FB4A702    90              NOP
6FB4A703    90              NOP
6FB4A704    90              NOP
6FB4A705    90              NOP
6FB4A706    90              NOP
6FB4A707    90              NOP
6FB4A708    90              NOP
6FB4A709    90              NOP
6FB4A70A    90              NOP
6FB4A70B    90              NOP
6FB4A70C    90              NOP
6FB4A70D    90              NOP
6FB4A70E    90              NOP
6FB4A70F    90              NOP
6FB4A710    90              NOP
6FB4A711    90              NOP
6FB4A712    90              NOP
6FB4A713    90              NOP
6FB4A714    90              NOP
6FB4A715    90              NOP
6FB4A716    90              NOP
6FB4A717    90              NOP
6FB4A718    90              NOP
6FB4A719    90              NOP
6FB4A71A    90              NOP
6FB4A71B    90              NOP
6FB4A71C    90              NOP
6FB4A71D    90              NOP
6FB4A71E    90              NOP
6FB4A71F    90              NOP
6FB4A720    90              NOP
6FB4A721    90              NOP
6FB4A722    90              NOP
6FB4A723    90              NOP
6FB4A724    90              NOP
PATCH DATA: This is the data you want to patch. This can be a function, some bytes, whatever you want. This is explained further later in this tutorial.

RELATIVE: This tells the patcher whether it should consider this patch as a relative address. If you look at how calls or jumps work in ASM, you will notice it doesn't point directly to an address

Code: Select all

6FB4A6CE    E8 DD28FFFF     CALL D2Client.6FB3CFB0
Setting this to true will make the patcher handle this stuff on it's own so that we don't need to worry about it. So when patching function adresses basically, you set this to true. (in most cases)

--------------------------------------------------------------------------------------------------

Patch Defintions Examples

There's plenty of different stuff you can patch using the patcher, but here goes the main ones you will be using.
You will likely find out what other types of patches there is to make by yourself as you get better at code injection with the template.

Patching a NOP block

The following patch would patch a block of 52 NOP's at D2Client.0x9A6F1

Code: Select all

{D2DLL_D2CLIENT, 0x9A6F1, (DWORD)PATCH_NOPBLOCK, FALSE, 0x34},
This patch would look like this once applied:

Code: Select all

6FB4A6F1    90              NOP
6FB4A6F2    90              NOP
6FB4A6F3    90              NOP
6FB4A6F4    90              NOP
6FB4A6F5    90              NOP
6FB4A6F6    90              NOP
6FB4A6F7    90              NOP
6FB4A6F8    90              NOP
6FB4A6F9    90              NOP
6FB4A6FA    90              NOP
6FB4A6FB    90              NOP
6FB4A6FC    90              NOP
6FB4A6FD    90              NOP
6FB4A6FE    90              NOP
6FB4A6FF    90              NOP
6FB4A700    90              NOP
6FB4A701    90              NOP
6FB4A702    90              NOP
6FB4A703    90              NOP
6FB4A704    90              NOP
6FB4A705    90              NOP
6FB4A706    90              NOP
6FB4A707    90              NOP
6FB4A708    90              NOP
6FB4A709    90              NOP
6FB4A70A    90              NOP
6FB4A70B    90              NOP
6FB4A70C    90              NOP
6FB4A70D    90              NOP
6FB4A70E    90              NOP
6FB4A70F    90              NOP
6FB4A710    90              NOP
6FB4A711    90              NOP
6FB4A712    90              NOP
6FB4A713    90              NOP
6FB4A714    90              NOP
6FB4A715    90              NOP
6FB4A716    90              NOP
6FB4A717    90              NOP
6FB4A718    90              NOP
6FB4A719    90              NOP
6FB4A71A    90              NOP
6FB4A71B    90              NOP
6FB4A71C    90              NOP
6FB4A71D    90              NOP
6FB4A71E    90              NOP
6FB4A71F    90              NOP
6FB4A720    90              NOP
6FB4A721    90              NOP
6FB4A722    90              NOP
6FB4A723    90              NOP
6FB4A724    90              NOP
Patching a function call (to call our own function instead)

The following patch would replace the call to D2Client.0xC39E0 with our own function. Notice we don't patch D2Client.0x4437B here, but rather one byte later as we do not want to overwrite the CALL instruction. An ASM CALL instruction looks like this 0xE8 ########. The 0xE8 is the CALL instruction, the ######## is the part we want to patch.

Code: Select all

{D2DLL_D2CLIENT, 0x4437C, (DWORD)D2UI_Main, TRUE, 0x00},
The patch would look like this once applied:

Code: Select all

6FAF437B    E8 ########     CALL D2Template.########
Patching a function call (where there is no call instruction originally)

Similar to the previous patch, except that we're patching a location where there is no call instruction originally, so we need to patch it ourself.

Code: Select all

{D2DLL_D2CLIENT, 0x8B1DE, (DWORD)PATCH_CALL, FALSE, 0x00},				// needs to be declared first
{D2DLL_D2CLIENT, 0x8B1DF, (DWORD)DRLGUI_LevelBackground, TRUE, 0x00},
The patch would look like this once applied:

Code: Select all

6FB3B1DE    E8 ########     CALL D2Template.########
You can do the same thing with a jump if you want:

Code: Select all

{D2DLL_FOG, 0x17F60, (DWORD)PATCH_JMP, FALSE, 0x00},
{D2DLL_FOG, 0x17F61, (DWORD)SAVEFILE_GetSavePath, TRUE, 0x00},
Last edited by kidpaddle94 on Thu Jun 09, 2022 5:04 pm, edited 1 time in total.

User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

Re: D2Template

Post by Necrolis » Tue Jun 23, 2015 6:07 pm

Just a little usability hint: Shift the patch size to the last member in the structure, this allows you to omit it from records where its not used and have it default to zero.
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

Post Reply

Return to “Code Editing”