AutoHotkey Community

It is currently May 27th, 2012, 3:42 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 356 posts ]  Go to page Previous  1 ... 16, 17, 18, 19, 20, 21, 22 ... 24  Next
Author Message
 Post subject:
PostPosted: June 25th, 2010, 4:05 am 
Offline

Joined: July 30th, 2007, 11:32 pm
Posts: 581
I made a script to automate as much as possible the process of converting C/C++ code into machine code. See here.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 30th, 2010, 8:09 pm 
Is it possible to make extreme fast hex2txt and txt2hex functions with mcode?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: June 30th, 2010, 8:29 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 30th, 2010, 8:49 pm 
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.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 19th, 2010, 7:45 am 
Offline

Joined: July 30th, 2007, 11:32 pm
Posts: 581
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 19th, 2010, 9:36 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 19th, 2010, 6:12 pm 
Offline

Joined: July 30th, 2007, 11:32 pm
Posts: 581
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 19th, 2010, 11:02 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
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:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 21st, 2010, 10:50 pm 
Offline

Joined: April 22nd, 2007, 6:33 pm
Posts: 1833
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 July 21st, 2010, 11:48 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 21st, 2010, 11:00 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
What does not work? What values do you see in the original scan0 memory location? What are the values of the other parameters?


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Shellcode
PostPosted: July 22nd, 2010, 2:23 am 
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 !


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 22nd, 2010, 3:04 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 22nd, 2010, 12:45 pm 
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")
}


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 22nd, 2010, 3:19 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 30th, 2010, 9:41 pm 
Offline

Joined: December 29th, 2009, 12:48 am
Posts: 43
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 :roll: 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.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 356 posts ]  Go to page Previous  1 ... 16, 17, 18, 19, 20, 21, 22 ... 24  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: xXDarknessXx, Yahoo [Bot] and 17 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group