[1.10] Retreive pGame

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

P.J.
Posts: 66
Joined: Wed Jan 13, 2010 7:47 pm
Russia

[1.10] Retreive pGame

Post by P.J. » Wed May 02, 2018 11:31 am

Hello

For add 1 skill point by Den of Evil quest there is a call of addStat func:

Code: Select all

6FC97CF4  |.  53            PUSH EBX                                 ; /Arg4           Unknow
6FC97CF5  |.  6A 01         PUSH 1                                   ; |Arg3 = 1      Stat Value
6FC97CF7  |.  6A 05         PUSH 5                                   ; |Arg2 = 5      StatId ftom ISC
6FC97CF9  |.  51            PUSH ECX                                 ; |Arg1           pUnit
6FC97CFA  |.  E8 BB3B0800   CALL <JMP.&D2Common.#10518>              ; \D2Common.#10518   addStat Func
I want to replace this with my custom function:

Code: Select all

void __fastcall Reward(game* pGame, unit* pUnit)
{
	
	if(pGame == NULL || pUnit == NULL) return;

	int Difficulty = pGame->nDifficulty;

	switch(Difficulty)
	{
		case DIFF_NORMAL: 
			{
				D2COMMON_AddStat(pUnit, STAT_STATPTS, 5, 0);
			}	break;
		case DIFF_NIGHTMARE:
			{
				D2COMMON_AddStat(pUnit, STAT_STATPTS, 10, 0);
			}	break;
		case DIFF_HELL:
			{
				D2COMMON_AddStat(pUnit, STAT_STATPTS, 15, 0);
			}	break;
	}
}
As i understand before call this func i should have pGame in ECX and pUnit in EDX. So i should MOV EDX, ECX and retrieve pGame to ECX in some way. There is any way to do that? As far as i know there are some {filtered} which return pUnit to EAX, there is same way for pGame probably?
Sorry for noob questions.

Regards

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

Hand-picked

Re: [1.10] Retreive pGame

Post by Necrolis » Wed May 02, 2018 12:46 pm

in this case its actually easier to just access the pGame pointer form pUnit+0x80, then you can just replace the call to the AddStat function. If you do want to use your function instead, then you'd need to have some additional assembly to move the pGame pointer into ecx from wherever is been saved by that function into ECX, and the pUnit into EDX.
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

P.J.
Posts: 66
Joined: Wed Jan 13, 2010 7:47 pm
Russia

Re: [1.10] Retreive pGame

Post by P.J. » Wed May 02, 2018 2:08 pm

So i need something like:

Code: Select all

MOV EDX,ECX
MOV ECX, DWORD PTR DS:[EDX+80]
PUSH EDX
PUSH ECX
Before the call to my func?


==========UPDATE==========

So as i understand i should setup like this?

Original:

Code: Select all

6FC97CF1  |.  8B4F 0C       MOV ECX,DWORD PTR DS:[EDI+0C]          ;Retrieving pUnit 
6FC97CF4  |.  53            PUSH EBX                                 ; /Arg4           Unknow
6FC97CF5  |.  6A 01         PUSH 1                                   ; |Arg3 = 1      Stat Value
6FC97CF7  |.  6A 05         PUSH 5                                   ; |Arg2 = 5      StatId ftom ISC
6FC97CF9  |.  51            PUSH ECX                                 ; |Arg1           pUnit
6FC97CFA  |.  E8 BB3B0800   CALL <JMP.&D2Common.#10518>              ; \D2Common.#10518 

My:

Code: Select all

 8B57 0C       		MOV EDX,DWORD PTR DS:[EDI+0C]       ;Retrieving pUnit 
 8B8A 80000000         MOV ECX,DWORD PTR DS:[EDX+80]       ;Retrieving pGame            
 52           			PUSH EDX                                 ; /Arg2    ;pUnit
 51            		PUSH ECX                                 ; |Arg1    ;Pgame
 E8 ########   CALL <JMP.&.######>.######>              ; \Myfunc

Its looks correct? If yes, i have no enough space for this..

Thanks

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

Re: [1.10] Retreive pGame

Post by Mnw1995 » Wed May 02, 2018 3:08 pm

It is not correct. You don't need to push your arguments, if you declare your function as __fastcall

Still, you don't need to bother with all that stuff in ASM. You could just retrieve pGame from pUnit in your C code.

Code: Select all

void __stdcall Reward(unit* pUnit, int /*Stat*/, int /*Value*/, int /*Param*/)
{
	
	if(pUnit == NULL) return;

	int Difficulty = pUnit->pGame->nDifficulty;

	switch(Difficulty)
	{
		case DIFF_NORMAL: 
			{
				D2COMMON_AddStat(pUnit, STAT_STATPTS, 5, 0);
			}	break;
		case DIFF_NIGHTMARE:
			{
				D2COMMON_AddStat(pUnit, STAT_STATPTS, 10, 0);
			}	break;
		case DIFF_HELL:
			{
				D2COMMON_AddStat(pUnit, STAT_STATPTS, 15, 0);
			}	break;
	}
}
If you change your code like this, the only thing you need to do in ASM is patching the call:

Code: Select all

6FC97CFA  |.  E8 BB3B0800   CALL <JMP.&D2Common.#10518>              ; \D2Common.#10518 
to

Code: Select all

E8 ########   CALL <JMP.&.######>.######>              ; \Myfunc

P.J.
Posts: 66
Joined: Wed Jan 13, 2010 7:47 pm
Russia

Re: [1.10] Retreive pGame

Post by P.J. » Wed May 02, 2018 10:46 pm

Thank you for help, guys, its working perfectly now.

Return to “Code Editing”