Finding Output Stream for Source Engine Developer Console

Want Cheat Engine to do something specific and no idea how to do that, ask here. (From simple scripts to full trainers and extensions)
Post Reply
vertigo103
What is cheating?
What is cheating?
Posts: 3
Joined: Mon Sep 18, 2017 7:42 pm
Reputation: 0

Finding Output Stream for Source Engine Developer Console

Post by vertigo103 » Tue Sep 19, 2017 7:46 pm

So I've looked at a few tutorials and done some searching but haven't been able to find anything specific to my issue.

Basically, I'm trying to find a static address pointer within the Source Engine ( counter strike, tf2, gmod, etc. ) that points to, or at least helps me find the "output" stream for all of the information that gets Printed to the Developer Console in game.


Here is what I tested:

Image


Strings found:
Image


After sending another line:
( appears on same line because i edited the previous string, which messed up the new line character I guess)

Image

how the other addresses changed:

Image


---

Previously I was able to find a somewhat contiguous region where it was writing things, but the area seems to jump around when sending new commands.


When I was able to "see what writes to this" or what "accesses" this, I ran into assembler commands where I didnt know how to get the value of certain parts.

How do I get the value of registers like this:
Image


TL;DR

I'm not sure how to deal with this situation because the region where the information is stored changes so much.

It's not as simple as changing how much ammo a player has since you can't directly edit any lines in console to see what accesses them.

Any suggestions on ways to approach this?

I understand that there may not be a fully contiguous region that the engine always writes to, so I guess I just need to find what is doing the writing, but I'm not sure how to do that.

Thanks

User avatar
seikur0
Expert Cheater
Expert Cheater
Posts: 87
Joined: Sat Aug 26, 2017 10:48 am
Reputation: 57

Re: Finding Output Stream for Source Engine Developer Console

Post by seikur0 » Wed Sep 20, 2017 3:27 pm

bp is just the lower 2 bytes of ebp, so in that case 6B->"k".

You shouldn't bother with these low level string duplication functions, try setting a breakpoint on data write and from there find the calling function/trace back the pointer/create one with aob.

vertigo103
What is cheating?
What is cheating?
Posts: 3
Joined: Mon Sep 18, 2017 7:42 pm
Reputation: 0

Re: Finding Output Stream for Source Engine Developer Console

Post by vertigo103 » Sun Oct 08, 2017 8:23 pm

seikur0 wrote:
Wed Sep 20, 2017 3:27 pm
bp is just the lower 2 bytes of ebp, so in that case 6B->"k".

You shouldn't bother with these low level string duplication functions, try setting a breakpoint on data write and from there find the calling function/trace back the pointer/create one with aob.
(finally had some time to get back to this.)

Ok, so I've been messing with Break Points / Break and Trace - my issue right now is that I'm not exactly sure what I'm looking for.

Im at a point where I can consistently test the same address though - to see what writes to it.

Steps
> Clear the in-game console
> Write a New command <--- Goes to the same address as previous command
> Repeat


Memory View:

Image


So from their I've created a Breakpoint which shows the instruction that writes to the address.

In this image, the instruction Moves the letter M into the address:

Image

After doing a break point and stepping through the "move" sequence a couple times, it's clear that it goes through 100 or 200 instructions between each character that gets copied to the address.

So I'm assuming that at some point the character is Copied from somewhere into the register that is being used in the Copy instruction.

Here's my problem

I'm not totally sure how to trace the character back to the source, or back to a static address that I can use to find it at any time.

Right now I'm trying to use the Break and Trace option - but I'm not familiar enough with it, so I'm looking for some guidance on what I should look for to find the calling function or pointer that I need.


Here is what the Break and Trace Looks like for when I wrote "a4" to the console address:

Image


From what I read on the wiki page, it seems like it could be useful. I'm just not sure what to look for.

Do ALL the instructions shown in the Break and Trace somehow relate to the address that I created the break on? (cause there are a ton - probably because I had it set to 1000)

anyway - thanks for any help! :D

User avatar
SunBeam
Trouble Makers
Trouble Makers
Posts: 455
Joined: Thu Mar 02, 2017 10:15 pm
Reputation: 129

Re: Finding Output Stream for Source Engine Developer Console

Post by SunBeam » Mon Oct 09, 2017 6:59 am

Do PM me your target's name. Been playing with quite a few engines and consoles lately, should get you somewhere useful real fast ;)

EDIT: This would be the function that gets executed when console text buffer is written to (note that the text is UNICODE, not ASCII):

Code: Select all

gameui.dll+D2980 - 8B 44 24 04           - mov eax,[esp+04]
gameui.dll+D2984 - 66 83 38 00           - cmp word ptr [eax],00
gameui.dll+D2988 - 53                    - push ebx
gameui.dll+D2989 - 55                    - push ebp
gameui.dll+D298A - 8B E9                 - mov ebp,ecx
gameui.dll+D298C - 8B D8                 - mov ebx,eax
gameui.dll+D298E - 0F84 B1000000         - je gameui.dll+D2A45
gameui.dll+D2994 - 56                    - push esi
gameui.dll+D2995 - 57                    - push edi
gameui.dll+D2996 - 66 8B 03              - mov ax,[ebx]
gameui.dll+D2999 - 3C 0D                 - cmp al,0D
gameui.dll+D299B - 89 44 24 14           - mov [esp+14],eax
gameui.dll+D299F - 0F84 91000000         - je gameui.dll+D2A36
gameui.dll+D29A5 - 8B 85 08010000        - mov eax,[ebp+00000108]
gameui.dll+D29AB - 85 C0                 - test eax,eax
gameui.dll+D29AD - 7E 0F                 - jle gameui.dll+D29BE
gameui.dll+D29AF - 39 85 B8000000        - cmp [ebp+000000B8],eax
gameui.dll+D29B5 - 7E 07                 - jle gameui.dll+D29BE
gameui.dll+D29B7 - 8B CD                 - mov ecx,ebp
gameui.dll+D29B9 - E8 02FEFFFF           - call gameui.dll+D27C0
gameui.dll+D29BE - 8B BD B8000000        - mov edi,[ebp+000000B8]
gameui.dll+D29C4 - 8B 85 B0000000        - mov eax,[ebp+000000B0]
gameui.dll+D29CA - 8D B5 AC000000        - lea esi,[ebp+000000AC]
gameui.dll+D29D0 - 8D 4F 01              - lea ecx,[edi+01]
gameui.dll+D29D3 - 3B C8                 - cmp ecx,eax
gameui.dll+D29D5 - 7E 0F                 - jle gameui.dll+D29E6
gameui.dll+D29D7 - 8B D7                 - mov edx,edi
gameui.dll+D29D9 - 2B D0                 - sub edx,eax
gameui.dll+D29DB - 83 C2 01              - add edx,01
gameui.dll+D29DE - 52                    - push edx
gameui.dll+D29DF - 8B CE                 - mov ecx,esi
gameui.dll+D29E1 - E8 FA29F9FF           - call gameui.dll+653E0
gameui.dll+D29E6 - 83 46 0C 01           - add dword ptr [esi+0C],01
gameui.dll+D29EA - 8B 46 0C              - mov eax,[esi+0C]
gameui.dll+D29ED - 8B 0E                 - mov ecx,[esi]
gameui.dll+D29EF - 2B C7                 - sub eax,edi
gameui.dll+D29F1 - 83 E8 01              - sub eax,01
gameui.dll+D29F4 - 85 C0                 - test eax,eax
gameui.dll+D29F6 - 89 4E 10              - mov [esi+10],ecx
gameui.dll+D29F9 - 7E 13                 - jle gameui.dll+D2A0E
gameui.dll+D29FB - 03 C0                 - add eax,eax
gameui.dll+D29FD - 8D 0C 79              - lea ecx,[ecx+edi*2]
gameui.dll+D2A00 - 50                    - push eax
gameui.dll+D2A01 - 51                    - push ecx
gameui.dll+D2A02 - 83 C1 02              - add ecx,02
gameui.dll+D2A05 - 51                    - push ecx
gameui.dll+D2A06 - E8 E5540200           - call gameui.dll+F7EF0
gameui.dll+D2A0B - 83 C4 0C              - add esp,0C
gameui.dll+D2A0E - 8B 0E                 - mov ecx,[esi]
gameui.dll+D2A10 - 8D 04 79              - lea eax,[ecx+edi*2]
gameui.dll+D2A13 - 85 C0                 - test eax,eax
gameui.dll+D2A15 - 74 08                 - je gameui.dll+D2A1F
gameui.dll+D2A17 - 66 8B 54 24 14        - mov dx,[esp+14]
gameui.dll+D2A1C - 66 89 10              - mov [eax],dx
gameui.dll+D2A1F - 8B 85 CC000000        - mov eax,[ebp+000000CC]
gameui.dll+D2A25 - 8B 55 00              - mov edx,[ebp+00]
gameui.dll+D2A28 - 83 E8 02              - sub eax,02
gameui.dll+D2A2B - 8B CD                 - mov ecx,ebp
gameui.dll+D2A2D - 89 85 EC000000        - mov [ebp+000000EC],eax
gameui.dll+D2A33 - FF 52 10              - call dword ptr [edx+10]
gameui.dll+D2A36 - 83 C3 02              - add ebx,02
gameui.dll+D2A39 - 66 83 3B 00           - cmp word ptr [ebx],00
gameui.dll+D2A3D - 0F85 53FFFFFF         - jne gameui.dll+D2996
gameui.dll+D2A43 - 5F                    - pop edi
gameui.dll+D2A44 - 5E                    - pop esi
gameui.dll+D2A45 - 8B 45 00              - mov eax,[ebp+00]
gameui.dll+D2A48 - 6A 00                 - push 00
gameui.dll+D2A4A - 6A 00                 - push 00
gameui.dll+D2A4C - 8B CD                 - mov ecx,ebp
gameui.dll+D2A4E - FF 90 F0000000        - call dword ptr [eax+000000F0]
gameui.dll+D2A54 - 8B 55 00              - mov edx,[ebp+00]
gameui.dll+D2A57 - 8B CD                 - mov ecx,ebp
gameui.dll+D2A59 - C6 85 E8000000 01     - mov byte ptr [ebp+000000E8],01
gameui.dll+D2A60 - FF 52 10              - call dword ptr [edx+10]
gameui.dll+D2A63 - 5D                    - pop ebp
gameui.dll+D2A64 - 5B                    - pop ebx
gameui.dll+D2A65 - C2 0400               - ret 0004
To get to where I got, simply look-up a line from the console with CE, as UTF-16. Then scroll and debug the first byte after 0A 00 (check the hexa). It's basically where next text line will start to be written. Then just type something, hit Enter and CE will pop :)

