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.
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.
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 :
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 :
Code:
// 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]
Then, start your server and check your log, you should see something like :
Code:
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.
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 :
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
Re: Orpheu: How to make signatures of bytes
What Should I Do With That Plugin ?
How To Install ?
So, is IDA Pro needed ?
Arkshine
01-17-2011 05:38
Re: Orpheu: How to make signatures of bytes
It doesn't matter what version you use. You need IDA, that's all.
Seta00
01-17-2011 10:49
Re: Orpheu: How to make signatures (of bytes)
Excellent resource! (Lacks a few 'be's, but who cares? :D)
Arkshine
01-17-2011 10:52
Re: Orpheu: How to make signatures (of bytes)
Where. :twisted:
meTaLiCroSS
01-17-2011 11:35
Re: Orpheu: How to make signatures (of bytes)
:D... too pro for me :c.
Arkshine
01-17-2011 11:36
Re: Orpheu: How to make signatures (of bytes)
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
Re: Orpheu: How to make signatures (of bytes)
What about finding a memory address for a variable that you want to modify?
Arkshine
01-17-2011 14:32
Re: Orpheu: How to make signatures (of bytes)
You're right, I've missed that. I will add later, though the method is the same.
drekes
03-08-2011 21:00
Re: Orpheu: How to make signatures (of bytes)
After a while i got it working :D
I've used CBaseButton::ButtonUse with this signature: