Home AgeRage.net Forum Cheats News Hosting Shop About Links


Links
shop

download

facebook
Go Back   AgeRage.net Forum > ..::The Coding House::.. > Newbies Help > Tutorials Room


Thread: CS 1.6 Gateway Tutorial
Tutorials Room Read our excellent tutorials and be an expert!

Reply

 
LinkBack Thread Tools


  #1 (permalink)  
Join Date: 16 Feb 2006
Posts: 98
wav's Avatar
Old 28-06-2006, 21:01
wav wav is offline
Silver Member
CS 1.6 Gateway Tutorial

Lets take CL_CreateMove as an example

Code:
01955750    83EC 10         SUB ESP,10
01955753    8D4424 1C       LEA EAX,DWORD PTR SS:[ESP+1C]
01955757    8D4C24 18       LEA ECX,DWORD PTR SS:[ESP+18]
0195575B    8D5424 14       LEA EDX,DWORD PTR SS:[ESP+14]
0195575F    53              PUSH EBX
01955760    50              PUSH EAX
01955761    A1 F079A101     MOV EAX,DWORD PTR DS:[1A179F0]
01955766    51              PUSH ECX
01955767    52              PUSH EDX
01955768    FF50 38         CALL NEAR DWORD PTR DS:[EAX+38]
the sub esp 10, sets up some space on the stack to pass 3 arguments. the lea loads the address of these arguments and the push passes them to the nullstub which normally would return. Now when you use ltfx hooking you modify the export table to point to your table.

let me explain this part now

Code:
if( c[0] == 0xc3 )
You cast the slots pointer as a byte pointer, (unsigned char *) to check if the opcode at that particular point in the data segment is 0xC3 If it doesn't equal 0xC3, then we do nothing. Of course this is redundant since look a bit above

Code:
c = (unsigned char*)slots[s];
if( c[0] != 0xc3 )
{
	patched=false;
	MessageBox(NULL, "Things look wrong... very wrong", NULL, MB_OK);
}
With that out of the way lets continue.

Code:
01955761    A1 F079A101     MOV EAX,DWORD PTR DS:[1A179F0]
This is the "retart", slotsfx, slointer, whatever you want to call it. it holds the address of the export table. LTFXGuy found it first but this isn't story time.

Code:
01955768    FF50 38         CALL NEAR DWORD PTR DS:[EAX+38]
now eax contains the start of the export table, we want createmove so we add 0x38 and call it, which happens to be...

0xC3, which will just return.

Now onto the real stuff, with all this out of the way.

We modify the export table to point to our jumpgates and then the real fun starts. When the nullstub is called rather than just returning it goes to our jumpgate.

Code:
10014F55    56              PUSH ESI                                 ; hl.02EB8F84
10014F56    36:8B7424 28    MOV ESI,DWORD PTR SS:[ESP+28]
10014F5B    8935 380D0510   MOV DWORD PTR DS:[10050D38],ESI
10014F61    FF35 E0180010   PUSH DWORD PTR DS:[100018E0]             ; OGC Tweak.10014F4A
10014F67    5E              POP ESI
10014F68    36:897424 28    MOV DWORD PTR SS:[ESP+28],ESI
10014F6D    5E              POP ESI
10014F6E    C3              RETN
esi in this case currently holds the usercmd struct. so we store in on the stack. now this is where the retaddress comes into play.
Code:
MOV ESI,DWORD PTR SS:[ESP+28]
esi will hold the retaddress, but how did we get esp + 0x28.

here's how.

remember cl_createmove's start?

Code:
01955750    83EC 10         SUB ESP,10
01955753    8D4424 1C       LEA EAX,DWORD PTR SS:[ESP+1C]
01955757    8D4C24 18       LEA ECX,DWORD PTR SS:[ESP+18]
0195575B    8D5424 14       LEA EDX,DWORD PTR SS:[ESP+14]
0195575F    53              PUSH EBX
01955760    50              PUSH EAX
01955761    A1 F079A101     MOV EAX,DWORD PTR DS:[1A179F0]
01955766    51              PUSH ECX
01955767    52              PUSH EDX
01955768    FF50 38         CALL NEAR DWORD PTR DS:[EAX+38]
breakpoint on the 1955750 and notice the stack.

Code:
0012F304   01D1C08D  RETURN to hl.01D1C08D from hl.01D0E4F0
now breakpoint on the 1955768.

Code:
12F2DC
12F304 - 12F2DC = 0x28

Simple enough.

now,

Code:
10014F56    36:8B7424 28    MOV ESI,DWORD PTR SS:[ESP+28]            ; hl.01D1C08D
hmm, clientmove is what called cl_createmove. Must be the return address.

Code:
10014F61    FF35 E0180010   PUSH DWORD PTR DS:[100018E0]             ; OGC Tweak.10014F4A
This simply stores the address of the jumpgate on the stack. It will be used to "call" our gateway after the clientfunction is finished.

Code:
10014F67    5E              POP ESI
10014F68    36:897424 28    MOV DWORD PTR SS:[ESP+28],ESI            ; OGC Tweak.10014F4A
10014F6D    5E              POP ESI
10014F6E    C3              RETN
we pop esi twice to get the usercmd struct back. but first

Code:
MOV DWORD PTR SS:[ESP+28],ESI
All this does is move the gateway into esp + 0x28. It will be used later to call our gateway

Finally we retn to the client function, with everything setup, then after the client function returns it calls the gateway.

This may not appear elsewhere without permission, but may be linked to.
Reply With Quote

AgeRage.net Shop - Buy your valid CD-Keys

  #2 (permalink)  
Join Date: 16 Feb 2006
Posts: 98
wav's Avatar
Old 28-06-2006, 21:02
wav wav is offline
Silver Member
with the information gleaned from the tutorial above its pretty simple to make a gateway for hud_addentity in dod.

Code:
int iResult;

DWORD dwReturnAddress = 0x01D0E3AF;
PDWORD pdwStackPointer = (PDWORD)0x0012FB34;

__declspec( naked )void Gateway2_HUD_Add_Entity( void )
{
    _asm { mov iResult, eax }
    _asm { call HUD_AddEntity }
    _asm { mov eax, iResult } 
    _asm { jmp dwReturnAddress }
}

__declspec( naked )void Gateway_HUD_Add_Entity( void )
{
     *pdwStackPointer = (DWORD)Gateway2_HUD_Add_Entity;
     _asm { ret }
}
This of course relies on the fact the game won't update. Its shorter and works effectively.

now if you don't want to do it this way

Code:
__declspec( naked )void Gateway2_HUD_AddEntity( void )
{
	__asm
	{
		mov AddEntResult, eax;
		call HUD_AddEntity;
		mov eax, AddEntResult;
		jmp retaddress;
	}
}

DWORD AddEnt = (DWORD)&Gateway2_HUD_AddEntity;
__declspec( naked )void Gateway1_HUD_AddEntity( void )
{
	
	__asm
	{
		push esi;
		mov esi,dword ptr ss:[esp+0xE0];
		mov retaddress,esi;
		push AddEnt
		pop esi;
		mov dword ptr ss:[esp+0xE0],esi;
		pop esi;
		ret;
	}
}
Code:
0012FB34   01D0E3AF  RETURN to hl.01D0E3AF
Breakpointed at the start of the function.

Code:
0012FA54
Breakpointed on the call to the nullstub.

Last edited by wav; 28-06-2006 at 21:58..
Reply With Quote
  #3 (permalink)  
Join Date: 16 Feb 2006
Posts: 98
wav's Avatar
Old 28-06-2006, 21:03
wav wav is offline
Silver Member
How to setup HUD_GetStudioModelInterface gateway for cs 1.6

HUD_GetStudioModelInterface is called only once after HW_Decode. If we don't get it then, we won't be able to breakpoint and get the data we need.

So you must attach olly while cs or whatnot is loading or hook hl_decode -> see goldfinder basehook.

now presuming you have it attached, place a breakpoint here.

Code:
01D0F110    E8 2B3B0800     CALL hl.01D92C40
It will stop the process so we can do our work now.