Now.. console buffer size and buffer pointer are referenced here:

Code: Select all

gameui.dll+D29EA - 8B 46 0C              - mov eax,[esi+0C]
gameui.dll+D29ED - 8B 0E                 - mov ecx,[esi]
If you hook that spot, type in something, then use [esi] in Lua, you can print your own stuff, as Unicode (you only need pointer and size of buffer to print).

Here you go:

Image

You can then either parse the output or write-up a Lua function to display the information properly:

- you have the size, which needs to be * 2, due to text being Unicode (widechar)
- create an iterator to loop through the text buffer till size, looking for 0x0A characters; when found, stop, then use readString( start, size, true) and print it
- loop the above till size is hit
- will write something up shortly :P

BR,
Sun

vertigo103
What is cheating?
What is cheating?
Posts: 3
Joined: Mon Sep 18, 2017 7:42 pm
Reputation: 0

Re: Finding Output Stream for Source Engine Developer Console

Post by vertigo103 » Mon Oct 09, 2017 7:07 pm

thank you very much, appreciate the help - I will read through this and test when I get a chance.

Thanks again! :D

User avatar
SunBeam
Trouble Makers
Trouble Makers
Posts: 455
Joined: Thu Mar 02, 2017 10:15 pm
Reputation: 129

Re: Finding Output Stream for Source Engine Developer Console

