PDA

View Full Version : Orpheu: How to make signatures (of bytes)


Arkshine
01-16-2011, 20:44
Orpheu : How to make signatures (of bytes)
- last updated : 16 jan 2010


Hello John D., welcome.

You are here because you have found a function by reading the tutorial Searching for functions in libraries (http://forums.alliedmods.net/showthread.php?t=118934) and because you know how to make a function file (http://forums.alliedmods.net/showthread.php?t=116393).
If not, you are invited do it now, please.

Let's start.

topContents :
Configuring IDA
Making a signature of bytes
Displacement




configurationConfiguring IDA top

So, you found CBasePlayerWeapon::KickBack(). Why not.

Before, to make more easily a signature, we need to configure IDA by showing the opcode bytes. You will understand.

Start to open IDA on this function.
Click on the IDA View tab, if not done already. If you are in graph view, click right and select Text View.
Go to the menu : Options > General.
http://i.imgur.com/OBGZl01.png
In the windows, at the right, you see "Number of opcode bytes". Put a number like 10.

http://i.imgur.com/VMS26fB.png
After validiting, you see finally something like the following image. Notice now the opcode bytes at the left.

http://i.imgur.com/ihoT02a.png


makingMaking a signature of bytes top

We are ready to start to make a signature of bytes.

You have to keep in mind :
The signature needs to be unique.
The signature must start from the top of the function.

The length of the signature will depend of the content of the function.
If the content is somehow unique like KickBack(), you won't need a large signature.
If the content has a lot of memory references, there is a chance you would need a large signature.

A reminder : a signature would be an array of bytes or "*" or "?".
"*" is meant to be used when you don't care about the value of that byte.
"?" is meant to be used when you don't care about the value of the byte and it can even not exist.

About when you should place "*", a good rule would be : any memory references.
I can't explain because I don't know enough about assembly/memory but that's something it will change at restart.
It's explained further down.

Note : in IDA, '?' has the same meaning as '*' in Orpheu.


So, here my way, the main steps :
We retrieve an amount of bytes.
We replace any memory references with '?'.
We check with IDA if this block of bytes is well referenced one time. If not, back to 1) and increasing the amount of bytes.
We modify the block of bytes to be compliant to the Orpheu format.
We make the function file and we test.

1) We retrieve an amount of bytes

- Make sure the cursor is at the top of the function.
- Go the Hex View tab.
- Select an amount of bytes, like at least the first 16 bytes.
http://i.imgur.com/96gruqD.png
- Copy them in a text editor.
http://i.imgur.com/XdVJFqJ.png


2) We replace any memory references with '?'

EDIT: A more simple way would be :
Keep always the first byte
Replace any others bytes with "?"
That's all.

Before wanted to replace we need to understand what we have to replace.
You don't need really to know about assembly to do that, though there are few things to know.
I don't know much about it, so if you want to learn more, search for tutorials.

Here, how is composed an instruction. All are optional except the opcode. (image stolen from a tutorial)
All "SIB", "Displacement" and "Immediate" would need to be replaced with "*".
Basically, when you see any value, call to a function and jump to a location or value referenced with a var.

http://i.imgur.com/exlYgpB.png

Let's try with the KickBack() bytes.

51 push ecx // no memory reference.
└────── Opcode ────────┴───────┘ // 51
(fixed form)

56 push esi // no memory reference.
└────── Opcode ────────┴───────┘ // 51 56
(fixed form)

8B F1 mov esi, ecx // no memory reference.
└──┼───── Opcode ──────┘ │ │ // 51 56 8B F1
└───── ModR/M ──────────────┴────┘

8B 86 00 01 00 00 mov eax, [esi+100h] // 100h is an offset. It may change.
└──┼──┼── Opcode ──────┘ │ │ │ // 51 56 8B F1 8B 86 ? ? ? ?
└──┼── ModR/M ──────────────┴─────┘ │
└── Displacement ──────────────────┘
83 F8 01 cmp eax, 1 // no memory reference, but an hardcoded value. It may change by a plugin or something.
└──┼──┼── Opcode ──────┘ │ │ // 51 56 8B F1 8B 86 ? ? ? ? 83 F8 ?
└──┼── ModR/M ──────────────┘ │
└── Immediate ───────────────┘

89 44 24 04 mov [esp+8+var_4], eax // When you click right on it, you see 8+var_4 is equal to 4, a relative offset.
└──┼──┼──┼─ Opcode ────┘ │ │ │ │ // Anyway, it may change. I've notived also the SIB is generally different on cz.
└──┼──┼─ ModR/M ─────────────┼──┼───┼──────┘ // 51 56 8B F1 8B 86 ? ? ? ? 83 F8 ? 89 44 ? ?
└──┼─ SIB ────────────────┘ │ │
└─ Displacement ──────────┴───┘

Since we don't care the value of the two last bytes, we have finally :

http://i.imgur.com/Mdml3yV.png
It might not be enough.


3) We check with IDA if this block of bytes is well referenced one time

Let's check if IDA find only one reference.
Go the menu, Search > sequence of bytes... or you can use the shortcut alt + B.

http://i.imgur.com/4eZzw4G.png
In the windows, paste the block of bytes.
Make sure to mark as Hex and you want to Find all occurences.

http://i.imgur.com/gxHC2HY.png
As result, we see one reference, and it's good. It means it's unique and we can use this block of bytes as signature.

http://i.imgur.com/4mBw01X.png

4) We modify the block of bytes to be compliant to the Orpheu format

Don't bother to do byte by byte. With your text editor you can use replace.
It's probably possible to create a macro to do the task automatically, if your software supports the macros.

Anyway, manually :

// So, you have that.
51 56 8B F1 8B 86 ? ? ? ? 83 F8 ? 89 44

// Replace all ' ?' by ,"*". Be careful if use '?' for orpheu.
51 56 8B F1 8B 86,"*","*","*","*" 83 F8,"*" 89 44

// Replace all ' ' by ',0x'
,0x51,0x56,0x8B,0xF1,0x8B,0x86,"*","*","*","*",0x83,0xF8,"*",0x89,0x44

// Fix the first byte, add '[' and '] and your signature is ready.
[0x51,0x56,0x8B,0xF1,0x8B,0x86,"*","*","*","*",0x83,0xF8,"*",0x89,0x44]


5) We make the function file and we test

We make our file :

{
"name" : "KickBack",
"class" : "CBasePlayerWeapon",
"library" : "mod",
"arguments" :
[
{
"type" : "float"
},
{
"type" : "float"
},
{
"type" : "float"
},
{
"type" : "float"
},
{
"type" : "float"
},
{
"type" : "float"
},
{
"type" : "int"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x51,0x56,0x8B,0xF1,0x8B,0x86,"*","*","*","*",0x83,0xF8,"*",0x89,0x44]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "KickBack__17CBasePlayerWeaponffffffi"
}
]
}


Then, start your server and check your log, you should see something like :


Parsing folder "CBasePlayerWeapon" started
Parsing file "KickBack" started
Argument type "float" validated
Argument type "float" validated
Argument type "float" validated
Argument type "float" validated
Argument type "float" validated
Argument type "float" validated
Argument type "int" validated
Searching for signature "[0x51][0x56][0x8b][0xf1][0x8b](...)" ... FOUND
Parsing file "KickBack" ended
Parsing folder "CBasePlayerWeapon" ended

If you see "FOUND", be happy.
If you see "NOT FOUND", check carefully what you have done. It may either a typo or you have missed a byte to ignore.




displacementDisplacement top

Depending the content of the function, it may be impossible to make a decent signature of bytes, either because there are only few bytes or too much memory references.
In this case, you have the possibility to use the "displacement" field.

It allows you to define a block of bytes which doesn't start from the top of the function, then you need to adjust with this field.
It can be negative or positive value.

Example with our previous signature, I remove the 2 first bytes :

{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x51,0x56,0x8B,0xF1,0x8B,0x86,"*","*","*","*",0x83,0xF8,"*",0x89,0x44]
},

You can do that :

{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x8B,0xF1,0x8B,0x86,"*","*","*","*",0x83,0xF8,"*",0x89,0x44],
"displacement" : -2
},

I think you get the idea.



Feel free to ask if you don't understand something.

I will add later a plugin to get the bytes from an offset provided.
It may help if you have problems to make a signature.

That's all.

ConnorMcLeod
01-17-2011, 02:09
What Should I Do With That Plugin ?
How To Install ?

So, is IDA Pro needed ?

Arkshine
01-17-2011, 05:38
It doesn't matter what version you use. You need IDA, that's all.

Seta00
01-17-2011, 10:49
Excellent resource! (Lacks a few 'be's, but who cares? :D)

Arkshine
01-17-2011, 10:52
Where. :twisted:

meTaLiCroSS
01-17-2011, 11:35
:D... too pro for me :c.

Arkshine
01-17-2011, 11:36
That's not hard as you think. Even me I can, so you can too. :p It's because you are not used to play with IDA. Anyway, if you have difficulties, you can ask here.

Exolent[jNr]
01-17-2011, 14:05
What about finding a memory address for a variable that you want to modify?

Arkshine
01-17-2011, 14:32
You're right, I've missed that. I will add later, though the method is the same.

drekes
03-08-2011, 21:00
After a while i got it working :D

I've used CBaseButton::ButtonUse with this signature:

{
"name" : "ButtonUse",
"class" : "CBaseButton",
"library" : "mod",
"arguments" :
[
{
"type" : "int"
},
{
"type" : "int"
},
{
"type" : "int"
},
{
"type" : "float"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x56,0x8B,0xF1 ,0x57,"*","*","*","*","*","*","*","*","*",0x0F,0x84,0xFC,0x00,0x00,0x00]
}
]
}and this code to test it:

#include <amxmodx>
#include <orpheu>


public plugin_init()
OrpheuRegisterHook(OrpheuGetFunction("ButtonUse", "CBaseButton"), "HandleButtonUse");


public HandleButtonUse(id, iButton, iUseType, Float: flSomething)
client_print(0, print_chat, "Orpheu says: Button used :O");
Thanks man, this is awesome.

Exolent[jNr]
03-08-2011, 21:12
You're right, I've missed that. I will add later, though the method is the same.

Could I get that added some time soon? :)

Arkshine
03-09-2011, 05:41
...

Nice try, but that's not totally correct.

When you check if the signature is well referenced one time, you see 2 references.
You need add more bytes.

Also you use "*" wrongly. See below, in blue it's what you should use "*". It should be enough.

.text:10064C80 56 push esi
.text:10064C81 8B F1 mov esi, ecx
.text:10064C83 57 push edi
.text:10064C84 8B 86 A4 00 00 00 mov eax, [esi+0A4h]
.text:10064C8A 83 F8 02 cmp eax, 2
.text:10064C8D 0F 84 FC 00 00 00 jz loc_10064D8F
.text:10064C93 83 F8 03 cmp eax, 3
.text:10064C96 0F 84 F3 00 00 00 jz loc_10064D8F
.text:10064C9C 8B 44 24 0C mov eax, [esp+8+arg_0]

So, a final signature would be : [0x56,0x8B,0xF1,0x57,0x8B,0x86,"*","*","*","*",0x83,0xF8,"*",0x0F,0x84,"*","*","*","*",0x83,0xF8,"*",0x0F,0x84,"*","*","*","*",0x8B]

But like you can see in IDA, you see CBasePlayer::ButtonUse(CBaseEntity*,CBaseEnti ty*,USE_TYPE,float) is exported (you can see easily because you see all the arguments type), it means there is a symbol name for this function. Click right on the function at left and choose "Edit function". You will see : ?ButtonUse@CBaseButton@@QAEXPAVCBaseEntity@@0 W4USE_TYPE@@M@Z

About the signature file, you have not written properly the arg type. The 2 first should be CBaseEntity * (It's written in IDA). About "int", the type is "USE_TYPE" but it's just a tag for an enum and the value passed is anyway an "int", but since "USE_TYPE" is supported, use it.

So, the file should be like :


{
"name" : "ButtonUse",
"class" : "CBaseButton",
"library" : "mod",
"arguments" :
[
{
"type" : "CBaseEntity *",
"info" : "pActivator"
},
{
"type" : "CBaseEntity *",
"ingo" : "pCaller"
},
{
"type" : "USE_TYPE",
"info" : "useType"
},
{
"type" : "float",
"info" : "value"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : "?ButtonUse@CBaseButton@@QAEXPAVCBaseEntity@@0 W4USE_TYPE@@M@Z"
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "ButtonUse__11CBaseButtonP11CBaseEntityT18USE_ TYPEf"
}
]
}


Notive I've added the linux signature. If you release a plugin with a signature file, don't forget to do for linux. You have just to open the .so, editing the function and copy-paste the symbol name.
You are encouraged to make comments if necessary by using the key "info".

Hope you will understand better. Nice to see someone trying to play with orpheu. :)

schmurgel1983
03-09-2011, 07:48
So, you found CBasePlayerWeapon::KickBack().thanks arky for don't answer my pm :)
i don't found any CBasePlayerWeapon what made i wrong?
http://img811.**************/img811/1521/neuebitmapv.png

Arkshine
03-09-2011, 08:37
thanks arky for don't answer my pm

I don't see the point to PM someone when you could ask in the related thread and helping others people who wanted to know the same thing. Like you see, you won't get the answer more fastly by PM me.

It's a function not exported, so without symbol name. You need to find the function and rename it. For sure, I could have said more clearly where to find the function, but the answer is already in the tutorial, either using the offset on the image, or the signatures of bytes.

Go to Search > Jump to file offset... > Type D9550 and valid.
Scroll up a bit and you will see a function name like sub_* , just click right on it, then rename it in CBasePlayerWeapon::KickBack.

@Exolent[jNr] : Will try to add today, but do you have in mind something specific ? I could base the explanation on it.

drekes
03-09-2011, 09:58
Okay, i gave it another try.
I searched CArmoury::ArmouryTouch and got this as signature:


{
"name" : "ArmouryTouch",
"class" : "CArmoury",
"library" : "mod",
"arguments" :
[
{
"type" : "CBaseEntity *",
"info" : "Entity id"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : "?ArmouryTouch@CArmoury@@QAEXPAVCBaseEntity@@@ Z"
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "ArmouryTouch__8CArmouryP11CBaseEntity"
}
]
}It works, but can you confirm if the signature is right this time ?

Arkshine
03-09-2011, 11:24
It seems right.

But here it's an easy function since it's exported and you don't need to make a signature. :p

drekes
03-09-2011, 11:36
Could you give me a harder function to find, so i can see if i got the way it works right

Arkshine
03-09-2011, 11:56
Just look at the linux binary with IDA, pick up randomly a function which is not renamed in the windows one. But if you want a function, hmm, try to search HandleMenu_ChooseTeam() and make a signature.

schmurgel1983
03-09-2011, 12:53
thanks :) its work
but how do u know sub_100D9550 is CBasePlayerWeapon::KickBack thats what i dosen't understand xD

drekes
03-09-2011, 12:59
I'm having problems with that too.
I think i have the value for linux, but can't seem to find the windows value.

This is what i currently have:

{
"name" : "HandleMenu_ChooseTeam",
"class" : "CBasePlayer",
"library" : "mod",
"arguments" :
[
{
"type" : "CBasePlayer *",
"info" : "Player id"
},
{
"type" : "int",
}
],
"identifiers" :
[
{
"os" : "windows",
"mod" : "cstrike",
"value" :
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "HandleMenu_ChooseTeam__FP11CBasePlayeri"
}
]
}

Arkshine
03-09-2011, 13:51
Like said, you want some difficulty, try to find the function. There is a tuto about how to find functions. Use the IDA with linux binary to see what you can check in IDA with windows binary. Making a signature file is very easy. Which is more difficult is to find a function in windows. Not funny If I give you directly the offset. ^^ (but if you really don't get how to find the function, I will give the solution :p)

drekes
03-09-2011, 14:44
I'll keep trying, i'll figure it out sometime :)

drekes
03-09-2011, 21:41
I've been spending several hours now, reread the 2 linked tutorials,
but i can't seem to figure out how to find the windows offset.
Maybe you can lead me in the right direction ;)

Arkshine
03-10-2011, 05:12
To search a function in windows, it's a matter of searching string and/or looking where are referenced a function. Here, the function is filled with string. It will be easy to find it.

So, you have just to pick up a string in linux, copy, and checking in windows.

To check a string among the referenced ones, go to View > Open subviews > Strings. Then in this new tab, search for a specific string. You can do Search > Search... or ALT + T.
Once you done, click on the string, you will be redirected where the string is referenced.

From there, you can see a variable (aSomething) associated to the full string name and its xrefs. xrefs are where are referenced the string in the functions. By default it shows only the 2 first xrefs and to have a full list you need to select the variable and clicking right on Jump to xref to operand... or use X. Now it's just a matter to click on it and see if it's the right function. For this function, you're lucky it's actually easy. :p.

drekes
03-10-2011, 06:29
I think i got it, at least i found something
but when i make the signature it always says:
FILE FORMATTED INCORRECT

I've rewritten it 3 times, but i fail to get it right or to see what i'm doing wrong.

{
"name" : "HandleMenu_ChooseTeam",
"library" : "mod",
"arguments" :
[
{
"type" : "CBasePlayer *"
},
{
"type" : "int"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x81,0xEC,"*","*","*","*",0x53,0x55,0x,0x8B,0x2D,0x7C,0x8F,0x12,0x10,0 x56,0x8B]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "HandleMenu_ChooseTeam__FP11CBasePlayeri"
}
]
}

Arkshine
03-10-2011, 06:38
,0x, be careful when you copy the bytes from Hexview tab, there is a space :p like : 16 bytes space 16 bytes, remove this extra space. (by the way it should start by 83 not 81 :p )

drekes
03-10-2011, 08:16
That's why i didn't saw what's wrong, i just copied the value when i rewrote it.
I'll check it again, see if i can find the right value now.
Thanks

drekes
03-10-2011, 14:23
I still haven't been able to find it. I've found several values that i though could be the right one, but none starts with 83.
I also haven't found any string values in either IDA and the decompiled version of the linux library from the how to find functions tutorial.

Arkshine
03-10-2011, 14:30
To find HandleMenu_ChooseTeam() in linux, you have just to open your eyes at left. If not done, you can sort the list by name. And you have to scroll down until you find it. If you still have problem to find it (it would be really weird), just use ALT + T on the list, and type the function name. EDIT: you can even click on the function from CHalfLifeMultiplay::PlayerThink() or others where you find references.

Once done, you can see there are severals strings in this function.

drekes
03-10-2011, 16:30
I think i got it, it says FOUND in console but did i do right with the "*".

{
"name" : "HandleMenu_ChooseTeam",
"library" : "mod",
"arguments" :
[
{
"type" : "CBasePlayer *",
"info" : "Player id"
},
{
"type" : "int",
"info" : "Menu Item"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x83,0xEC,"*",0x8B,0x0D,"*","*","*","*",0x53,0x55,0x56,0x8B,0x74,"*","*",0x57,0x33,0xFF]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "HandleMenu_ChooseTeam__FP11CBasePlayeri"
}
]
}
EDIT: updated sig with "info" things

Arkshine
03-10-2011, 17:52
Yep, it's ok. Mine is the same but just a bit more long but since yours is still referenced one time, it's all good. You can also add "info" above "arguments" if you want to add a description for the function.

Anyway good job. :)

drekes
03-10-2011, 21:07
Thanks, i'm glad i finally got the hang of it.
Time to experiment with the possibilities now =)

ConnorMcLeod
04-15-2011, 01:52
What is wrong with this ?
I'm trying to find AddAccount signature

So first i've founded CBasePlayer::AddAccount(int,bool) in "Names" window
Double clicked on it, put cursor above function name in "IDA View-A" and jumped to Hex View-A window to find bits

It doesn't begin at the start of a line but i don't think it is a problem, so first 16 bits are :
55 89 E5 83 EC 0C 57 56 53 E8 EE FF FF FF 81 C3

Search for "55 89 E5 83 EC ? 57 56 53 E8 EE ? ? ? 81 C3" in IDA returns me around 1600 occurences, so i put more bits untill i found only 1 result

55 push ebp
89 E5 mov ebp, esp
83 EC 0C sub esp, 0Ch
57 push edi
56 push esi
53 push ebx
E8 EE FF FF FF call sub_EDE28
81 C3 92 73 0F 00 add ebx, (offset loc_F7391+1)
8B 7D 08 mov edi, [ebp+arg_0]
8B 87 E0 01 00 00 mov eax, [edi+1E0h]
03 45 0C add eax, [ebp+arg_4]

So
55 89 E5 83 EC 0C 57 56 53 E8 EE FF FF FF 81 C3 ? ? ? ? 8B 7D ? 8B 87 ? ? ? ? 03 45
and
8B 7D ? 8B 87 ? ? ? ? 03 45
and
8B 87 ? ? ? ? 03 45
returned a unique occirence in IDA

Tried :


[0x55,0x89,0xE5,0x83,0xEC,"*",0x57,0x56,0x53,0xE8,0xEE,"*","*","*",0x81,0xC3,"*","*","*","*",0x8B,0x7D,"*",0x8B,0x87,"*","*","*","*",0x03,0x45]


and (tried to put less bits with displacement)

[0x8B,0x87,"*","*","*","*",0x03,0x45]
"displacement" : -23

and also:

"value" : [0x8B,0x7D,"*",0x8B,0x87,"*","*","*","*",0x03,0x45],
"displacement" : -20


I'm testing on a listenserver


configs\orpheu\functions\CBasePlayer\AddAccou nt
->
{
"name" : "AddAccount",
"class" : "CBasePlayer",
"library" : "mod",
"arguments" :
[
{
"type" : "int",
"info" : "amount"
},
{
"type" : "bool",
"info" : "bTrackChange"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x8B,0x7D,"*",0x8B,0x87,"*","*","*","*",0x03,0x45],
"displacement" : -20
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "AddAccount__11CBasePlayerib"
}
]
}


Cs console says that signature is NOT FOUND.

ConnorMcLeod
04-15-2011, 11:09
Solved (with all day arkshine's help), was looking in linux file...

{
"name" : "AddAccount",
"class" : "CBasePlayer",
"library" : "mod",
"arguments" :
[
{
"type" : "int",
"info" : "amount"
},
{
"type" : "bool",
"info" : "bTrackChange"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x8B,0x44,"*","*",0x56,0x8B,0xF1,0x8B,0x8E,"*","*","*","*",0x03,0xC8,0x89]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "AddAccount__11CBasePlayerib"
}
]
}

Arkshine
04-15-2011, 11:16
Wooo. Congratulation. One person of more now converted to Orpheu. Next ?

ConnorMcLeod
04-15-2011, 12:02
Make 1 sig doesn't mean you are converted, there is a lot to learn.

Arkshine
04-15-2011, 13:10
You are interested by Orpheu now, and trying to understand how work things. Basically, you are converted because you're going anyway to learn more and more, otherwise you would not have spent that time on it.

That said, will try to update tutorial soon. I had forgot the xolent's request.

K.K.Lv
04-20-2012, 03:23
I have found this

00068BE4 55 89 E5 81 EC 5C 08 00 00 57 56 53 E8 EB FF FF

with IDA at engine_i686.so
because I try to hook this function

SV_SendServerinfo

but when I use above line to make a signature, and the function was not found.
what is the correct way to find the function, and use it ?
PS:server using the win version. finding the function with the linux version.
please help me how to do it ?

edited:
when I see Connor post, I think I got the same problem !
How to find the correct windows value ?
because I can't find the "SV_SendServerinfo" at windows file .

Arkshine
04-20-2012, 04:12
Did you read this tutorial http://forums.alliedmods.net/showthread.php?t=118934 ?

Just a matter to find some reference in linux and searching in windows with that.
Looking inside the function, it has strings, it should be easy to find it on windows.

K.K.Lv
04-20-2012, 04:35
Maybe I have found it

.text:01D968E0 sub_1D968E0 proc near ; CODE XREF: sub_1D972D0+BAp
.text:01D968E0 ; sub_1D9D7B0+229p


but the server console still tell me "File incorrectly formatted"

folder:addons\amxmodx\configs\orpheu\function s\engine
name SV_SendServerinfo
signature:

{
"name" : "SV_SendServerinfo",
"library" : "engine",
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x55,0x8B,0xEC,0x81,0xEC,0x04,0x08, "*", "*",0xD9,0x05,0x28,0x56,0xE5,0x01,0xD8]
}
{
"os" : "linux",
"mod" : "cstrike",
"value" : "SV_SendServerinfo"
}
]
}

server print
http://forums.alliedmods.net/attachment.php?attachmentid=102428&stc=1&d=1334910926

Arkshine
04-20-2012, 04:45
You forget , et put spaces when you should not in the signature :

Try :


{
"name" : "SV_SendServerinfo",
"library" : "engine",
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x55,0x8B,0xEC,0x81,0xEC,0x04,0x08,"*","*",0xD9,0x05,0x28,0x56,0xE5,0x01,0xD8]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "SV_SendServerinfo"
}
]
}

K.K.Lv
04-20-2012, 04:59
"class name must be equal to folder name"
how to fix it ?
forgive me I learning :).

Arkshine
04-20-2012, 05:04
Don't remember the error exactly ; this file should be put inside functions/ at the root (not in a sub-directory).
If not about parsing, show your code so.

K.K.Lv
04-20-2012, 05:12
OK , I will try to explain it clear.

try to hook function is "SV_SendServerinfo"
and I found the windows version line here

.text:01D968E0 55 push ebp
.text:01D968E1 8B EC mov ebp, esp
.text:01D968E3 81 EC 04 08 00 00 sub esp, 804h
.text:01D968E9 D9 05 28 56 E5 01 fld flt_1E55628
.text:01D968EF D8 1D AC E0 E2 01 fcomp ds:flt_1E2E0AC
.text:01D968F5 53 push ebx
.text:01D968F6 56 push esi
.text:01D968F7 8B 75 08 mov esi, [ebp+arg_0]
.text:01D968FA 57 push edi
.text:01D968FB DF E0 fnstsw ax
.text:01D968FD F6 C4 44 test ah, 44h
.text:01D96900 7A 09 jp short loc_1D9690B
.text:01D96902 83 3D C8 62 13 02 01 cmp dword_21362C8, 1
.text:01D96909 7E 41 jle short loc_1D9694C

correct me if I'm wrong.

and my signature is

{
"name" : "SV_SendServerinfo",
"library" : "engine",
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x55, 0x8B, 0xEC, 0x81, 0xEC, 0x04, 0x08, "*", "*", 0xD9, 0x05, 0x28, 0x56, 0xE5, 0x01, 0xD8]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "SV_SendServerinfo"
}
]
}

signature name is "SV_SendServerinfo"

folder is "cstrike\addons\amxmodx\configs\orpheu\functio ns"

and the problem is "signature is not found"

Arkshine
04-20-2012, 05:39
Try this one :

[0x55,0x8B,"*",0x81,"*","*","*","*","*",0xD9,"*","*","*","*","*",0xD8,"*","*","*","*","*",0x53,0x56,0x8B,"*","*",0x57]

K.K.Lv
04-20-2012, 08:46
Yeah , got it !
1.why ?
2.what type argument dose this function pass ? how to find it ?

Arkshine
04-20-2012, 10:19
1. Why what ? If you're talking about why my signature works is because you don't have really understood my tutorial and you don't have put enough "*" for instructions/value which can change. If you want a rule more simple : keep always the first byte, and keep when e*x are used ; others you can put a *.

2. By guessing/searching. It seems to have 2 args. Both pointer. First not sure, it seems an address of a string is passed and second it's client_t* client for sure. It makes me think you did not add the args in the signature.

K.K.Lv
04-20-2012, 10:26
I think I know something,because I have found a new function like this, and done it ! :)

{
"name" : "SV_DropClient",
"library" : "engine",
"arguments" :
[
{
"type" : "int"
},
{
"type" : "int"
},
{
"type" : "char *"
},
{
"type" : "char"
}
],
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x55,0x8B,"*",0x81,"*","*","*","*","*",0x8B,"*","*",0x53,0x56,0x8D,"*","*",0x57,0x50]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "SV_DropClient"
}
]
}

like you said, there was much to learn :mrgreen:
thx man !

edited:

#include <amxmodx>
#include <orpheu>

public plugin_init()
{
register_plugin("", "", "")

OrpheuRegisterHook(OrpheuGetFunction("SV_DropClient"), "Hook_SV_DropClient")
}

public OrpheuHookReturn:Hook_SV_DropClient(a, b, c[], d)
{
server_print("%i, %i, %s, %c", a, b, c, d);
}

use this code and get this at the console
115283104, 0, Client sent 'drop', <

ConnorMcLeod
04-20-2012, 11:55
Yeah , got it !
1.why ?
2.what type argument dose this function pass ? how to find it ?

This is from an old hlds version
//sends things like gravity, part of this is IDable from SV_New
void SV_SendServerinfo(sizebuf_t * buffer, client_t * ptrClient) {

char tempstr[0x80]; //Ought to be enough for now.
unsigned int var808;
CRC32_t var814;
unsigned int var_filesize;
BYTE * LoadedFile;

int i;

if(global_svs.allocated_client_slots > 1 || cvar_developer.value != 0) {

MSG_WriteByte(buffer, 8);
//This doesn't look like good, quality, correct functionality to me.
/*
Q_snprintf(array800, sizeof(array800)-1, "%c\nOSHLDS BUILD %d SERVER (%i CRC)\nServer # %i\n",
2, build_number(), 0, global_svs.ServerCount);
array800[sizeof(array800)-1] = '\0';
MSG_WriteString(buffer, array800);
*/

//Meanwhile, this is messy, but should be faster.
//The -1 +1s are all in place to prevent us from writing a null until the very end.
#define __SVSERVERWELCOME_1 "\x02" "\nOSHLDS VER "
#define __SVSERVERWELCOME_2 " BUILT " __DATE__ "--" __TIME__ "\nServer # "
MSG_WriteBuf(buffer, sizeof(__SVSERVERWELCOME_1)-1, __SVSERVERWELCOME_1);

i = sprintf(tempstr, "%u", build_number());
MSG_WriteBuf(buffer, i, tempstr);
MSG_WriteBuf(buffer, sizeof(__SVSERVERWELCOME_2)-1, __SVSERVERWELCOME_2);

i = sprintf(tempstr, "%u\n", global_svs.ServerCount);
MSG_WriteBuf(buffer, i+1, tempstr);
}

MSG_WriteByte(buffer, 0x0B);
MSG_WriteLong(buffer, 0x2E);
MSG_WriteLong(buffer, global_svs.ServerCount);

var808 = NUM_FOR_EDICT(ptrClient->padding4A84) - 1;
var814 = global_sv.map_CRC;

COM_Munge3((char *)(&var814), 4, (0xFF - var808) & 0xFF); //Yeah, looks like we're munging an int...

MSG_WriteLong(buffer, var814);
MSG_WriteBuf(buffer, 0x10, global_sv.usedpadding);
//I'm guessing that means "player X of Y".
MSG_WriteByte(buffer, global_svs.allocated_client_slots);
MSG_WriteByte(buffer, var808);

if(cvar_deathmatch.value == 0 || cvar_coop.value != 0) {
MSG_WriteByte(buffer, 1);
}
else {
MSG_WriteByte(buffer, 0);
}

COM_GetGameDirSize(tempstr, sizeof(tempstr));
MSG_WriteString(buffer, tempstr);
MSG_WriteString(buffer, cvar_hostname.string);
MSG_WriteString(buffer, global_sv.name4);

LoadedFile = COM_LoadFileForMe(cvar_mapcyclefile.string, &var_filesize);

if(LoadedFile != NULL) {
if(var_filesize != 0) {
MSG_WriteString(buffer, LoadedFile);
}
else {
MSG_WriteString(buffer, "mapcycle failure");
}
COM_FreeFile(LoadedFile);
}
else {
MSG_WriteString(buffer, "mapcycle failure");
}

MSG_WriteByte(buffer, global_svs.paddingE8);
if(global_svs.paddingE8 != 0) {

MSG_WriteByte(buffer, 4);
MSG_WriteBuf(buffer, 4, &(sUpdateIPAddress.ip)); //That's the ADDRESS, or a pointer to object.padding4
MSG_WriteBuf(buffer, 0x10, &global_svs.module80[1].buf10);
}
MSG_WriteByte(buffer, 0x36);
MSG_WriteString(buffer, com_clientfallback); //This was always an empty string for us. What does it do otherwise?
MSG_WriteByte(buffer, allow_cheats);

SV_WriteDeltaDescriptionsToClient(buffer);
SV_SetMoveVars();
SV_WriteMovevarsToClient(buffer);

MSG_WriteByte(buffer, 0x20);
MSG_WriteByte(buffer, gGlobalVariables.cdAudioTrack);
MSG_WriteByte(buffer, gGlobalVariables.cdAudioTrack);
MSG_WriteByte(buffer, 0x05);

MSG_WriteShort(buffer, NUM_FOR_EDICT(ptrClient->padding4A84));

ptrClient->padding04 = 0;
ptrClient->padding08 = 0;
ptrClient->padding0C_connected = 1;
}

K.K.Lv
04-20-2012, 12:30
where dose you get it connor ?

Arkshine
04-20-2012, 13:57
Here http://team.steamlessproject.org/rguest/hlds.html

hornet
06-04-2012, 08:05
Wooo. Congratulation. One person of more now converted to Orpheu. Next ?

Yep, looks like I'm up next :)

I want to try and make a function file for CBaseEntity::Spawn. I've located it in the decompressed Linux file but there doesn't seem to be anything distinctive to use to locate it in the Windows function dump ( ... or really anything at all ):

void __cdecl CBaseEntity__Spawn()
{
;
}

I've tried searching through the text in the Windows library but couldn't find anything.

May I please have some help finding it? :)

Arkshine
06-04-2012, 09:54
Spawn is a virtual function. Prefer the use of Ham, more simple. The tutorial is not for such functions since it doesn't require signatures.

K.K.Lv
06-04-2012, 12:40
http://forums.alliedmods.net/showthread.php?t=118138. Maybe it could help you , I have hook player spawn and work fine ;)

hornet
06-04-2012, 22:59
Well I was actually after entity spawn, not particularly player spawn. They are different, right?

ConnorMcLeod
06-05-2012, 00:27
Well I was actually after entity spawn, not particularly player spawn. They are different, right?

int __cdecl CBaseEntity::Spawn(CBaseEntity *this)
{
;
}

You try to hook an empty function, that is only called for following classes :
http://img811.**************/img811/7703/spawns.png


if you want to catch entities spawns, not players, you can hook DispatchSpawn (there is a metamod forward for this, don't bother with sigs) :
int DispatchSpawn( edict_t *pent )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);

if (pEntity)
{
// Initialize these or entities who don't link to the world won't have anything in here
pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1);
pEntity->pev->absmax = pEntity->pev->origin + Vector(1,1,1);

pEntity->Spawn();

Last line is the call of virtual function Spawn

kiki33hun
08-10-2012, 02:07
I need signatures:

NET_SendPacket
SV_GetClientIDString
MSG_WriteLong
SV_ReadPackets
SV_CheckForDuplicateNames
SVC_GetChallenge
COM_BuildNumber__Fv
SV_ConnectionlessPacket
net_from
net_message
gEntityInterface

Please post this signatures! Big thanx!

ConnorMcLeod
08-10-2012, 02:17
Seems that it's time for you to learn to make sigs.

kiki33hun
08-10-2012, 02:46
Ahh, it is difficult for me :)

Arkshine
08-10-2012, 03:16
Add that in your signature. ^^

kiki33hun
09-23-2012, 05:47
Help me, i am using linux server and this signature hokking dont work!


{
"name" : "SV_CountPlayers",
"library" : "engine",
"arguments" :
[
{
"type" : "char *"
}
],
"return" :
{
"type" : "char *"
},
"identifiers":
[
{
"os" : "windows",
"value" : [NOT FOUND ONLY LINUX]
},
{
"os" : "linux",
"value" : "SV_CountPlayers"
}
]
}

Server log:

Parsing file "SV_CountPlayers" started
Argument type "char *" validated
Return type "char *" validated
Searching for name "SV_CountPlayers"... FOUND
Parsing file "SV_CountPlayers" ended

ConnorMcLeod
09-23-2012, 10:25
Here is the header :

void SV_CountPlayers(int *);

kiki33hun
09-23-2012, 12:45
I tried but it is not good: (

ConnorMcLeod
09-23-2012, 13:17
{
"name" : "SV_CountPlayers",
"library" : "engine",
"arguments" :
[
{
"type" : "pointer"
}
],
"identifiers":
[
{
"os" : "linux",
"value" : "SV_CountPlayers"
}
]
}

kiki33hun
09-23-2012, 13:27
I am tested, ant not working!

L 09/23/2012 - 19:25:12: [ORPHEU] Function "SV_CountPlayers" not found
L 09/23/2012 - 19:25:12: [AMXX] Run time error 10 (plugin "teszt.amxx") (native "OrpheuGetFunction") - debug not enabled!


Screeonlog:

Parsing file "SV_CountPlayers" started
Argument has invalid type "int *"
FAILED

Arkshine
09-23-2012, 14:00
use "pointer" instead.

kiki33hun
09-23-2012, 14:05
Yes i am use, look last post!

Arkshine
09-23-2012, 14:08
It should be : "type" : "pointer"

kiki33hun
09-23-2012, 14:12
Okey, i am tested!

I register orpheu hook SV_CountPlayers, in plugin precache!

And handler:

log_to_file("kiki.log", "ERTEKE: %d", OrpheuGetReturn());

Log:

L 09/23/2012 - 20:08:35: ERTEKE: -1278492088
L 09/23/2012 - 20:08:35: ERTEKE: -1278492088
L 09/23/2012 - 20:09:35: ERTEKE: -1278492088
L 09/23/2012 - 20:10:35: ERTEKE: -1278492088
L 09/23/2012 - 20:11:35: ERTEKE: -1278492088
L 09/23/2012 - 20:12:35: ERTEKE: -1278492088

And sig file:

{
"name" : "SV_CountPlayers",
"library" : "engine",
"arguments" :
[
{
"type" : "pointer"
}
],
"return" :
{
"type" : "pointer"
},
"identifiers":
[
{
"os" : "linux",
"value" : "SV_CountPlayers"
}
]
}

Arkshine
09-23-2012, 15:15
The header is : void SV_CountPlayers(int *);

So it doesn't return something, result is passed by reference.

Not sure if it will work, but you can try to hook as post, then using OrpheuMemoryGetAtAddress with the param in the header.

kiki33hun
09-24-2012, 07:54
Okay, i want some help.


I am probaly

public plugin_precache()
{
new teszt = OrpheuGetFunctionAddress(OrpheuGetFunction("SV_CountPlayers"))

new address
OrpheuMemoryGetAtAddress(teszt, "SV_CountPlayers", address);
log_to_file("kiki.log", "ERTEKE: %d", teszt);
}


and log:
L 09/24/2012 - 14:16:45: [ORPHEU] Invalid memory structure "SV_CountPlayers"
L 09/24/2012 - 14:16:45: [AMXX] Displaying debug trace (plugin "teszt.amxx")
L 09/24/2012 - 14:16:45: [AMXX] Run time error 10: native error (native "OrpheuMemoryGetAtAddress")
L 09/24/2012 - 14:16:45: [AMXX] [0] teszt.sma::plugin_precache (line 24)

Arkshine
09-24-2012, 08:57
You should create a new thread in scripting help because your problem has nothing to do with this tutorial.

teh ORiON
02-10-2013, 15:26
Hi,

I have a variable I want to change in memory (engine lib), im not sure how to make the signature for this. (dword_256D924). How should it look?


http://i.imgur.com/Kdi0YqU.png


Thanks.

Arkshine
02-10-2013, 16:27
You would need to retrieve its address from a function where it's used.

teh ORiON
02-10-2013, 17:06
You would need to retrieve its address from a function where it's used.

It is used in that function, "sub_1D5B210", as shown in the image. It's used in several other functions as well, however it's never passed as a parameter or return.

Arkshine
02-10-2013, 17:09
You can either make a signature of this function sub_1D5B210, retrieving its address, then adding some bytes as displacement to point to the address of this var, or making a signature direcly on the address of this var. You follow me ?

teh ORiON
02-10-2013, 17:15
You can either make a signature of this function sub_1D5B210, retrieving its address, then adding some bytes as displacement to point to the address of this var, or making a signature direcly on the address of this var. You follow me ?

Yes, sort of. So in this case,

"8B 0D 24 D9 56 02 mov, ecx, dword_256D924"

Would the byte sig then be 24 D9 56 02 and displaced -2 to point directly, or am I not understanding it correctly?

Arkshine
02-10-2013, 17:20
Better to start to 8B, then you would +2.

Your sig should start like : 8B ? ? ? ? ? etc..

teh ORiON
02-10-2013, 17:31
Better to start to 8B, then you would +2.

Your sig should start like : 8B ? ? ? ? ? etc..

Ok so now I have:


[
{
"name" : "mod_numknown",
"library" : "engine",
"type" : "long",
"memoryType" : "data",
"identifiers" :
[
{
"os" : "windows",
"mod" : "tfc",
"value" : [0x8B,"*","*","*","*","*",0x85,0xC9,0x7E,"*",0xB8,"*","*","*","*"],
"displacement" : 2
}
]
}
]


Im getting a value, but it doesn't seem like it's the correct value. This should be correct right?

Arkshine
02-10-2013, 17:37
Tell me what you want to retrieve exactly, I will have a better view of the issue, because dword_xxxx or sub_xxxx doesn't help much.

teh ORiON
02-10-2013, 17:50
Tell me what you want to retrieve exactly, I will have a better view of the issue, because dword_xxxx or sub_xxxx doesn't help much.

Ok so, I have this engine function:

void __cdecl sub_1D5B210()
{
int v0; // ecx@1
_UNKNOWN *v1; // eax@2

v0 = dword_256D924;
if ( dword_256D924 > 0 )
{
v1 = &unk_256D9C0;
do
{
if ( *(_DWORD *)v1 != 3 )
*(_DWORD *)v1 = 2;
v1 = (char *)v1 + 392;
--v0;
}
while ( v0 );
}
}


int __cdecl Mod_ClearAll()
{
int result; // eax@1
char *v1; // edx@1
int v2; // ecx@2

result = mod_numknown;
v1 = mod_known;
if ( mod_numknown > 0 )
{
v2 = mod_numknown;
result = -mod_numknown & 3;
if ( !result )
goto LABEL_25;
if ( result < 3 )
{
if ( result < 2 )
{
if ( *(_DWORD *)&mod_known[64] != 3 )
*(_DWORD *)&mod_known[64] = 2;
--v2;
v1 = &mod_known[392];
}
if ( *((_DWORD *)v1 + 16) != 3 )
*((_DWORD *)v1 + 16) = 2;
--v2;
v1 += 392;
}
if ( *((_DWORD *)v1 + 16) != 3 )
*((_DWORD *)v1 + 16) = 2;
v1 += 392;
--v2;
if ( v2 )
{
LABEL_25:
do
{
if ( *((_DWORD *)v1 + 16) != 3 )
*((_DWORD *)v1 + 16) = 2;
if ( *((_DWORD *)v1 + 114) != 3 )
*((_DWORD *)v1 + 114) = 2;
if ( *((_DWORD *)v1 + 212) != 3 )
*((_DWORD *)v1 + 212) = 2;
if ( *((_DWORD *)v1 + 310) != 3 )
*((_DWORD *)v1 + 310) = 2;
v2 -= 4;
v1 += 1568;
}
while ( v2 );
}
}
return result;
}
// 2CB048: using guessed type int mod_numknown;


Which is roughly similar to this q1 function:

int mod_numknown;

/*
===================
Mod_ClearAll
===================
*/
void Mod_ClearAll (void)
{
int i;
model_t *mod;

for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
if (mod->type != mod_alias)
mod->needload = true;
}


Instruction list from IDA for the function:

http://i.imgur.com/1C85EaM.png


What im trying to do is retrieve that variable "mod_numknown", which should be an int, and it should also denote the amount of models that's in the cache currently.

Arkshine
02-10-2013, 18:19
It works for me.

#include <amxmodx>
#include <orpheu_memory>

public plugin_init()
{
new mod_numknown = OrpheuMemoryGetAtAddress( OrpheuMemoryGet( "mod_numknown" ), "int" );

log_amx( "mod_numknown = %d", mod_numknown ); // [Untitled.amxx] mod_numknown = 217
}
{
"name" : "mod_numknown",
"library" : "engine",
"type" : "long",
"memoryType" : "data",
"identifiers" :
[
{
"os" : "windows",
"value" : [0x8B,"*","*","*","*","*",0x85,"*",0x7E,"*",0xB8],
"displacement" : 2
}
]
}
{
"name" : "int",
"type" : "int",
"memoryType" : "data",
"identifiers" :
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : 0
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : 0
}
]
}

teh ORiON
02-10-2013, 18:33
Ah nice! That works for me too. I was trying just,

new mod_numknown =OrpheuMemoryGet( "mod_numknown" ) That was the confusion. Thought that was the way to retrieve it in pawn. I guess that way only works if you have a direct address to a constant?

Thanks alot for the help!

Arkshine
02-10-2013, 19:09
Here another way, can be useful if you want to support linux and don't want to make signatures :

#include <amxmodx>
#include <orpheu>
#include <orpheu_memory>
#include <orpheu_advanced>

public plugin_init()
{
new mod_numknown_addr = OrpheuMemoryGetAtAddress( OrpheuGetFunctionAddress( OrpheuGetFunction( "Mod_ClearAll" ) ) + ( is_linux_server() ? 1 : 2 ), "int" );

new mod_numknown = OrpheuMemoryGetAtAddress( mod_numknown_addr, "int" );

log_amx( "mod_numknown = %d", mod_numknown );
}

{
"name" : "Mod_ClearAll",
"library" : "engine",
"identifiers" :
[
{
"os" : "windows",
"value" : [0x8B,"*","*","*","*","*",0x85,"*",0x7E,"*",0xB8]
},
{
"os" : "linux",
"value" : "Mod_ClearAll"
}
]
}

In this case, mod_numknown is retrieved at the start of function, so doing stuffs from the start of the function is enough safe.
what we can do is to retrieve Mod_ClearAll address, adding the displacement ( 1 for linux, 2 for windows ) to point to the address of mod_numknown, then reading the value. This way, we avoid signature for linux.

teh ORiON
02-10-2013, 19:35
Ah yes, I see. That's pretty clever. Will keep that in mind! Thanks!

darktemplar
02-15-2013, 02:07
@ Arkshine : Can you help me to change the base damage of CS Weapon ?

I've found this :

http://code.google.com/p/cs-sdk/source/browse/trunk/wpn_m4a1.cpp?spec=svn83&r=83

And I know the FireBullets and FireBullets3 is the function which calculates and does damage. Can you help me to hook and change the flDamage? :D

meTaLiCroSS
02-18-2013, 22:55
@ Arkshine : Can you help me to change the base damage of CS Weapon ?

I've found this :

http://code.google.com/p/cs-sdk/source/browse/trunk/wpn_m4a1.cpp?spec=svn83&r=83

And I know the FireBullets and FireBullets3 is the function which calculates and does damage. Can you help me to hook and change the flDamage? :D

Arkshine provided Rage's signatures on it's respective thread, search for it, is on the first page

hornet
06-11-2013, 01:30
I've found InstallHostageManager, and I'm under the impression that it is an object like g_pGameRules, and that it would allow me to do some fun stuff with hostages?

So from:

51 push ecx
A1 4C A2 12 10 mov eax, dword_1012A24C
56 push esi
33 F6 xor esi, esi
3B C6 cmp eax, esi
74 4E jz short loc_1004EE9B
53 push ebx
55 push ebp
89 44 24 0C mov [esp+10h+var_4], eax
57 push edi
8D A8 34 01 00 00 lea ebp, [eax+134h]
BB 15 00 00 00 mov ebx, 15h


I've come up with:

{
"name" : "InstallHostageManager",
"library" : "mod",
"return" :
{
"type" : "CHalfLifeMultiplay *"
},
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x51,0xA1,0x4C,"*","*","*",0x56,0x33,0xF6,0x3B,0xC6,0x74,"*",0x53,0x55,0x89,0x44,"*","*",0x57,0x8D,0xA8,"*","*","*","*",0xBB,0x15],
}
]
}




But it reports as not found. Can I please have some help?

Arkshine
06-11-2013, 03:34
InstallHostageManager() doesn't return. Inside it sets directly g_pHostages.

hornet
06-11-2013, 04:10
Okay. I probably should have looked further into this beforehand - It seems that g_pHostages is only used CHostageManager which I don't need.
So the rest of the functions from CHostage and CHostageImprov are virtual and don't need bytes signatures correct?

Arkshine
06-11-2013, 09:06
What do you mean by "the rest of the functions" ?

hornet
06-11-2013, 20:03
Sorry, bad terminology, I meant to say - All of the CHostage And CHostageImprov functions, are they virtual or do they require a signature of bytes?

TheDS1337
06-18-2013, 13:01
Arkshine, can you explain me "replace any memory references with '?'" i didn't understand any things on the picture ;(
and this:
51 push ecx // no memory reference.
└────── Opcode ────────┴───────┘ // 51
(fixed form)

56 push esi // no memory reference.
└────── Opcode ────────┴───────┘ // 51 56
(fixed form)

8B F1 mov esi, ecx // no memory reference.
└──┼───── Opcode ──────┘ │ │ // 51 56 8B F1
└───── ModR/M ──────────────┴────┘

8B 86 00 01 00 00 mov eax, [esi+100h] // 100h is an offset. It may change.
└──┼──┼── Opcode ──────┘ │ │ │ // 51 56 8B F1 8B 86 ? ? ? ?
└──┼── ModR/M ──────────────┴─────┘ │
└── Displacement ──────────────────┘
83 F8 01 cmp eax, 1 // no memory reference, but an hardcoded value. It may change by a plugin or something.
└──┼──┼── Opcode ──────┘ │ │ // 51 56 8B F1 8B 86 ? ? ? ? 83 F8 ?
└──┼── ModR/M ──────────────┘ │
└── Immediate ───────────────┘

