 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Fri Jun 25, 2010 3:05 am Post subject: |
|
|
| 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 |
|
 |
ddk^nnl Guest
|
Posted: Wed Jun 30, 2010 7:09 pm Post subject: |
|
|
| 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
|
Posted: Wed Jun 30, 2010 7:29 pm Post subject: |
|
|
| 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 |
|
 |
ddk^notlgdin Guest
|
Posted: Wed Jun 30, 2010 7:49 pm Post subject: |
|
|
| 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
|
Posted: Mon Jul 19, 2010 6:45 am Post subject: |
|
|
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 |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Mon Jul 19, 2010 8:36 am Post subject: |
|
|
| 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 |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Mon Jul 19, 2010 5:12 pm Post subject: |
|
|
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 |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
Posted: Mon Jul 19, 2010 10:02 pm Post subject: |
|
|
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  |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Wed Jul 21, 2010 9:50 pm Post subject: |
|
|
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 |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Wed Jul 21, 2010 10:00 pm Post subject: |
|
|
| 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 |
|
 |
TheLexicon Guest
|
Posted: Thu Jul 22, 2010 1:23 am Post subject: Shellcode |
|
|
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
|
Posted: Thu Jul 22, 2010 2:04 am Post subject: |
|
|
| 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 |
|
 |
Guest
|
Posted: Thu Jul 22, 2010 11:45 am Post subject: |
|
|
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
|
Posted: Thu Jul 22, 2010 2:19 pm Post subject: |
|
|
| 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 |
|
 |
ddk
Joined: 28 Dec 2009 Posts: 43
|
Posted: Fri Jul 30, 2010 8:41 pm Post subject: |
|
|
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:
And I guess that's not right 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 |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|