AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Machine code functions: Bit Wizardry
Goto page Previous  1, 2, 3 ... 17, 18, 19 ... 22, 23, 24  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sat May 22, 2010 2:14 pm    Post subject: Reply with quote

Thanks! This looks better for VS'08.
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Sun May 30, 2010 9:37 am    Post subject: Reply with quote

Dear Laszlo, Smile

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
View user's profile Send private message Send e-mail
YMP



Joined: 23 Dec 2006
Posts: 418
Location: Russia

PostPosted: Sun May 30, 2010 10:49 am    Post subject: Reply with quote

Oh, it's quite a simple function, perhaps mine will work as well. Smile
Code:

MCode(Return, "8B442404C3")

Ret := DllCall(&Return, "UInt", 12345, "CDecl")

MsgBox, %Ret%

Code:

Return:
    mov eax,[esp+4]
    ret
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Sun May 30, 2010 11:14 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
hughman



Joined: 11 Feb 2007
Posts: 166

PostPosted: Sun May 30, 2010 3:12 pm    Post subject: Reply with quote

I want to know how to convert a function to machine code, who can tell me?
Back to top
View user's profile Send private message
YMP



Joined: 23 Dec 2006
Posts: 418
Location: Russia

PostPosted: Sun May 30, 2010 5:06 pm    Post subject: Reply with quote

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. Smile
Back to top
View user's profile Send private message
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Mon Jun 21, 2010 5:58 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Mon Jun 21, 2010 6:05 pm    Post subject: Reply with quote

In the original function you may try replacing "char" with "short".
Back to top
View user's profile Send private message
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Mon Jun 21, 2010 6:19 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Mon Jun 21, 2010 7:19 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Mon Jun 21, 2010 7:40 pm    Post subject: Reply with quote

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
View user's profile Send private message
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Mon Jun 21, 2010 9:42 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Mon Jun 21, 2010 10:00 pm    Post subject: Reply with quote

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
View user's profile Send private message
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Mon Jun 21, 2010 10:54 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Tue Jun 22, 2010 12:59 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... 17, 18, 19 ... 22, 23, 24  Next
Page 18 of 24

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group