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 ... 18, 19, 20 ... 22, 23, 24  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Fri Jun 25, 2010 3:05 am    Post subject: Reply with quote

I made a script to automate as much as possible the process of converting C/C++ code into machine code. See here.
Back to top
View user's profile Send private message Visit poster's website
ddk^nnl
Guest





PostPosted: Wed Jun 30, 2010 7:09 pm    Post subject: Reply with quote

Is it possible to make extreme fast hex2txt and txt2hex functions with mcode?
Back to top
Laszlo



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

PostPosted: Wed Jun 30, 2010 7:29 pm    Post subject: Reply with quote

Try the Bin2Hex and Hex2Bin functions posted on page 1 and page 8 of this thread. The search function of the Forum is not very good for finding something in long threads...
Back to top
View user's profile Send private message
ddk^notlgdin
Guest





PostPosted: Wed Jun 30, 2010 7:49 pm    Post subject: Reply with quote

Laszlo wrote:
Try the Bin2Hex and Hex2Bin functions posted on page 1 and page 8 of this thread. The search function of the Forum is not very good for finding something in long threads...

Oh yeah, I see.
If you weren't sarcastic I agree with you, AHK forums should upgraded to version where you can use search in threads.
Back to top
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Mon Jul 19, 2010 6:45 am    Post subject: Reply with quote

I've discovered something cool!
It is possible to "call" APIs (or really any function) from machine code:

Here is a quick example:

Code:
_MessageBoxA := DllCall("GetProcAddress", "uint", DllCall("GetModuleHandle", "str", "user32"), "str", "MessageBoxA") ;Get the address of MessageBoxA
MCode(MessageBoxA, "8B4424148B4C24108B54240C508B44240C515250FF542414C3") ;Using MCodeGen with VS2010 installed (http://www.autohotkey.com/forum/viewtopic.php?t=59593)
DllCall(&MessageBoxA, "uint", _MessageBoxA, "uint", 0, "str", "This is my text.", "str", "This is my caption.", "uint", 0, "cdecl")


The trick is to call the function by address inside the machine code. This is the C code compiled:

Code:
#include <windows.h>

int CallMessageBox(int (__stdcall *MessageBoxFunc)(HWND, LPCTSTR, LPCTSTR, UINT), HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
   return MessageBoxFunc(hWnd, lpText, lpCaption, uType);
}


MessageBox is just an example, but you could use this technique for any function. Obviously, you'll have to compile the appropriate C code for functions with different signatures.

After running a few benchmarks, it seems to be faster than calling the target function directly with DllCall. Although I couldn't find a good CPU intensive function to test with (suggestions?). Regardless, we still have to use DllCall in the end, incurring whatever overhead comes with it.
Back to top
View user's profile Send private message Visit poster's website
Lexikos



Joined: 17 Oct 2006
Posts: 7299
Location: Australia

PostPosted: Mon Jul 19, 2010 8:36 am    Post subject: Reply with quote

TheGood wrote:
It is possible to "call" APIs (or really any function) from machine code:
I used a similar technique to implement FileExtract, which runs a compiled C++ function in a separate thread. The function depends on ConnectNamedPipe, ReadFile and GlobalReAlloc, which are passed to it via a structure/parameter.
Quote:
The trick is to call the function by address inside the machine code.
Another trick is to put the address directly into the machine code, as I did with DebugBIF. The function address has to be called indirectly, unless you want to calculate the offset of the function to the 'call' instruction... One way way to do it is something like:
Code:
((void (* )())0x12345678)(); // untested!
...then replacing 78563412 in the output. (If you're viewing it as a stream of hexadecimal characters, the least significant bytes come first. DebugBIF uses __mcodeptr to format the pointer this way.) Equivalent assembly is something like:
Code:
mov ecx, 0x66666666
call ecx
Quote:
After running a few benchmarks, it seems to be faster than calling the target function directly with DllCall.
I presume you were comparing to DllCall("LiteralFunctionName"), which is not direct. It has to call GetProcAddress every time to retrieve the function address, and for quick functions this means a considerable amount of overhead. Well, unless you're using AutoHotkey_L or a derivative, in which case such function names are automatically resolved at load-time if they are present in memory.
Edit: In your example, calling _MessageBoxA instead should be faster.
Back to top
View user's profile Send private message Visit poster's website
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Mon Jul 19, 2010 5:12 pm    Post subject: Reply with quote

Yeah, you're right. I did a bit more testing today (this time with MulDiv), and it seems like _MulDiv is the fastest in mainstream AHK, while "MulDiv" is fastest in AHK_L by a slight margin.

Code:
_MulDiv := DllCall("GetProcAddress", "uint", DllCall("GetModuleHandle", "str", "kernel32"), A_IsUnicode ? "astr" : "str", "MulDiv")
MCode(MulDiv, "FF742410FF742410FF742410FF542410C3")

AHK:
                           1        2        3  average
DllCall("MulDiv") = 5551.670 7609.345 7494.034 6885.016 ms
DllCall(_MulDiv)  = 1992.712 1683.229 1991.623 1889.188 ms
DllCall(&MulDiv)  = 5125.352 5154.847 5146.098 5142.099 ms

AHK_L
                           1        2        3  average
DllCall("MulDiv") = 1532.916 1595.839 1506.173 1544.976 ms
DllCall(_MulDiv)  = 1559.126 1659.080 1563.747 1593.984 ms
DllCall(&MulDiv)  = 2899.750 3738.775 3769.903 3469.476 ms
Back to top
View user's profile Send private message Visit poster's website
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Mon Jul 19, 2010 10:02 pm    Post subject: Reply with quote

If you are after DllCall speedup, you might be interested in DynaCall (AHK_H).
Code:
#NoEnv
SetBatchLines,-1
Loop:=1000000

Loop % (start:=A_TickCount) ? loop : 0
   DllCall("MulDiv", int, 3, int, 4, int, 3)
_a := A_TickCount-start                              ;~ 1000 mSec

;set up DynaToken object
MulDiv:=DynaCall("MulDiv","iii")
Loop % (start:=A_TickCount) ? loop : 0
   MulDiv.(3,4,3)
_b := A_TickCount-start                              ;~ 500 mSec

Loop % (start:=A_TickCount) ? loop : 0
   MulDiv.() ;parameters already set
_c:=A_TickCount-start                              ;~ 400 mSec

MsgBox % "a: " _a "`nb: " _b "`nc: " _c

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun Wink
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1786

PostPosted: Wed Jul 21, 2010 9:50 pm    Post subject: Reply with quote

Sorry, just doing some speed tests and I know not related to ahk, but why does:

Code:
void test(int w, int h, unsigned char * scan0, int stride)
{
   for(int y = 0; y < h; ++y)
   {
      for(int x = 0; x < w; ++x)
      {
         //scan0[3] = 255;
         scan0[2] = 0;
         scan0[1] = 255;
         scan0[0] = 0;
         scan0 += 4;
      }
      scan0 += stride - (w*4);
   }
   return;
}


not work? but if i uncomment the highlighted line then it does work. surely that byte (alpha channel) should be left as is when its commented

edit:
sorry for the stupid post Laszlo.....was just a typo. Ill post the code when Ive finished it. Thanks for all the hard work though


Last edited by tic on Wed Jul 21, 2010 10:48 pm; edited 1 time in total
Back to top
View user's profile Send private message
Laszlo



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

PostPosted: Wed Jul 21, 2010 10:00 pm    Post subject: Reply with quote

What does not work? What values do you see in the original scan0 memory location? What are the values of the other parameters?
Back to top
View user's profile Send private message
TheLexicon
Guest





PostPosted: Thu Jul 22, 2010 1:23 am    Post subject: Shellcode Reply with quote

Take a look at the array given below:

char addfunc[] = "\x55\x89\xe5\x8b\x55\x0c\x8b\x45\x08\x01\xd0\x5d\xc3\x90";

The above array contains x86 instructions corresponding to

int Add( int a , int b ) {
return a+b;
}

We can include the above declaration in our C/C++ Programs ( 32 bit windows or 32 bit Linux ) and execute those instructions (from addfunc).Need to figure it out how this can be achieved in

a) MS Windows ( 32 bit )
b) GNU Linux ( x86 32 bit )

The Challenge is to generate x86 32 bit instructions for the function given below:

long swap(long *a , long *b ) {
long temp = *a;
long *a = *b;
*b = temp;
}
char swapfunc[] = { <your instruction list goes here> }

Write a ANSI C/C++ program which can run on
b ) under Linux 32 bit
a ) under Windows 32 bit

Provide a single source code base , which can be compiled on both platforms using make files.

Please Help Great guys !
Back to top
Laszlo



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

PostPosted: Thu Jul 22, 2010 2:04 am    Post subject: Reply with quote

Is the problem that pointers are different in Windows and Linux, or long means different things, or (most likely) parameters are passed to a function differently (registers/stack), or the stack is cleaned up by the caller in one platform and by the function in the other, or different registers/pages need to be preserved? If any of these is true, a universal binary would need assembler programing.
Back to top
View user's profile Send private message
Guest






PostPosted: Thu Jul 22, 2010 11:45 am    Post subject: Reply with quote

if I create a function that returns an int pointer:

Code:
int * fn()
{
   int x = 7;
   return &x;
}


then how can I get the value 7 using NumGet?

Code:
MCode(fn, "518D042459C3")
E := DllCall(&fn)
K := NumGet(E, 0, "uint")      ;%
P := NumGet(K, 0, "int")
MsgBox, % E "`n" K "`n" P      ;%
return

;#######################################################################

MCode(ByRef code, hex)
{
   VarSetCapacity(code, StrLen(hex)//2)
   Loop % StrLen(hex)//2      ;%
      NumPut("0x" . SubStr(hex, 2*A_Index-1, 2), code, A_Index-1, "char")
}
Back to top
Laszlo



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

PostPosted: Thu Jul 22, 2010 2:19 pm    Post subject: Reply with quote

In the C function you declare a local variable x. When the fn function returns, this variable does not exist any more, its memory is freed. You probably want to pass an address of an AHK variable to the function, where you store 7.
Back to top
View user's profile Send private message
ddk



Joined: 28 Dec 2009
Posts: 43

PostPosted: Fri Jul 30, 2010 8:41 pm    Post subject: Reply with quote

I changed my OS to my nlited XP and since then I've had problems with bin2hex function:
Code:
MCode(Bin2Hex,"8B4C2404578B7C241085FF7E2F568B7424108A06C0E8042C0A8AD0C0EA052AC2044188018A06240F2C0A8AD0C0EA052AC2410441468801414F75D75EC601005FC3")

bin := "abc", VarSetCapacity(hex,9)
dllcall(&Bin2Hex, "uint",&hex, "uint",&bin, "uint",4, "cdecl")
VarSetCapacity(hex,-1) ; update StrLen
MsgBox %hex%           ; 31323300

That example returns me 4 boxes:
Code:
ㄶ〰㈶〰

And I guess that's not right Rolling Eyes I've also tried standalone version of bin2hex and not working, also tried the BinToHex.dll. My AHK version is 1.0.48.05.L52H20.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... 18, 19, 20 ... 22, 23, 24  Next
Page 19 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