you should have this :

Code:
01D0F110    E8 2B3B0800     CALL hl.01D92C40
01D0F115    A1 3C1AEC01     MOV EAX,DWORD PTR DS:[1EC1A3C]
01D0F11A    85C0            TEST EAX,EAX
01D0F11C    74 40           JE SHORT hl.01D0F15E
01D0F11E    8B4424 04       MOV EAX,DWORD PTR SS:[ESP+4]
01D0F122    68 4C91E801     PUSH hl.01E8914C                                              ; ASCII "HUD_GetStudioModelInterface"
01D0F127    50              PUSH EAX
01D0F128    FF15 2812E601   CALL NEAR DWORD PTR DS:[1E61228]                              ; kernel32.GetProcAddress
01D0F12E    A1 1CCEF302     MOV EAX,DWORD PTR DS:[2F3CE1C]
01D0F133    85C0            TEST EAX,EAX
01D0F135    74 27           JE SHORT hl.01D0F15E
01D0F137    68 C841EA01     PUSH hl.01EA41C8
01D0F13C    68 8C42EA01     PUSH hl.01EA428C
01D0F141    6A 01           PUSH 1
01D0F143    FFD0            CALL NEAR EAX
01D0F145    83C4 0C         ADD ESP,0C
01D0F148    85C0            TEST EAX,EAX
01D0F14A    75 12           JNZ SHORT hl.01D0F15E
01D0F14C    68 6891E801     PUSH hl.01E89168                                              ; ASCII "Couldn't get client .dll studio model rendering interface.  Version mismatch?
"
01D0F151    E8 7A050200     CALL hl.01D2F6D0
01D0F156    83C4 04         ADD ESP,4
01D0F159    E9 E23A0800     JMP hl.01D92C40
01D0F15E    C3              RETN
01D0F15F    90              NOP
01D0F160    8D4424 08       LEA EAX,DWORD PTR SS:[ESP+8]
01D0F164    8D4C24 04       LEA ECX,DWORD PTR SS:[ESP+4]
01D0F168    50              PUSH EAX
01D0F169    51              PUSH ECX
01D0F16A    FF15 E8E1E901   CALL NEAR DWORD PTR DS:[1E9E1E8]                              ; hl.01D63420
01D0F170    83C4 08         ADD ESP,8
01D0F173    E9 68F50100     JMP hl.01D2E6E0
I will not explain the dump, just the part you need.

Code:
01D0F12E    A1 1CCEF302     MOV EAX,DWORD PTR DS:[2F3CE1C]
01D0F133    85C0            TEST EAX,EAX
01D0F135    74 27           JE SHORT hl.01D0F15E
01D0F137    68 C841EA01     PUSH hl.01EA41C8
01D0F13C    68 8C42EA01     PUSH hl.01EA428C
01D0F141    6A 01           PUSH 1
01D0F143    FFD0            CALL NEAR EAX
2F3CE1C has the address of HUD_GetStudioModelInterface, and test eax checks if its zero. if so it performs a short jump and returns. Otherwise it will pass the ppinterface struct and pstudio structs to the clientfunction and the version information in reverse

ex:

Code:
int HUD_GetStudioModelInterface ( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )
The part you need to be concerned about is call near eax, this is where we want to go, so look in the eax register and goto the address or execute it by stepping into it.

Now you should have this

Code:
01948600    8D4424 0C       LEA EAX,DWORD PTR SS:[ESP+C]
01948604    8D4C24 08       LEA ECX,DWORD PTR SS:[ESP+8]
01948608    50              PUSH EAX
01948609    A1 F079A101     MOV EAX,DWORD PTR DS:[1A179F0]
0194860E    8D5424 08       LEA EDX,DWORD PTR SS:[ESP+8]
01948612    51              PUSH ECX
01948613    52              PUSH EDX
01948614    FF90 9C000000   CALL NEAR DWORD PTR DS:[EAX+9C]
0194861A    8B4424 10       MOV EAX,DWORD PTR SS:[ESP+10]
0194861E    83C4 0C         ADD ESP,0C
01948621    83F8 01         CMP EAX,1
01948624    74 03           JE SHORT hl.01948629
01948626    33C0            XOR EAX,EAX
01948628    C3              RETN
01948629    8B4C24 08       MOV ECX,DWORD PTR SS:[ESP+8]
0194862D    56              PUSH ESI
0194862E    57              PUSH EDI
0194862F    BF 802FA301     MOV EDI,hl.01A32F80
01948634    C701 B0069E01   MOV DWORD PTR DS:[ECX],hl.019E06B0
0194863A    8B7424 14       MOV ESI,DWORD PTR SS:[ESP+14]
0194863E    B9 2E000000     MOV ECX,2E
01948643    F3:A5           REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
01948645    B9 900FA201     MOV ECX,hl.01A20F90
0194864A    E8 51A50100     CALL hl.01962BA0
0194864F    5F              POP EDI
01948650    B8 01000000     MOV EAX,1
01948655    5E              POP ESI
01948656    C3              RETN
Now note the stack. You should see this:

Code:
0012F858   01D0F145  RETURN to hl.01D0F145
The return to hl. 1D0F145 is the return address of HUD_GetStudioModelInterface. Get out calculator and save the 0012F858, we're going to need it later.

Step through to this:

Code:
01948614    FF90 9C000000   CALL NEAR DWORD PTR DS:[EAX+9C]
The current esp (extended stack pointer) should read

0012F84C

Now take 0x12F858 - 0x12F84C. The result should be 0xC.

Code:
__asm
{
	push esi;
	mov esi,dword ptr ss:[esp+0xC];
	mov retaddress,esi;
	push StudioModelInterface
	pop esi;
	mov dword ptr ss:[esp+0xC],esi;
	pop esi;
	ret;
}
or you can do it the short way

Code:
int iRet;

DWORD dwReturnAddress = 0x01D0F145;
PDWORD pdwStackPointer = (PDWORD)0x0012F858;

__declspec( naked )void Gateway2_HUD_GetStudioModelInterface( void )
{
    _asm { mov iRet, eax }
    _asm { call HUD_GetStudioModelInterface }
    _asm { mov eax, iRet }
    _asm { jmp dwReturnAddress }
}

__declspec( naked )void Gateway_HUD_GetStudioModelInterface( void )
{
     *pdwStackPointer = (DWORD)Gateway2_HUD_GetStudioModelInterface;
     _asm { ret }
}

Last edited by wav; 28-06-2006 at 21:56..
Reply With Quote
  #4 (permalink)  
Join Date: 29 Sep 2005
Posts: 928
2nd~0v3R|r!de's Avatar
Old 28-06-2006, 21:30
Bronze Dragon
Very, very nice wav.

I've been reading all of your tutorials/code you've posted so far and there all very interesting. Nice to have you on AgeRage.
Reply With Quote
  #5 (permalink)  
Join Date: 16 Feb 2006
Posts: 98
wav's Avatar
Old 28-06-2006, 21:59
wav wav is offline
Silver Member
Quote:
Originally Posted by 2nd~0v3R|r!de
Very, very nice wav.

I've been reading all of your tutorials/code you've posted so far and there all very interesting. Nice to have you on AgeRage.
I updated the tutorial due to the fact I realized that the functions need to get the return value from eax and the hooked clientfunction modifies that. So in other words its perfect now
Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

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 Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
[Tutorial] Client Hooking Tutorial 1 Neg6 Tutorials Room 24 31-03-2008 22:15
I found the tutorial & read it but.... ismjism Age Of Mythology & The Titans 1 23-05-2007 23:49
*RELEASE* The Ultimate Scenario Design Tutorial 2.2! malakai AoE Non Cheating Sector 11 04-09-2005 04:26
Requesting AoC Triggers Tutorial Hollowed_Eye AoE Non Cheating Sector 2 17-03-2005 01:48


All times are GMT +1. The time now is 14:30.

Latest Threads

About AgeRage Forum

Powered by vBulletin® Version 3.7.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.2.0
AgeRage.net - 'Feeding Your Cheating Obsession'
Page generated in 0.23179 seconds with 13 queries