[TUTORIAL] GetActiveWeapon
Page 1 of 10 12345678910 Last
  1. #1

    [TUTORIAL] GetActiveWeapon

    Today we will learn how to debugg the pointer to the GetActiveWeapon memberfunction of C_BaseEntity.

    [HIDE]
    What we need:
    OllyDbg
    OB engine SDK( optional )

    Let's start!

    Look in clientmode_shared.cpp and search for:
    Code:
    //-----------------------------------------------------------------------------
    // Purpose: We've received a keypress from the engine. Return 1 if the engine is allowed to handle it.
    //-----------------------------------------------------------------------------
    int	ClientModeShared::KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
    {
    	if ( engine->Con_IsVisible() )
    		return 1;
    	
    	// Should we start typing a message?
    	if ( pszCurrentBinding &&
    		( Q_strcmp( pszCurrentBinding, "messagemode" ) == 0 ||
    		  Q_strcmp( pszCurrentBinding, "say" ) == 0 ) )
    	{
    		if ( down )
    		{
    			StartMessageMode( MM_SAY );
    		}
    		return 0;
    	}
    	else if ( pszCurrentBinding &&
    				( Q_strcmp( pszCurrentBinding, "messagemode2" ) == 0 ||
    				  Q_strcmp( pszCurrentBinding, "say_team" ) == 0 ) )
    	{
    		if ( down )
    		{
    			StartMessageMode( MM_SAY_TEAM );
    		}
    		return 0;
    	}
    	
    	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
    
    	// if ingame spectator mode, let spectator input intercept key event here
    	if( pPlayer &&
    		( pPlayer->GetObserverMode() > OBS_MODE_DEATHCAM ) &&
    		!HandleSpectatorKeyInput( down, keynum, pszCurrentBinding ) )
    	{
    		return 0;
    	}
    
    	// Let game-specific hud elements get a crack at the key input
    	if ( !HudElementKeyInput( down, keynum, pszCurrentBinding ) )
    	{
    		return 0;
    	}
    
    	C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
    	if ( pWeapon )
    	{
    		return pWeapon->KeyInput( down, keynum, pszCurrentBinding );
    	}
    
    	return 1;
    }
    As you can see the penultimate call is GetActiveWeapon.
    Now do the following steps:
    Open OllyDbg, attach to hl2.exe, click on the "E"-Button to open the "Executable modules" window.
    Find and doubleclick on client.dll to open the assembly window.
    Now rightclick in this window and select "Search for" -> "All referenced text strings".
    A window named "Text strings referenced in client:.text" should have popped up.
    Rightclick in this window and select "Search for text" to search for the ascii string "messagemode" and doubleclick on it.
    The following steps should lead you to this assembly:
    Code:
    10BF0298   BF ECAFE610      MOV EDI,client.10E6AFEC                  ; ASCII "messagemode"
    10BF029D   8BF5             MOV ESI,EBP
    10BF029F   B9 0C000000      MOV ECX,0C
    10BF02A4   33C0             XOR EAX,EAX
    10BF02A6   F3:A6            REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
    10BF02A8   74 12            JE SHORT client.10BF02BC
    10BF02AA   BF E8AFE610      MOV EDI,client.10E6AFE8                  ; ASCII "say"
    10BF02AF   8BF5             MOV ESI,EBP
    10BF02B1   B9 04000000      MOV ECX,4
    10BF02B6   33D2             XOR EDX,EDX
    10BF02B8   F3:A6            REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
    10BF02BA   75 1A            JNZ SHORT client.10BF02D6
    10BF02BC   394424 14        CMP DWORD PTR SS:[ESP+14],EAX
    10BF02C0   74 0B            JE SHORT client.10BF02CD
    10BF02C2   8B03             MOV EAX,DWORD PTR DS:[EBX]
    10BF02C4   8B50 48          MOV EDX,DWORD PTR DS:[EAX+48]
    10BF02C7   6A 01            PUSH 1
    10BF02C9   8BCB             MOV ECX,EBX
    10BF02CB   FFD2             CALL EDX
    10BF02CD   5F               POP EDI
    10BF02CE   5E               POP ESI
    10BF02CF   5D               POP EBP
    10BF02D0   33C0             XOR EAX,EAX
    10BF02D2   5B               POP EBX
    10BF02D3   C2 0C00          RETN 0C
    10BF02D6   BF D8AFE610      MOV EDI,client.10E6AFD8                  ; ASCII "messagemode2"
    10BF02DB   8BF5             MOV ESI,EBP
    10BF02DD   B9 0D000000      MOV ECX,0D
    10BF02E2   33C0             XOR EAX,EAX
    10BF02E4   F3:A6            REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
    10BF02E6   74 12            JE SHORT client.10BF02FA
    10BF02E8   BF CCAFE610      MOV EDI,client.10E6AFCC                  ; ASCII "say_team"
    10BF02ED   8BF5             MOV ESI,EBP
    10BF02EF   B9 09000000      MOV ECX,9
    10BF02F4   33D2             XOR EDX,EDX
    10BF02F6   F3:A6            REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
    10BF02F8   75 1A            JNZ SHORT client.10BF0314
    10BF02FA   394424 14        CMP DWORD PTR SS:[ESP+14],EAX
    10BF02FE   74 0B            JE SHORT client.10BF030B
    10BF0300   8B03             MOV EAX,DWORD PTR DS:[EBX]
    10BF0302   8B50 48          MOV EDX,DWORD PTR DS:[EAX+48]
    10BF0305   6A 02            PUSH 2
    10BF0307   8BCB             MOV ECX,EBX
    10BF0309   FFD2             CALL EDX
    10BF030B   5F               POP EDI
    10BF030C   5E               POP ESI
    10BF030D   5D               POP EBP
    10BF030E   33C0             XOR EAX,EAX
    10BF0310   5B               POP EBX
    10BF0311   C2 0C00          RETN 0C
    10BF0314   E8 574EFCFF      CALL client.10BB5170
    10BF0319   85C0             TEST EAX,EAX
    10BF031B   8B7424 18        MOV ESI,DWORD PTR SS:[ESP+18]
    10BF031F   8B7C24 14        MOV EDI,DWORD PTR SS:[ESP+14]
    10BF0323   74 24            JE SHORT client.10BF0349
    10BF0325   8B10             MOV EDX,DWORD PTR DS:[EAX]
    10BF0327   8BC8             MOV ECX,EAX
    10BF0329   8B82 34030000    MOV EAX,DWORD PTR DS:[EDX+334]
    10BF032F   FFD0             CALL EAX
    10BF0331   83F8 01          CMP EAX,1
    10BF0334   7E 13            JLE SHORT client.10BF0349
    10BF0336   8B13             MOV EDX,DWORD PTR DS:[EBX]
    10BF0338   8B82 94000000    MOV EAX,DWORD PTR DS:[EDX+94]
    10BF033E   55               PUSH EBP
    10BF033F   56               PUSH ESI
    10BF0340   57               PUSH EDI
    10BF0341   8BCB             MOV ECX,EBX
    10BF0343   FFD0             CALL EAX
    10BF0345   85C0             TEST EAX,EAX
    10BF0347  ^74 C2            JE SHORT client.10BF030B
    10BF0349   8B13             MOV EDX,DWORD PTR DS:[EBX]
    10BF034B   8B82 90000000    MOV EAX,DWORD PTR DS:[EDX+90]
    10BF0351   55               PUSH EBP
    10BF0352   56               PUSH ESI
    10BF0353   57               PUSH EDI
    10BF0354   8BCB             MOV ECX,EBX
    10BF0356   FFD0             CALL EAX
    10BF0358   85C0             TEST EAX,EAX
    10BF035A  ^74 AF            JE SHORT client.10BF030B
    10BF035C   E8 5F6FFBFF      CALL client.10BA72C0
    10BF0361   85C0             TEST EAX,EAX
    10BF0363   74 16            JE SHORT client.10BF037B
    10BF0365   8B10             MOV EDX,DWORD PTR DS:[EAX]
    10BF0367   55               PUSH EBP
    10BF0368   56               PUSH ESI
    10BF0369   8BC8             MOV ECX,EAX
    10BF036B   8B82 CC040000    MOV EAX,DWORD PTR DS:[EDX+4CC]
    10BF0371   57               PUSH EDI
    10BF0372   FFD0             CALL EAX
    10BF0374   5F               POP EDI
    10BF0375   5E               POP ESI
    10BF0376   5D               POP EBP
    10BF0377   5B               POP EBX
    10BF0378   C2 0C00          RETN 0C
    10BF037B   5F               POP EDI
    10BF037C   5E               POP ESI
    10BF037D   5D               POP EBP
    10BF037E   B8 01000000      MOV EAX,1
    10BF0383   5B               POP EBX
    10BF0384   C2 0C00          RETN 0C
    The penultimate call instruction leads us to the assembly of GetActiveWeapon() ( E8 5F6FFBFF CALL client.10BA72C0 ).
    Doubleclick on the penultimate call instruction and copy the address after "CALL" into your clipboard and close the popup.
    Press CTRL + G and paste the address. After your done with that press ok and the following assembly should appear:
    Code:
    10BA72C0   E8 ABDE0000      CALL client.10BB5170
    10BA72C5   85C0             TEST EAX,EAX
    10BA72C7   75 01            JNZ SHORT client.10BA72CA
    10BA72C9   C3               RETN
    10BA72CA   8B10             MOV EDX,DWORD PTR DS:[EAX]
    10BA72CC   8BC8             MOV ECX,EAX
    10BA72CE   8B82 00030000    MOV EAX,DWORD PTR DS:[EDX+300]
    10BA72D4   FFE0             JMP EAX
    Let me bring some light in the dark.
    Code:
    10BA72C0   E8 ABDE0000      CALL client.10BB5170           ; call GetLocalActiveWeapon
    10BA72C5   85C0             TEST EAX,EAX                   ; check if the returned handle is not valid
    10BA72C7   75 01            JNZ SHORT client.10BA72CA      ; if the handle is not valid jump to 10BA72CA -
    10BA72C9   C3               RETN                           ; else return the handle                      |
    10BA72CA   8B10             MOV EDX,DWORD PTR DS:[EAX]     ; edx = *(DWORD*)eax - *(DWORD*)eax is the address of our local player
    10BA72CC   8BC8             MOV ECX,EAX                    ; ecx = eax
    10BA72CE   8B82 00030000    MOV EAX,DWORD PTR DS:[EDX+300] ; this instruction copies the address of GetActiveWeapon into eax - 
                                                                 so edx( entity address ) + 0x300 = GetActiveWeapon
    10BA72D4   FFE0             JMP EAX                        ; this "JMP" is compareable to a "CALL" instruction and calls GetActiveWeapon
                                                               ; the pointer to the handle of the active weapon will be stored in eax
    Now let's code our GetActiveWeapon function.

    Code:
    C_BaseCombatWeapon* GetBaseCombatActiveWeapon( CBaseEntity* pBaseEntity )
    {
    	C_BaseCombatWeapon* pActiveWeapon = NULL;
    	__asm
    	{
    		MOV  EAX, pBaseEntity          ; eax = pBaseEntity
    		MOV  EDI, EAX                  ; edi = eax
    		MOV  EAX, DWORD PTR DS :[EDI]  ; eax = pointer to edi
    		MOV  ECX, EDI                  ; ecx = edi 
    		CALL DWORD PTR DS :[EAX+0x300] ; call GetActiveWeapon
    		MOV  pActiveWeapon, EAX;       ; save the returned pointer to the weaponhandle in pActiveWeapon
    	}
    	return pActiveWeapon;                 // return the weapon handle 
    }
    [/HIDE]

    Pretty simple, eh?

    Have phun!!1
    Last edited by aVitamin; 27th September 2008 at 11:26.

  2. #2

  3. #3
    what term "penultimate call" means? Very nice tutorial btw! Everything is explained nicely.
    Last edited by mencore; 27th September 2008 at 11:57.

  4. #4
    the call before the last call^O)

  5. #5
    Unhide

    Is this more explaning then fum1n's?

  6. #6

    o

    Thanks.

  7. #7

  8. #8
    unhide

  9. #9
    unhide

  10. #10

Page 1 of 10 12345678910 Last

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Log in

Log in