AndyG Posted October 18, 2010 Posted October 18, 2010 (edited) a little function called _AssembleIt() makes Wards "embedded" FASM-Assembler more embedded. The function is a "wrapper" for all the FASMxxx() and FASMyyy()-stuff. EDIT 03-20-2011: AssembleIt now includes a possibility to show the content of registers, flags,XMM-registers, FPU-registers and the stack during the runtime of the asm-code. Someone called this a "Debugger", it´s really not a debugger, it´s a chaotic piece of a script. */Sry, but i am not be able to put pictures or links in this post/*There are some nice features (i.e. running the asm-code until a register contains a specific content), so it could help sometimes...You can find AssembleIt and an example how to use it here or in the attached zipfile. Have fun!After including the AssembleIt.au3 the Assemblercode can be written like:;Example for _AssembleIt() ;32 Bit only! #include <AssembleIt.au3> Func _Add_int() ;any functionname, used by _AssembleIt() _("use32") ;32 Bit _("mov eax,dword[esp+4]") ;read 1st parameter in Register EAX=22 _("add eax,dword[esp+8]") ;add 2nd parameter EAX=EAX+33 _("ret") ;Returns result in EAX back to the calling function ;NO STACK CLEANING NECESSARY! EndFunc ;==>_Add_int ;_AssembleIt($Returntype, $Name_of_Func_with_code, $Type1 = "type", $Param1 = 0, $Type2 = "type", $Param2 = 0....up to 20 params) $ret = _AssembleIt("int", "_Add_int", "int", 22, "int", 33) ;thats all^^ MsgBox(0, 'Result _Add_int()', $ret) ;no array returned by _AssembleIt()Syntax check is integrated, and some more. See the examples!If your Assemblercode is running well and you don´t want to drag all the _ASMcode()-functions, AssembleIt.au3, FASM.au3 and MemoryDll.au3 with your script, it is now easy to make a "standalone" Version using a CallWindowProcW-call (which is much faster btw.)If you have a Script:expandcollapse popup#include <AssembleIt.au3> #include <GDIPlus.au3> ;32Bit only! Func _grayscale() _("use32") ;32Bit! _("mov esi,dword[esp+4]") ;Startadress Bitmapdata (Pixel) _("mov ecx,dword[esp+8]") ;number of Pixel _("mov edi,21845") ;konstant, *21845/2^16 is approximately 1/3 (replaces the slow DIV 3) _("_loop1:") ;until ecx=0 _("mov edx,[esi]") ;load pixel AARRGGBB (RR+GG+BB)/3 = colour grayscale _("mov al,dl") ;lowbyte (BB) Pixel to lowbyte al _("movzx bx,dh") ;highbyte (GG) Pixel to lowbyte of bx (bh is 0) _("shr edx,8") ;shift RR into dh _("add ax,bx") ;BB + GG _("movzx bx,dh") ;highbyte (RR) Pixel to lowbyte of bx (bh ist 0) _("add ax,bx") ;and add: dx=RR+GG+BB _("mul edi") ;ax=ax*21845 *21845/2^16 is about 1/3 _("shr eax,16") ;ax=ax/2^16 in al is now the greyscale colour for RR, GG und BB _("movzx dx,al") ;grayscale to dl, dh = 0 _("shl edx,16") ;grayscale to RR, AA = 0! _("mov dh,al") ;grayscale to GG _("mov dl,al") ;grayscale to BB edx is now 00alalal = grayscale AARRGGBB _("mov [esi],edx") ;write pixel _("add esi,4") ;address next pixel: 4 Byte = 1 dword = 1 Pixel _("sub ecx,1") ;counter (next pixel) _("ja _loop1") ;until ecx=0 ;upper 3 lines are faster than _("loop _loop1") ;until ecx=0 _("ret ") ;return EndFunc ;==>_grayscale $file = FileOpenDialog("Select 24 or 32 Bpp image!", @ScriptDir, "Image (*.jpg;*.bmp)", 1 + 2) if @error then exit _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromFile($file) $iWidth = _GDIPlus_ImageGetWidth($hBitmap) $iHeight = _GDIPlus_ImageGetHeight($hBitmap) $hBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB) $Scan = DllStructGetData($hBitmapData, "Scan0") $Stride = DllStructGetData($hBitmapData, "Stride") $tPixelData = DllStructCreate("dword[" & (Abs($Stride * $iHeight)) & "]", $Scan) ;$_ASSEMBLEIT_FLAG = 0 ;after uncomment this line, run the script, and replace the following line with the content of the clipboard, then delete #include <AssembleIt.au3> and the _grayscale()-function $ret=_AssembleIt("ptr","_grayscale","ptr", DllStructGetPtr($tPixelData), "int", $iWidth * $iHeight) ;ptr als Rückgabe, um die hexzahlen schön zu sehen _GDIPlus_BitmapUnlockBits($hBitmap, $hBitmapData) _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\greyscale.jpg") _GDIPlus_Shutdown() ShellExecute(@ScriptDir & "\greyscale.jpg")uncomment the line "$_ASSEMBLEIT_FLAG = 0" and run the script again._AssembleIt() creates now 3 lines AutoItcode and writes them into the Clipboard.Replace the line "$_ASSEMBLEIT_FLAG = 0" with the content of the clipboard (ctrl+v) and replace the param-variables (types were transfered) with the right ones from the "$ret=_AssembleIt("ptr"....blahblah)". Delete the "#include <AssembleIt.au3>" and the the function _grayscale() to get the following script#include <GDIPlus.au3> ;32Bit only! $file = FileOpenDialog("Select 24 or 32 Bpp image!", @ScriptDir, "Image (*.jpg;*.bmp)", 1 + 2) if @error then exit _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromFile($file) $iWidth = _GDIPlus_ImageGetWidth($hBitmap) $iHeight = _GDIPlus_ImageGetHeight($hBitmap) $hBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB) $Scan = DllStructGetData($hBitmapData, "Scan0") $Stride = DllStructGetData($hBitmapData, "Stride") $tPixelData = DllStructCreate("dword[" & (Abs($Stride * $iHeight)) & "]", $Scan) Global $tCodeBuffer = DllStructCreate("byte[61]") ;reserve Memory for opcodes DllStructSetData($tCodeBuffer, 1,"0x8B7424048B4C2408BF555500008B1688D0660FB6DEC1EA086601D8660FB6DE6601D8F7E7C1E810660FB6D0C1E21088C688C2891683C60483E90177D1C3") ;write opcodes into memory $ret=DllCall("user32.dll", "ptr", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"int",DllStructGetPtr($tPixelData), "int", $iWidth * $iHeight,"int",0,"int",0) _GDIPlus_BitmapUnlockBits($hBitmap, $hBitmapData) _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\greyscale.jpg") _GDIPlus_Shutdown() ShellExecute(@ScriptDir & "\greyscale.jpg")I have written a "tutorial" (unfortunately for you in german language) how to put and get AutoIt-variables into the ASM-code. There are also some examples how to use ASM-variables (VAR db 8 dup(7) ) in the ASM-code without a "org "&FasmGetBasePtr($Fasm), SSE-examples, speedup ASM with LUT and more....please feel free to ask me if you have questions. I am not an Assembler-"crack", but i like to speed up some functions with a little ASM...After i had written this tutorial, i wrote _AssembleIt() . And now i am too lazy to rewrite all FASMxxx()-stuff-examples into _AssembleIt()-style . Apologize....I see _AssembleIt() as a proof of concept, so i expect your comments/tips/hints/improvements!AssembleIt.zip Edited March 21, 2011 by AndyG JoeBar 1
trancexx Posted October 18, 2010 Posted October 18, 2010 It's impossible for me to resist to something like this. Very nice. ♡♡♡ . eMyvnE
UEZ Posted October 19, 2010 Posted October 19, 2010 Well done AndyG! 5* from me for your ASM hammer Bis denne, UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
UEZ Posted October 19, 2010 Posted October 19, 2010 It's impossible for me to resist to something like this.Somehow I already thought this... Br,UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Ascend4nt Posted October 19, 2010 Posted October 19, 2010 (edited) AndyG, Global $tCodeBuffer = DllStructCreate("byte[61]") ;reserve Memory for opcodes DllStructSetData($tCodeBuffer, 1,"0xC3") ;write opcodes into memory (cut short) Be wary of allocating memory from the Heap, and then executing code there. Thats a big no-no. DEP (Data Execution Prevention) can prevent the code from running, or cause it to crash. Use VirtualAlloc, or GlobalAlloc with VirtualProtect to set up code execution areas. *edit: copy and paste goof Edited October 19, 2010 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
AndyG Posted October 19, 2010 Author Posted October 19, 2010 @Ascendant, DEP (Data Execution Prevention) can prevent...that´s surely true. I never had activated/permitted DEP in any way, and perhaps that is the reason why i do not have any problems with(out) it But yes, to avoid possible errors, Global/Local-alloc is far away from no-no. Although MSDN mentionedMemory objects allocated by GlobalAlloc and LocalAlloc are in private, committed pages with read/write access that cannot be accessed by other processesandAlthough the GlobalAlloc, LocalAlloc, and HeapAlloc functions ultimately allocate memory from the same heap, each provides a slightly different set of functionality., i´ll trust you.$pointer_tCodeBuffer=dllcall("kernel32.dll","ptr","GlobalAlloc","uint",0x40, "ulong_ptr", 61) ;0x40=GPTR Global $tCodeBuffer = DllStructCreate("byte[61]",$pointer_tCodeBuffer[0]) ;reserve Memory for opcodes Somehow I already thought this... doing archaic things is also one of my preferences.
Ascend4nt Posted October 19, 2010 Posted October 19, 2010 Well, I guess you learn something new everyday. I was under the impression that GlobalAlloc used a different allocation resource than HeapAlloc does, since it is a type of 'sharing' memory resource. But nope - by using the API calls GetProcessHeap+HeapAlloc and comparing the results to GlobalAlloc, I see they both use the same heap (verified with VirtualQuery). Of course, DllStructCreate gives a completely different memory address - but that's due to those functions using a different heap (each process generally has a few heaps to draw resources from).I've always used VirtualAlloc myself, and it was only when I saw trancexx's GIF code that I began to consider using GlobalAlloc. However I'm not so sure that's a good idea now. This one quote from MSDN still makes me doubt this is a good idea at all:It is best to avoid using VirtualProtect to change page protections on memory blocks allocated by GlobalAlloc, HeapAlloc, or LocalAlloc, because multiple memory blocks can exist on a single page. The heap manager assumes that all pages in the heap grant at least read and write access.While the protection type of PAGE_EXECUTE_READWRITE doesn't remove the regular access types, it can potentially cause a slight security risk if other memory blocks in the same page exist. Not a huge deal though..I think now however that the best method (a least for me personally) would be to use either VirtualAlloc or create a new Heap (HeapCreate), which would be created specifically for executing machine code.Hmm, well I apologize for the length of this post. I suppose your method would work with VirtualProtect, but you'll lose the allocation you make if you create it locally and don't return the DLLStruct (pointers to it will be invalidated once the struct is gone). That'd be at least one good reason to allocate the memory using an API call. (Remember DLLStructCreate accepts pointers, and this is where you'll need it)Thanks for making me dig a little deeper into this stuff. MSDN is a great resource, but its difficult at times to find out how certain things connect together My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
Malkey Posted October 20, 2010 Posted October 20, 2010 AndyG Referring to the image data, and in particular Scan0 - The element Scan0, which is in the $tagGDIPBITMAPDATA structure, which is returned from the _GDIPlus_BitmapLockBits() function, is a pointer to the first (index 0) scan line of the bitmap. Note the variable $Scan is the same value, and can replace DllStructGetPtr($tPixelData) in your script. And, it appears "$tPixelData = DllStructCreate("dword[" & (Abs($Stride * $iHeight)) & "]", $Scan)" is not necessary (redundant) when $Scan is used. I thought you might find that interesting.
AndyG Posted October 21, 2010 Author Posted October 21, 2010 (edited) @Malkey, you are right! The struct that you mentioned is one of the relics from the making of Assemblercode based on some older AutoIt-dllstructsetdata(Work_with_Bitmapdata)-Scripts. Sometimes it is useful to ask:"Hey, whats going on in the memory?". From AutoIt, the only chance you have to "see" some Bytes is the usage of dllstruct()....From time to time my first try of an idea is implemented in Autoitcode. Then i have to write/read Bits and Bytes and without dllstruct() nothing would ever happen . Edited October 21, 2010 by AndyG
AndyG Posted March 20, 2011 Author Posted March 20, 2011 (edited) AssembleIt() now with a "debugger", see first post please./edit/ i cannot edit the first post...always get a message "You must enter a post." EDIT 03-20-2011: AssembleIt now includes a possibility to show the content of registers, flags, xmm-registers, FPU-registers and the stack during the runtime of the asm-code. Someone called this a "Debugger", it´s really not a debugger, it´s a chaotic piece of a script. pictureThere are some nice features (i.e. running the asm-code until a register contains a specific content), so it could help sometimes...You can find AssembleIt and an example how to use it here or in the attached zipfile. Have fun! Edited March 20, 2011 by AndyG
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now