quote:
Originally posted by TheGuruSupremacy
Before posting i always trying to resolve my problems myself and if i can't to do it i'll post for help so i'll be patient but please don't tell me that i ask for help without knowing what i actually do....it's offensive....bye
I didn't say you didn't know what you were doing and that you just copy/paste stuff.
I said it involves some knoweldge of what unicode and ascii strings are and I said IF you simply copy/paste code you don't learn anything from it... What I said is actually nothing more than plain logic: if you want to know something, read up on some stuff about it. How is suggesting to read up on some background info about this while you wait on the detailed explaination, being any offensive??
On the other hand, it would be majorly offensive towards the people who try to help you with something if you just did copy/paste stuff though. Because like with this post, I simply could have posted the code and be done with it in 5 minutes, thus I took a lot of time to make this post and trying to explain the stuff behind it...
----------------------------------------------------------------------
quote:
Originally posted by TheGuruSupremacy
[SNIPPED]
I hope that you understand me....
I understand, and I already suspected you wanted to do that, but it involves a very good knowledge of ascii, unicode, and how everything is stored in memory.
Thus:
quote:
Originally posted by TheGuruSupremacy
for example if i pass to SetPatchData funtion this string "Example" i need to return
"\x45\x00\x78\x00\x61\x00\x6D\x00\x70\x00\x6C\x00\x65\x00"
This is correct as you state it, but do you exactly know what you just stated? Don't get me wrong though, I simply ask this because there can be a lot of confusion if one isn't used to deal with unicode vs. ascii vs. bytes. And as I said earlier it is absolutely vital that you post it in the correct form. eg: "\x45" is not the same as 0x45... "\x45" is 0x45 0x00
"Example" is the same as "\x45\x78\x61\x6D\x70\x6C\x65".
So if you meant to show the byte representation of this string with "\x45\x00\x78\x00..." then you got the bytes correct but you posted a totally wrong thing.
Because "\x45\x00\x78\x00
etc" actually consists of the bytes 0x45 0x00 0x00 0x00 0x78 0x00 0x00 0x00.
So you should have said: "
I need to return 0x45 0x00 0x78 0x00.". But in that case you got the wrong idea in what needs to be passed to the
Patch() function and thus it wouldn't be correct......
Again, I say this because if you thought you needed to pass 0x45 0x00 0x78 0x00 (but used the wrong form in your post), and I said you where correct, then I might teach you the wrong thing.
-----------
Anyways,
You first need to take the unicode value of each character. This is a number between 0x0000 and 0xFFFF. It is after the high order and after the low order of that number that you need to add the "\x00", because that is what is being ignored by the
Patch function since it expects a
byte string, aka: a string consisting of only ascii characters from 0x00 to 0xFF.
To make it clear with an example:
The normal JScript string (thus which is always unicode) "This" has the bytes: 0x54 0x00 0x68 0x00 0x69 0x00 0x73 0x00
But this string, and let's say # is a unicode character: "#This" has the bytes: 0x11 0xEF 0x54 0x00 0x68 0x00 0x69 0x00 0x73 0x00
Notice that the character # does not have a null byte! It takes two bytes to represent a character in a unicode string, and that is also what you need to patch, 2 bytes per character.
Thus what you need to pass to the
Patch function is not:
0x11 0xEF 0x54 0x00 0x68 0x00 0x69 0x00 0x73 0x00
but
0x11
0x00 0xEF
0x00 0x54
0x00 0x00
0x00 0x68
0x00 0x00
0x00 0x69
0x00 0x00
0x00 0x73
0x00 0x00
0x00
where 0x00 are the added null bytes which will be ignored.
This is indeed what your original function intends to do:
code:
function SetDataPatch(string){
var newstring=0
for (var i=0;i<string.length;i++){
newstring += "\x" + Hex(string.charCodeAt( i)) + "\x00"}
Debug.Trace(newstring)
return newstring}
However there are some problems with it which I also already told you in my first reply in this thread though....
You can not simply add a string like "EF" to the string "\x" and expect it to be the string "\xEF".
For starters, the
Hex() function can return a string of any length (in this case 1 to 4 digits) since characters can be anything from code 0x0 to 0xFFFF...
But even if it did always return 2 digits, then "\x" would still be invalid, since \x is not an actual
string consisting of the characters '\' and 'x' but an
escape command, and the whole escape command must be \x?? where ?? must be a 2 digit hexadecimal number.
What
SetDataPatch() must do is putting a null byte (0x00) after each byte of the string and that can only be done by manipulating the original string on byte level.
To do this forget about using the
Hex() function, you don't need that. There are more ways than using the escape command \x?? to add characters to a string. What you need is the function
fromCharCode().
First do what the previous posted
SetDataPatch() does: get each character of the string one by one and split the unicode code up into the lower order and higher order byte. Then append these bytes (0 to 255) as being new characters to a string.
code:
function SetDataPatch(sUnicodeString) {
var newstring = "";
for (var i = 0; i < sUnicodeString.length; i++) {
// Get character
var charCode = sUnicodeString.charCodeAt(i);
// Get the low order byte (with an AND operation)
// And write it as a new character
newstring += String.fromCharCode(charCode & 0xFF);
// Get the high order byte (with a right bit shift operation)
// And write it as a new character
newstring += String.fromCharCode(charCode >>> 8);
}
return newstring;
}
Note that
fromCharCode() will write a unicode character! Thus if you say
fromCharCode(210) it will write actually two bytes: 0xD2 and 0x00. And since we make sure the character code passed to this function is always between 0 and 255, the second byte written will always be 0x00.
However, note that all this is a very slow process.
To overcome this, I've used ASM in one of my script patches though... anyways...
But the most simple solution is to forget the whole
SetDataPatch() function and alter the
Patch() function. If you have good knowledge of what you actually are doing with all this you would have come to that conclussion already though (just to say again that copy/pasting something isn't good if you don't understand what is being involved).
However, this solution has drawbacks because you would only be able to write unicode strings and not byte arrays (without even more dodgy unicode to ascii manipulations).
What does
Patch() do? The important stuff in that function is the use of the
WriteProcessMemory API which does nothing more than writing a passed byte array to memory. A unicode string is just a array of bytes, and this is how simple it gets... So if you want to write an unicode string to memory, then all you need to do is pass the unicode string directly to the
WriteProcessMemory API.
The reason why the original
Patch() function has some string manipulations in it is exactly because strings in JScript are always unicode. And it is very rare to patch only unicode strings so it needs this string manipulation so you can pass byte arrays in a convenient fast way. But if you do want to patch only unicode strings and nothing else, then you don't need those string manipulations at all. This is also explained (without so much words) in the original comments of that function btw...