89 44 24 04 mov [esp+8+var_4], eax // When you click right on it, you see 8+var_4 is equal to 4, a relative offset.
└──┼──┼──┼─ Opcode ────┘ │ │ │ │ // Anyway, it may change. I've notived also the SIB is generally different on cz.
└──┼──┼─ ModR/M ─────────────┼──┼───┼──────┘ // 51 56 8B F1 8B 86 ? ? ? ? 83 F8 ? 89 44 ? ?
└──┼─ SIB ────────────────┘ │ │
└─ Displacement ──────────┴───┘

Arkshine
06-18-2013, 13:27
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.

TheDS1337
06-18-2013, 13:41
ok thanks for your reply, i'll try latter ;)
EDIT:
Arkshine ? do you mean i can use:
[0x51,0x56,0x8B,0xF1,0x8B,0x86,0x00,0x01,0x00, 0x00,0x83,0xF8,0x01,0x89,0x44]
instead of:
[0x51,0x56,0x8B,0xF1,0x8B,0x86,"*","*","*","*",0x83,0xF8,"*",0x89,0x44]

Arkshine
06-19-2013, 19:30
I said ONLY first byte, and disregarding everything else, so :

51 56 8B ? 8B ? ? ? ? ? 83 ? ? 89

TheDS1337
06-20-2013, 03:50
Thanks

Spirit_12
08-29-2015, 18:53
Which library holds CHalfLifeMultiplay signatures? I have decompiled linux libraries, but can't find the signatures. I tried to find the working one, but still couldn't find them.

What .so file should I decompile to look for CHalfLifeMultiplay signature?

Arkshine
08-30-2015, 03:27
Well the mod, .so in $mod/dlls/.

Bugsy
01-17-2016, 12:56
As far as I understand, I need the linux version of the HLDS dll in order to make Windows signatures (in this case, SV_Rcon). Where can I get a copy of the linux HLDS dll to do this? I'm not very familiar with Linux stuff, can anyone chime in with which file I would reference in linux that is equivalent to swds.dll in Windows?

klippy
01-17-2016, 13:42
I'm not sure there is a way to legally acquire cstrike's server DLL without downloading it from Steam yourself. The Linux counterpart of swds.dll is engine_i486.so, and by the way, Linux counterpart of mp.dll is cs.so.
I could upload it for you, because I have both Linux and Windows on my PC and CS installed on both, but I know I am not allowed to upload binary files, so I'm asking for your permission first.

Bugsy
01-17-2016, 13:51
Ok, it helps to at least know the file name. I did find it on the net somewhere, I believe sourceforge. I'm not sure how out of date it is though. Let me see if a signature works then we will go from there. Thanks for the help.

HamletEagle
01-18-2016, 06:34
https://developer.valvesoftware.com/wiki/SteamCMD#Cross-Platform_Installation
You can download the linux version in windows.

Rirre
02-16-2016, 08:42
Someone able to restore the broken images?

Arkshine
02-16-2016, 09:32
I've restored the images but I should probably update the tutorial to simplify things.

Essentially, once you know how to display/retrieve bytes, it's just a matter to retrieve the first bytes of each line until you get a unique signature. And you should use by default "?" for "any byte" instead of "*" for "any byte and nothing". Most of case you don't want signature with "*".

Ghosted
04-30-2016, 09:28
Thanks For Tutor, I Founded Signatures For swds.dll (ReHLDS) for amx 1.8.3

DarthMan
04-28-2017, 05:19
I've restored the images but I should probably update the tutorial to simplify things.

Essentially, once you know how to display/retrieve bytes, it's just a matter to retrieve the first bytes of each line until you get a unique signature. And you should use by default "?" for "any byte" instead of "*" for "any byte and nothing". Most of case you don't want signature with "*".

Could you please help me here?

A1 E4 D2 0C 30 83 EC 58 D9 00 DC 05 30 DC 09 30

Thanks !

klippy
04-28-2017, 05:30
That signature alone can be hard to decipher. You should post the assembly (human readable) and hex too.

Bugsy
04-30-2017, 20:46
I created a tool in VB for creating signatures. All you would need to do is copy a block of text from IDA and paste it into the tool and it will generate the entire signature. Maybe I will wait until Arkshine revises the tutorial to make sure my tool has the correct logic.

http://i.imgur.com/UQD89lW.png
http://i.imgur.com/zOa93j7.png

Arkshine
05-01-2017, 04:05
Well, I don't have enough knowledge in assembly to affirm whether this opcode is static. As I said in the tutorial, it's easier to take just the first byte of each line until you have a unique signature. No need to bother with the others bytes. It might create longer signatures but doesn't matter much.

And by the way, "?" should be used by default. "?" = any bytes, "*" = any bytes or nothing. Most of time, you want "?".

PRoSToTeM@
05-01-2017, 10:34
I think the best way to analyze static opcodes for signatures is comparing function opcodes between old build (like 4554) and the newest (6153).

DarthMan
05-23-2017, 02:23
I created a tool in VB for creating signatures. All you would need to do is copy a block of text from IDA and paste it into the tool and it will generate the entire signature. Maybe I will wait until Arkshine revises the tutorial to make sure my tool has the correct logic.

http://i.imgur.com/UQD89lW.png
http://i.imgur.com/zOa93j7.png

Could u send us a link for download?

DarthMan
06-16-2017, 04:39
Well, I don't have enough knowledge in assembly to affirm whether this opcode is static. As I said in the tutorial, it's easier to take just the first byte of each line until you have a unique signature. No need to bother with the others bytes. It might create longer signatures but doesn't matter much.

And by the way, "?" should be used by default. "?" = any bytes, "*" = any bytes or nothing. Most of time, you want "?".

Hey Arkshine, could u better explain what keep always the first byte emans? Thanks !

I understood, in the IDA View-A I look for the 1st byte and keep it, and replace any other bytes with ?

Arkshine
06-17-2017, 04:21
It means you retrieve the first byte of the instruction (the mnemonic 'push', 'mov', etc., you see it in the above screenshot) and that's not something which will change at runtime.

DarthMan
10-24-2017, 04:56
It means you retrieve the first byte of the instruction (the mnemonic 'push', 'mov', etc., you see it in the above screenshot) and that's not something which will change at runtime.

I got it, sorry for the long time response.

ish12321
06-03-2018, 07:03
Hey,
I opened IDA Freeware. Clicked on new. Selected cs.so. Now a menu titled "Load a new file" appears with various options :
[1]
EFL for Intel 386 (Shared Object) [elf64.dll]
OR
Binary File

[2]
Processor Type with various options..
and many more...

Could anyone please help me out what to choose here?

metal_upa
01-24-2019, 08:41
I tried to make a signature for CBasePlayerWeapon::KickBack() on regamedll library but i don't find the function name 'CBasePlayerWeapon::KickBack()'. What now?

HamletEagle
01-24-2019, 09:43
Read the tutorial about finding functions?

metal_upa
01-24-2019, 13:43
Read the tutorial about finding functions?

There are no function named CBasePlayerWeapon::KickBack() in mp.dll from regamedll, most of them are sub_xxx and a few from CBasePlayer:: function. Tried with IDA freeware.

HamletEagle
01-25-2019, 04:26
There are no function named CBasePlayerWeapon::KickBack() in mp.dll from regamedll, most of them are sub_xxx and a few from CBasePlayer:: function. Tried with IDA freeware.

Maybe I was not clear enough: read the tutorial about finding functions.