Post by SunBeam » Mon Oct 09, 2017 8:32 pm

Adding more to this:

• this is the text copied from the actual in-game console:

Code: Select all

Not mounting addon/gamemode 'counter-strike', requires missing GCF file (240)
Not mounting addon/gamemode 'day-of-defeat', requires missing GCF file (300)
Parent cvar in server.dll not allowed (sk_apc_missile_damage)
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmdm.txt' missing section 'TranslationData'
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmod.txt' missing section 'TranslationData'
Garry's Mod client.dll Build #0016 [Jan 18 2007 23:06:10]
maxplayers set to 1
Heap: 256.00 Mb
Parsed 23 text messages
Not mounting addon/gamemode 'counter-strike', requires missing GCF file (240)
Not mounting addon/gamemode 'day-of-defeat', requires missing GCF file (300)
Adding Font resource/fonts/akbar.ttf
Adding Font resource/fonts/coolvetica.ttf
Adding Font resource/fonts/csd.ttf
Hud element 'CHudHDRDemo' doesn't have an entry 'HudHDRDemo' in scripts/HudLayout.res
Hud element 'CHudFilmDemo' doesn't have an entry 'HudHDRDemo' in scripts/HudLayout.res
Hud element 'CHudCommentary' doesn't have an entry 'HudCommentary' in scripts/HudLayout.res
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmdm.txt' missing section 'TranslationData'
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmod.txt' missing section 'TranslationData'
Garry's Mod server.dll Build #0016 [Jan 18 2007 23:07:22]
execing config.cfg
Can't use cheat cvar dsp_dist_max in multiplayer, unless the server has sv_cheats set to 1.
Can't use cheat cvar dsp_dist_min in multiplayer, unless the server has sv_cheats set to 1.
8 CPUs, Frequency: 3.5 Ghz,  Features: GenuineIntel SSE SSE2 MMX RDTSC CMOV FCMOV
GetAllManifestFiles:  Unable to load maplist.txt
execing valve.rc
execing autoexec.cfg
--- Missing Vgui material vgui/logos/UI/Spray_bullseye
--- Missing Vgui material vgui/gfx/vgui/crosshair
Unable to initialize DirectSoundCapture. You won't be able to speak to other players.couldn't exec userconfig.cfg
Host_WriteConfiguration: Wrote cfg/config.cfg
Changing resolutions from (1920, 1080) -> (1176, 664)
Unable to remove d:\games\garry\garrysmod\textwindow_temp.html!
couldn't exec userconfig.cfg
Host_WriteConfiguration: Wrote cfg/config.cfg
Starting Level gm_construct (Gamemode Override '')
maxplayers set to 1
execing game.cfg
Spawn Server gm_construct
Begin loading faces (loads materials)
End loading faces (loads materials)
Lua initialized (Lua 5.1)
Registering gamemode 'sandbox' derived from 'base'
Late precache of models/weapons/v_pistol.mdl
Late precache of models/weapons/w_camphone.mdl
Late precache of models/weapons/v_toolgun.mdl
Late precache of models/weapons/w_toolgun.mdl
Late precache of models/dav0r/balloon/balloon.mdl
Late precache of models/dav0r/camera.mdl
Late precache of models/dav0r/tnt/tnt.mdl
Late precache of models/dav0r/hoverball.mdl
Late precache of models/props_wasteland/prison_lamp001c.mdl
execing skill_manifest.cfg
execing skill.cfg
Executing listen server config file
Executing listen server config file
Precache of sprites/light_glow02_add_noz ambigious (no extension specified)
Precache of sprites/light_glow02_add_noz ambigious (no extension specified)
Section [Scenes]: 1096 resources total 17.54 KB, 0.84 % of limit (2.10 MB)
Game started
couldn't exec listenserver.cfg
couldn't exec listenserver.cfg
Initializing renderer...
AddPropOffsetToMap - already found entry [prop: 521 offset: 136] in table for DT_BasePlayer
AddPropOffsetToMap - already found entry [prop: 508 offset: 136] in table for DT_GMOD_Player
AddPropOffsetToMap - already found entry [prop: 533 offset: 136] in table for DT_HL2_Player
AddPropOffsetToMap - already found entry [prop: 508 offset: 136] in table for DT_HL2MP_Player
Precaching Spawn Icons................................................................................................................................ DONE!
--- Missing Vgui material vgui/entities/weapon_annabelle
--- Missing Vgui material vgui/entities/weapon_alyxgun
--- Missing Vgui material vgui/entities/weapon_citizenpackage
--- Missing Vgui material vgui/entities/weapon_citizensuitcase
Lua initialized (Lua 5.1)
Registering gamemode 'sandbox' derived from 'base'
Creating RT Texture 'GModToolgunScreen'..DONE!
Joining Game..
] sunbeam11xxxyx
Unknown command: sunbeam11xxxyx
] czx
Unknown command: czx
] abracadabra
Unknown command: abracadabra
] xz
Unknown command: xz
] zzx
Unknown command: zzx
] hehe
Unknown command: hehe
] lolazzo
Unknown command: lolazzo
] test
Unknown command: test
] z
Unknown command: z
• this is how the console looks like in-game:

