Raised This Month: $32 Target: $400
 8% 

Orpheu signature


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
CrazY.
Veteran Member
Join Date: May 2015
Location: SP, Brazil
Old 02-20-2019 , 11:10   Orpheu signature
Reply With Quote #1

Hello, I'm trying to make a signature to hook CSGameRules()->TeamFull (CHalfLifeMultiplay::TeamFull).

I got this sequence of bytes from cs.so,
Code:
8B 44 24 08 8B 54 24 04  83 F8 01 74 0B 83 F8 02
then

Quote:
Originally Posted by Arkshine View Post
Forget the picture.

Follow this rule, which is more simple :

- Always keep the first byte
- Disregard anything else.

Do that until you get an unique signature when checking in IDA.

This way, it may give longer signatures, but it's more reliable and easy to deal.
I discarded some bytes and got this (not sure if I did it right)
Code:
8B 44 24 08 8B 54 ? ?  ? ? 01 74 ? ? F8 02
and modified to orpheu format.
Code:
[0x8B,0x44,0x24,0x08,0x8B,0x54,"*","*","*","*",0x01,0x74,"*","*",0xF8,0x02]
In the plugin I did
Code:
OrpheuRegisterHook(OrpheuGetFunction("TeamFull", "CHalfLifeMultiplay"), "CHalfLifeMultiplay_TeamFull", OrpheuHookPre);

but I got this error:
Code:
L 02/20/2019 - 12:50:14: [ORPHEU] Function "CHalfLifeMultiplay::TeamFull" not found
Full signature, configs/orpheu/functions/CHalfLifeMultiplay/TeamFull
Code:
{ 
    "name"      : "TeamFull", 
    "class"     : "CHalfLifeMultiplay", 
    "library"   : "mod", 
    "arguments" :  
    [ 
        { 
            "type" : "int" 
        }
    ], 
    "identifiers" : 
    [ 
        { 
            "os"    : "windows", 
            "mod"   : "cstrike", 
            "value" : [0x8B,0x44,0x24,0x08,0x8B,0x54,"*","*","*","*",0x01,0x74,"*","*",0xF8,0x02]
        },  
        {  
            "os"    : "linux",  
            "mod"   : "cstrike",  
            "value" : "_ZN18CHalfLifeMultiplay8TeamFullEi"  
        } 
    ] 
}
__________________









Last edited by CrazY.; 02-20-2019 at 12:45.
CrazY. is offline
HamletEagle
AMX Mod X Plugin Approver
Join Date: Sep 2013
Location: Romania
Old 02-20-2019 , 12:51   Re: Orpheu signature
Reply With Quote #2

I checked your sequence of bytes with IDA and it doesn't match to any function so it's likely wrong. To check yourself, in IDA, go to search, sequence of bytes, add your sequence and select find all occurrences and see if you get a result. Always check the sequences you make.

How to find the function you need:

Since TeamFull is really small and doesn't contain strings you can't find it directly. Look for a function that calls it and that preferable has strings or is called from a function that has strings. Checking regamedll we find HandleMenu_ChooseTeam that calls TeamFull and we are lucky, HandleMenu_ChooseTeam has a bunch of strings.
Just pick one, like "#Too_Many_Terrorists"(without quotes) and go to Strings window and search(alt+t) with this string. You should see something like this:
Code:
.data:101155E4 23 54 6F 6F 5F 4D 61 6E 79 5F+aTooManyTerrori db '#Too_Many_Terrorists',0
.data:101155E4 54 65 72 72 6F 72 69 73 74 73+                                        ; DATA XREF: sub_10066D10+243↑o
DATA XREF is what you are looking for. It tells you that the string is used inside sub_10066D10 => sub_10066D10 is HandleMenu_ChooseTeam. Now rename it so you can easily find it in the future.

Now, ideally, you would want to decompile HandleMenu_ChooseTeam(press F5) and look in the decompiled C-like code. If you don't have IDA with a decompiler then there is an alternative, but you need to be able to read assembly code.

Let's assume you don't have the decompiler. Go to IDA View A.

We see this in regamedll:
PHP Code:
if (CSGameRules()->TeamFull(team))
    {
        
// The specified team is full
        // attempt to kick a bot to make room for this player
        
bool madeRoom false;
        if (
cv_bot_auto_vacate.value && !pPlayer->IsBot())
        {
            if (
UTIL_KickBotFromTeam(team))
                
madeRoom true;
        }

        if (!
madeRoom)
        {
            
ClientPrint(pPlayer->pevHUD_PRINTCENTER, (team == TERRORIST) ? "#Terrorists_Full" "#CTs_Full");
            return 
FALSE;
        }
    } 
TeamFull is near "#Terrorists_Full" string. So scroll on IDA View A until you find that string. Remember, what we are doing now is trying to find TeamFull call inside HandleMenu_ChooseTeam. We will look for an assembly instruction named "call", which is used to call functions.
Just a bit above this strings(4 lines) we see this:
Code:
call    sub_1008ECA0
Looks promising, it's a function call before our strings. But is it the right function? Let's look under it.

Code:
test    eax, eax
jz      short loc_10066F7C
In assembly, functions usually put their return values in eax register. Testing eax right after a call instruction usually means the code is checking for the return value.
test does bitwise and, so test eax, eax will set a flag called zero flag only if the return value stored in eax is 0.
The next instruction after this jz loc_10066F7C. jz checks if the zero flag is set(jump if 0) and if it is it will jump to loc_10066F7C address in the code(like a goto in pawn/C). Now look where loc_10066F7C is actually placed. It's way lower than the block of code we are interested in(the one with the strings).

If we put all this pieces together: the code calls a function, checks if it returned 0 and if it does return 0 it jumps away from the code we are interested in, exactly like when a if statement is false and the block of code from the if doesn't execute.
At this point you can be pretty sure that sub_1008ECA0 is the function we need. The assembly code matches the code we saw in regamedll.
You can also check the content of sub_1008ECA0 itself to make sure it matches the code from regamedll(and if do that you see it check for 1 or 2 which are the teams and returns something, so looks fine).

Let's build the signature:
Rename the function from sub_1008ECA0 to CHalfLifeMultiplay_TeamFull to make it easier in the future.

The bytes look like this:
Code:
8B 54 24 04
56
8B 74 24 0C     
3B D6
75 06
....
From each line, you will keep only the first byte and replace the other bytes with ?, resulting in:
Code:
8B ? ? ? 56 8B ? ? ? 3B ? 75
We don't know if this is an unique identifier for our function, so search the sequence and notice that we get only one result. This means that the signature is good.

Now convert into orpheu format: [0x8B,"*","*","*",0x56,0x8B,"*","*","*",0x3B," *",0x75]

The signature file is almost correct, but you are missing the return value. In regamedll it is BOOL, but that's not a default type. BOOL is just a define for int(you can check by yourself).

The final result:
Code:
{ 
    "name"      : "TeamFull", 
    "class"     : "CHalfLifeMultiplay", 
    "library"   : "mod", 
    "arguments" :  
    [ 
        { 
            "type" : "int" 
        }
    ], 
	"return"  : 
    {
        "type" : "int"
    },
    "identifiers" : 
    [ 
        { 
            "os"    : "windows", 
            "mod"   : "cstrike", 
            "value" : [0x8B,"*","*","*",0x56,0x8B,"*","*","*",0x3B,"*",0x75]
        },  
        {  
            "os"    : "linux",  
            "mod"   : "cstrike",  
            "value" : "_ZN18CHalfLifeMultiplay8TeamFullEi"  
        } 
    ] 
}
With orpheu loaded write "orpheu config" in the server console and look for the output:
Code:
Parsing file "TeamFull" started
				Argument type "int" validated
				Return type "int" validated
				Searching for signature "[0x8b][*][*][*][0x56](...)" ... FOUND
			Parsing file "TeamFull" ended
__________________

Last edited by HamletEagle; 02-20-2019 at 12:53.
HamletEagle is offline
CrazY.
Veteran Member
Join Date: May 2015
Location: SP, Brazil
Old 02-20-2019 , 14:35   Re: Orpheu signature
Reply With Quote #3

Thanks mate for your explanation, it's well detailed.

It's hooking now but there's a little problem with argument value. To debug value I did

Code:
public OrpheuHookReturn:CHalfLifeMultiplay_TeamFull(iTeam) {     server_print("[DEBUG] CHalfLifeMultiplay_TeamFull(%d)", iTeam); }

and what I got in server console
Code:
[DEBUG] CHalfLifeMultiplay_TeamFull(543457360)
For some reason it's passing a strange value instead of team index.

Code:
enum TeamName {     UNASSIGNED, // 0     TERRORIST, // 1     CT, // 2     SPECTATOR, // 3 };

I followed step by step. First I found the sub of HandleMenu_ChooseTeam
Code:
.text:10066EA3	sub_10066D90	B8 18 66 11 10                                mov     eax, offset aTerroristsFull ; "#Terrorists_Full"
.data:10116618		23 54 65 72 72 6F 72 69 73 74+aTerroristsFull db '#Terrorists_Full',0 ; DATA XREF: sub_10066D90+113↑o
After that I decompiled it to get the sub of TeamFull
Code:
LABEL_9:
      if ( sub_1008ECA0(v7) )
      {
        v9 = flt_101101E4 < 0.0;
        v10 = 0;
        v11 = flt_101101E4 == 0.0;
        if ( v8 & 0x4100 || (*(int (__thiscall **)(int))(*(_DWORD *)a1 + 324))(a1) || !(unsigned __int8)sub_10036A60(v7) )
        {
          v12 = aTerroristsFull;
          if ( v7 != 1 )
            v12 = aCtsFull;
LABEL_40:
          sub_100C3BF0(*(_DWORD *)(a1 + 4), 4, v12, 0, 0, 0, 0);
          return 0;
        }
      }
and its bytes

Code:
.text:1008ECA0 8B 44 24 04                                   mov     eax, [esp+arg_0]
.text:1008ECA4 56                                            push    esi
.text:1008ECA5 48                                            dec     eax
.text:1008ECA6 74 1C                                         jz      short loc_1008ECC4
.text:1008ECA8 48                                            dec     eax
.text:1008ECA9 74 06                                         jz      short loc_1008ECB1
.text:1008ECAB 33 C0                                         xor     eax, eax
.text:1008ECAD 5E                                            pop     esi
.text:1008ECAE C2 04 00                                      retn    4


Code:
8B ? ? ? 56 48 74 ? 48 74 ? 33 ? 5E C2 ?

Code:
[0x8B,"*","*","*",0x56,0x48,0x74,"*",0x48,0x74,"*",0x33,"*",0x5E,0xC2,"*"]
orpheu config
Code:
Parsing folder "CHalfLifeMultiplay" started
			Parsing file "TeamFull" started
				Argument type "int" validated
				Return type "int" validated
				Searching for signature "[0x8b][*][*][*][0x56](...)" ... FOUND
			Parsing file "TeamFull" ended
		Parsing folder "CHalfLifeMultiplay"
What I did wrong?
__________________









Last edited by CrazY.; 02-20-2019 at 14:55.
CrazY. is offline
HamletEagle
AMX Mod X Plugin Approver
Join Date: Sep 2013
Location: Romania
Old 02-20-2019 , 14:57   Re: Orpheu signature
Reply With Quote #4

I may be wrong, but it should pass an object as the first argument, so in your plugin you should have:
public OrpheuHookReturn:CHalfLifeMultiplay_TeamFull( this, iTeam)
__________________

Last edited by HamletEagle; 02-20-2019 at 14:57.
HamletEagle is offline
CrazY.
Veteran Member
Join Date: May 2015
Location: SP, Brazil
Old 02-20-2019 , 15:07   Re: Orpheu signature
Reply With Quote #5

Yes that's right, thank you.
Orpheu it's not that so hard as I thought.
__________________








CrazY. is offline
Reply



Posting Rules
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 On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 08:17.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode