 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Sat May 22, 2010 2:14 pm Post subject: |
|
|
| Thanks! This looks better for VS'08. |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 8688
|
Posted: Sun May 30, 2010 9:37 am Post subject: |
|
|
Dear Laszlo,
Can you please provide machine code for following function:
| Code: | Return( UInt ) {
Return UInt
} |
I intend to use it like:
| Code: | | Value := DllCall( BigEndian ? &BSwap32 : &Return, UInt,NumGet( Var ), "cdecl" ) |
Regards. |
|
| Back to top |
|
 |
YMP
Joined: 23 Dec 2006 Posts: 418 Location: Russia
|
Posted: Sun May 30, 2010 10:49 am Post subject: |
|
|
Oh, it's quite a simple function, perhaps mine will work as well.
| Code: |
MCode(Return, "8B442404C3")
Ret := DllCall(&Return, "UInt", 12345, "CDecl")
MsgBox, %Ret%
|
| Code: |
Return:
mov eax,[esp+4]
ret
|
|
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 8688
|
Posted: Sun May 30, 2010 11:14 am Post subject: |
|
|
Beautiful!.. Many thanks YMP
| Code: | NumPut( 0xC30424448B, Ret:="12345678", 0, "Int64" )
MsgBox, % DllCall( &Ret, UInt,1234, "CDecl" ) "`n" ErrorLevel "`n" A_LastError |
|
|
| Back to top |
|
 |
hughman
Joined: 11 Feb 2007 Posts: 166
|
Posted: Sun May 30, 2010 3:12 pm Post subject: |
|
|
| I want to know how to convert a function to machine code, who can tell me? |
|
| Back to top |
|
 |
YMP
Joined: 23 Dec 2006 Posts: 418 Location: Russia
|
Posted: Sun May 30, 2010 5:06 pm Post subject: |
|
|
If you mean an AHK function, I don't know of any way. You can write code in C/C++ or Assembler and compile it to produce an EXE or DLL. They will contain the machine code of your functions. As for its hex form, I personally copy it from a debugger window (OllyDbg). There I can also paste someone else's machine code and see what assembly instructions it contains. Very convenient.  |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Mon Jun 21, 2010 5:58 pm Post subject: |
|
|
| Laszlo wrote: | The C code for in-place reversal: | Code: | rev_bytes(char* d, int n) { // Reverse byte sequence
char t, *c = d+n;
while (c > d) { t = *--c; *c = *d; *d++ = t; }
} | From AHK call it with: | Code: | MCode(flip,"8b4c24048b44240803c13bc17610538a19488a1088188811413bc177f25bc3")
MCode(ByRef code, hex) { ; allocate memory and write Machine Code there
VarSetCapacity(code,StrLen(hex)//2)
Loop % StrLen(hex)//2
NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char")
}
In = Quick
dllcall(&flip,"UInt",&In, "UInt",5, "CDECL") ; Reverse byte sequence
MsgBox [%In%] |
|
Any chance this could be adapted to reverse Unicode (UTF-16) strings? Something like (just guessing here, there's probably a neater way):
| Code: | rev_bytes(char* d, int n) { // Reverse byte sequence (n = number of characters)
char t1, t2, *c = d+(n*2);
while (c > d) { t2 = *--c; t1 = *--c; *c = *d; *(c+1) = *(d+1); *d++ = t1; *d++ = t2; }
} |
|
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Mon Jun 21, 2010 6:05 pm Post subject: |
|
|
| In the original function you may try replacing "char" with "short". |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Mon Jun 21, 2010 6:19 pm Post subject: |
|
|
| Laszlo wrote: | | In the original function you may try replacing "char" with "short". |
Ah ok. That would be much better.
So the code would be:
| Code: | rev_utf16(short* d, int n) { // Reverse character sequence (n = number of characters)
short t, *c = d+(n*2);
while (c > d) { t = *--c; *c = *d; *d++ = t; }
} |
Is that correct?
Now, how do I go about converting this into MCode?
Edit: The disassembler in your main post doesn't seem to be up anymore.
Edit2: Seems like it's here now. I'll give this a go! Thansk for the help. |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Mon Jun 21, 2010 7:19 pm Post subject: |
|
|
Hmmm... my machine code is unusually long:
| Code: | "558bec0000381ecd80000005356570000c8dbd28ffffffb936000000b8cccc"
. "ccccf3ab8b450cd1e08b4d088d14418955ec8b45ec3b450876348b45ec83e8028945ec8b4dec"
. "668b11668955f88b45ec8b4d08668b116689108b4508668b4df86689088b550883c202895508"
. "ebc45f5e5b8be55dc3" |
Especially compared to your version. Am I supposed to keep only a certain part of the machine code in the .cod file? I updoaded the file here.
Just for reference, the C code compiled is:
| Code: | rev_utf16(short* d, int n) { // Reverse character sequence (n = number of characters)
short t, *c = d+(n*2);
while (c > d) { t = *--c; *c = *d; *d++ = t; }
} |
|
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Mon Jun 21, 2010 7:40 pm Post subject: |
|
|
I updated the first post of this thread, removing the reference of the disassembler, which is not necessary. Follow this link for information on converting C functions to machine code using Microsoft's free Visual C++ Express compilers.
Look at Jamie's mod of the script helping to extract machine code from the assembler listing.
Try setting full optimization with preferred size over speed to get shorter code. There are other settings, which could help, like not checking frame boundaries, etc. |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Mon Jun 21, 2010 9:42 pm Post subject: |
|
|
I was able to bring it down in size considerably. Thanks!
However, it doesn't seem to work at all!
C code:
| Code: | rev_utf16(short* d, int n) { // Reverse character sequence (n = number of characters)
short t, *c = d+(n*2);
while (c > d) { t = *--c; *c = *d; *d++ = t; }
} |
.cod file: http://pastebin.com/Lm9H3Gy2
Testing it:
| Code: | MCode(rev, "8b4c24048b4424088d04813bc1761656668b3148480fb71066893066891141413bc177ec5ec3")
VarSetCapacity(var, 4, 0), NumPut(0xFFFEFDFC, var)
OutputDebug, % MCode_Bin2Hex(&var, 4) ;Outputs FCFDFEFF
DllCall(&rev, "uint", &var, "uint", 2, "CDECL")
OutputDebug, % MCode_Bin2Hex(&var, 4) ;Outputs 00000000 but I expect FEFFFCFD |
I think it is something wrong with the C code, because just to test I compiled your original rev_bytes() function and I got the exact same machine code as you in the end, so the compiler is working fine.
Edit: OK, I guess I don't know C enough. But the following C code works (yes, n in the number of 16-bit characters, not the number of bytes):
| Code: | rev_utf16(short* d, int n) { // Reverse character sequence (n = number of characters)
short t, *c = d+n;
while (c > d) { t = *--c; *c = *d; *d++ = t; }
} |
| Code: | MCode(rev, "8b4c24048b4424088d04413bc1761656668b3148480fb71066893066891141413bc177ec5ec3")
VarSetCapacity(var, 4, 0), NumPut(0xFFFEFDFC, var)
OutputDebug, % MCode_Bin2Hex(&var, 4) ;Outputs FCFDFEFF
DllCall(&rev, "uint", &var, "uint", 2, "CDECL")
OutputDebug, % MCode_Bin2Hex(&var, 4) ;Outputs FEFFFCFD |
Thanks for all the help! |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Mon Jun 21, 2010 10:00 pm Post subject: |
|
|
| Quote: | | In UTF-16, a BOM (U+FEFF) is placed as the first character of a file or character stream to indicate the endianness (byte order) of all the 16-bit code units of the file or stream. | So you may want to start the string reversal at an offset 2. Also, keep in mind that | Quote: | | For characters in the Basic Multilingual Plane (BMP), U+0000 through U+FFFF, the resulting encoding is a single 16-bit word. For characters in the other planes the encoding is a pair of 16-bit words, together called a surrogate pair. | If your string contains such surrogate pairs (like Chinese characters), they need special handling. In this case you may want to use Windows' conversion functions to UTF-32, reverse the string there and convert back. |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Mon Jun 21, 2010 10:54 pm Post subject: |
|
|
But the BOM is optional, right? Would it be possible for a character to be assigned 0xFEFF?
Also, do you know if AHK_L has a BOM at the beginning of all its internal strings? |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Tue Jun 22, 2010 12:59 am Post subject: |
|
|
Here's a version of the Bin2Hex function found here which works under both the ANSI and Unicode (AHK_L) builds of AHK (for the Unicode C source, I simply changed hex's type to a short*):
| Code: | MCode_Bin2Hex(addr, len) {
Static fun
If (fun = "") {
If Not A_IsUnicode
h=8B54240C85D2568B7424087E3A53578B7C24148A07478AC8C0E90480F9090F97C3F6DB80E30702D980C330240F881E463C090F97C1F6D980E10702C880C130880E464A75CE5F5BC606005EC3
Else h=
( LTrim Join
8B54240C568B74240885D27E5053578B7C24148A0733DB8AC8C0F9044780F9090F9FC3660FBEC9240F66F7DB6683E3076603
D96683C33066891E33C946463C090F9FC1669866F7D96683E1076603C86683C13066890E46464A75B85F5B33C06689065EC3
)
VarSetCapacity(fun, n := StrLen(h)//2)
Loop % n
NumPut("0x" . SubStr(h, 2 * A_Index - 1, 2), fun, A_Index - 1, "Char")
}
VarSetCapacity(hex, A_IsUnicode ? 4 * len + 2 : 2 * len + 1)
DllCall(&fun, "uint", &hex, "uint", addr, "uint", len, "cdecl")
VarSetCapacity(hex, -1) ;update StrLen
Return hex
} |
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|