Image

Image

• wrote a function that dumps the console text to Lua's window:

Code: Select all

function ParseConsoleText()

  local pString = 0x1BC2AAA8
  local pSize = 0x11AA * 2
  local i = 0

  for j = 0, pSize, 2 do
    if readBytes( pString + j, 2 ) == 0xA then
      --print( string.format( "i = 0x%X", i ) )
      --print( string.format( "j = 0x%X", j ) )
      print( readString( pString + i, j - i, true ) )
      i = j + 2
      j = j + 2
    end
  end

end

ParseConsoleText()
• this is what the Lua code produces (you may ignore the top part, it's auto-printed just in-case you fuck up something in the exec pane, to preserve historical changes):

Code: Select all

function ParseConsoleText()

  local pString = 0x1BC2AAA8
  local pSize = 0x11AA * 2
  local i = 0

  for j = 0, pSize, 2 do
    if readBytes( pString + j, 2 ) == 0xA then
      --print( string.format( "i = 0x%X", i ) )
      --print( string.format( "j = 0x%X", j ) )
      print( readString( pString + i, j - i, true ) )
      i = j + 2
      j = j + 2
    end
  end

end

ParseConsoleText()

Not mounting addon/gamemode 'counter-strike', requires missing GCF file (240) 
Not mounting addon/gamemode 'day-of-defeat', requires missing GCF file (300) 
Parent cvar in server.dll not allowed (sk_apc_missile_damage) 
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmdm.txt' missing section 'TranslationData' 
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmod.txt' missing section 'TranslationData' 
Garry's Mod client.dll Build #0016 [Jan 18 2007 23:06:10] 
maxplayers set to 1 
Heap: 256.00 Mb 
Parsed 23 text messages 
Not mounting addon/gamemode 'counter-strike', requires missing GCF file (240) 
Not mounting addon/gamemode 'day-of-defeat', requires missing GCF file (300) 
Adding Font resource/fonts/akbar.ttf 
Adding Font resource/fonts/coolvetica.ttf 
Adding Font resource/fonts/csd.ttf 
Hud element 'CHudHDRDemo' doesn't have an entry 'HudHDRDemo' in scripts/HudLayout.res 
Hud element 'CHudFilmDemo' doesn't have an entry 'HudHDRDemo' in scripts/HudLayout.res 
Hud element 'CHudCommentary' doesn't have an entry 'HudCommentary' in scripts/HudLayout.res 
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmdm.txt' missing section 'TranslationData' 
CDecalEmitterSystem::LoadDecalsFromScript:  Script 'scripts/decals/gmod.txt' missing section 'TranslationData' 
Garry's Mod server.dll Build #0016 [Jan 18 2007 23:07:22] 
execing config.cfg 
Can't use cheat cvar dsp_dist_max in multiplayer, unless the server has sv_cheats set to 1. 
Can't use cheat cvar dsp_dist_min in multiplayer, unless the server has sv_cheats set to 1. 
8 CPUs, Frequency: 3.5 Ghz,  Features: GenuineIntel SSE SSE2 MMX RDTSC CMOV FCMOV 
GetAllManifestFiles:  Unable to load maplist.txt 
execing valve.rc 
execing autoexec.cfg 
--- Missing Vgui material vgui/logos/UI/Spray_bullseye 
--- Missing Vgui material vgui/gfx/vgui/crosshair 
Unable to initialize DirectSoundCapture. You won't be able to speak to other players.couldn't exec userconfig.cfg 
Host_WriteConfiguration: Wrote cfg/config.cfg 
Changing resolutions from (1920, 1080) -> (1176, 664) 
Unable to remove d:\games\garry\garrysmod\textwindow_temp.html! 
couldn't exec userconfig.cfg 
Host_WriteConfiguration: Wrote cfg/config.cfg 
Starting Level gm_construct (Gamemode Override '') 
maxplayers set to 1 
execing game.cfg 
Spawn Server gm_construct 
Begin loading faces (loads materials) 
End loading faces (loads materials) 
Lua initialized (Lua 5.1) 
Registering gamemode 'sandbox' derived from 'base' 
Late precache of models/weapons/v_pistol.mdl 
Late precache of models/weapons/w_camphone.mdl 
Late precache of models/weapons/v_toolgun.mdl 
Late precache of models/weapons/w_toolgun.mdl 
Late precache of models/dav0r/balloon/balloon.mdl 
Late precache of models/dav0r/camera.mdl 
Late precache of models/dav0r/tnt/tnt.mdl 
Late precache of models/dav0r/hoverball.mdl 
Late precache of models/props_wasteland/prison_lamp001c.mdl 
execing skill_manifest.cfg 
execing skill.cfg 
Executing listen server config file 
Executing listen server config file 
Precache of sprites/light_glow02_add_noz ambigious (no extension specified) 
Precache of sprites/light_glow02_add_noz ambigious (no extension specified) 
Section [Scenes]: 1096 resources total 17.54 KB, 0.84 % of limit (2.10 MB) 
Game started 
couldn't exec listenserver.cfg 
couldn't exec listenserver.cfg 
Initializing renderer... 
AddPropOffsetToMap - already found entry [prop: 521 offset: 136] in table for DT_BasePlayer 
AddPropOffsetToMap - already found entry [prop: 508 offset: 136] in table for DT_GMOD_Player 
AddPropOffsetToMap - already found entry [prop: 533 offset: 136] in table for DT_HL2_Player 
AddPropOffsetToMap - already found entry [prop: 508 offset: 136] in table for DT_HL2MP_Player 
Precaching Spawn Icons................................................................................................................................ DONE! 
--- Missing Vgui material vgui/entities/weapon_annabelle 
--- Missing Vgui material vgui/entities/weapon_alyxgun 
--- Missing Vgui material vgui/entities/weapon_citizenpackage 
--- Missing Vgui material vgui/entities/weapon_citizensuitcase 
Lua initialized (Lua 5.1) 
Registering gamemode 'sandbox' derived from 'base' 
Creating RT Texture 'GModToolgunScreen'..DONE! 
Joining Game.. 
] sunbeam11xxxyx 
Unknown command: sunbeam11xxxyx 
] czx 
Unknown command: czx 
] abracadabra 
Unknown command: abracadabra 
] xz 
Unknown command: xz 
] zzx 
Unknown command: zzx 
] hehe 
Unknown command: hehe 
] lolazzo 
Unknown command: lolazzo 
] test 
Unknown command: test 
] z 
Unknown command: z
• and this is how the Lua window looks like :)

Image

What you can do next is figure out where that console buffer pointer is acquired (can be a static pointer leading to it, in which case you're lucky), then write-up a timer or a thread that executes constantly and checks the console buffer size. When size changes, clear Lua window and re-spool information. Or create 2 functions: an init one that dumps the console text to Lua window in the beginning, keeping track of the iterator (the counter) and a timer that checks console text buffer size and prints the new lines that pop after init ;)

BR,
Sun

Post Reply

Who is online

Users browsing this forum: No registered users