trancexx Posted June 7, 2009 Posted June 7, 2009 (edited) Another theoretical/practical contemplation. I've been working and playing with AutoIt for the past little over a year. We all know how great AutoIt is.What I miss the most is the speed. I mean there is nothing particulary bed with anything (at least wouldn't be noticed) but loops. I'm aware this is caused by the interpretation process, but it sucks. And if you try to ask for an alternative you get banned (I'm kidding, but still don't ask , it's not allowed on grounds of motives).Alternative to looping this high could be this relatively new technique of generating assembly code on the fly.Idea is to push loops to assembly level and just wait for the results. Writting code that loops there is probably the fastest thing you will ever write. You are communicating with a processor directly.Let's take one example. Will proccess code written for the purposes of one thread in General Help and Support forum. This is the link to the code and the code is this: expandcollapse popup#include <GUIConstantsEx.au3> Opt("GUIOnEventMode", 1) Global Const $iWidth = 110 Global Const $iHeight = 70 GUICreate("", $iWidth, $iHeight) GUISetOnEvent(-3, "_Quit") GUISetBkColor(0x000000) Global $Pic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight) Global Const $STM_SETIMAGE = 370 Global $iSize = $iWidth * $iHeight Global $tBits = DllStructCreate("int[" & $iSize & "]") Global $pBits = DllStructGetPtr($tBits) Global $hBitmap, $aCall GUISetState() While 1 For $i = 1 To $iSize DllStructSetData($tBits, 1, Random(0, 0xFFFFFF, 1), $i) Next DllCall("gdi32.dll", "int", "DeleteObject", "ptr", $hBitmap) $aCall = DllCall("gdi32.dll", "hwnd", "CreateBitmap", _ "int", $iWidth, _ "int", $iHeight, _ "dword", 1, _ "dword", 32, _ "ptr", $pBits) $hBitmap = $aCall[0] DllCall("gdi32.dll", "int", "DeleteObject", "ptr", GUICtrlSendMsg($Pic, $STM_SETIMAGE, 0, $hBitmap)) Sleep(0) WEnd Func _Quit() Exit EndFunc;==>_QuitWhat it does? It generates a bitmap with randomly colored pixels and displays that bitmap in GUI.Every pixel is, as I said, colored differently. Part of the code that deals with that is:For $i = 1 To $iSize DllStructSetData($tBits, 1, Random(0, 0xFFFFFF, 1), $i) Next Value of $iSize in that case is 7700. That means that AutoIt will do 7700 times:DllStructSetData($tBits, 1, Random(0, 0xFFFFFF, 1), $i)If you run that code you will see that it takes almost 100% CPU (one processor) and that it's almose incredibly slow. I even had to add Sleep(0) to avoid total disaster.It's the fastest you'll get using conventional AutoIt scripting.So, how to speed it up?First I'm going to rewrite it to use win api calls inside While... WEnd. This s needed and is essential for transformation to assembly.Modified script would be this:expandcollapse popup#include <GUIConstantsEx.au3> Opt("GUIOnEventMode", 1) Global Const $STM_SETIMAGE = 370 Global Const $iWidth = 110 Global Const $iHeight = 70 GUICreate("", $iWidth, $iHeight) GUISetOnEvent(-3, "_Quit") GUISetBkColor(0x000000) Global $hPic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight) Global $iSize = $iWidth * $iHeight Global $tBits = DllStructCreate("int[" & $iSize & "]") Global $pBits = DllStructGetPtr($tBits) Global $hBitmap, $aCall, $iHMsg Global $hPicHandle = GUICtrlGetHandle($hPic) Global $tRandom = DllStructCreate("dword") Global $pRandom = DllStructGetPtr($tRandom) GUISetState() While 1 For $i = 0 To $iSize - 1 DllCall("ntdll.dll", "dword", "RtlRandomEx", "ptr", $pRandom) DllCall("kernel32.dll", "none", "RtlMoveMemory", _ "ptr", $pBits + $i * 4, _ "ptr", $pRandom, _ "dword", 3) Next ;DllCall("gdi32.dll", "int", "DeleteObject", "ptr", $hBitmap) $aCall = DllCall("gdi32.dll", "hwnd", "CreateBitmap", _ "int", $iWidth, _ "int", $iHeight, _ "dword", 1, _ "dword", 32, _ "ptr", $pBits) $hBitmap = $aCall[0] $aCall = DllCall("user32.dll", "ptr", "SendMessageW", _ "hwnd", $hPicHandle, _ "dword", $STM_SETIMAGE, _ "dword", 0, _ "ptr", $hBitmap) $iHMsg = $aCall[0] DllCall("gdi32.dll", "int", "DeleteObject", "ptr", $iHMsg) Sleep(0) WEnd Func _Quit() Exit EndFunc ;==>_QuitIf you run it you will se that it's as CPU demanding as before only a bit slower.That is not a concern righ now. It is what it is. Main thing is that inside While... WEnd is nothing but DllCall(). Now for why I'm writing this...If you have some experience with assembly (maybe thru mine or monoceres's posts/threads) then you know that out of that code you can write something like this and doing that you will be a step closer to a moon:expandcollapse popup#include <GUIConstantsEx.au3> #include <Memory.au3> Opt("GUIOnEventMode", 1) Global Const $STM_SETIMAGE = 370 Global Const $iWidth = 110 Global Const $iHeight = 70 GUICreate("", $iWidth, $iHeight) GUISetOnEvent(-3, "_Quit") GUISetBkColor(0) Global $hPic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight) Global $iSize = $iWidth * $iHeight Global $tBits = DllStructCreate("int[" & $iSize & "]") Global $pBits = DllStructGetPtr($tBits) Global $hBitmap, $aCall, $iHMsg Global $hPicHandle = GUICtrlGetHandle($hPic) Global $tRandom = DllStructCreate("dword") Global $pRandom = DllStructGetPtr($tRandom) GUISetState() Global $aRtlRandomEx = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("ntdll.dll"), "str", "RtlRandomEx") Global $pRtlRandomEx = $aRtlRandomEx[0] Global $aRtlMoveMemory = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "RtlMoveMemory") Global $pRtlMoveMemory = $aRtlMoveMemory[0] Global $pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) Local $tCodeBuffer = DllStructCreate("byte[512]", $pRemoteCode) While 1 #Region Assembly DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "33DB" & _ ; xor ebx, ebx "68" & SwapEndian($pRandom) & _ ; push $pRandom "B8" & SwapEndian($pRtlRandomEx) & _ ; mov eax, RtlRandomEx "FFD0" & _ ; call eax "8BCB" & _ ; mov ecx, ebx "69C9" & SwapEndian(4) & _ ; imul ecx, 4 "81C1" & SwapEndian($pBits) & _ ; add ecx, $pBits "68" & SwapEndian(3) & _ ; push 3 bytes "68" & SwapEndian($pRandom) & _ ; push $pRandom "51" & _ ; push ecx "B8" & SwapEndian($pRtlMoveMemory) & _ ; mov eax, RtlMoveMemory "FFD0" & _ ; call eax "43" & _ ; inc ebx "81FB" & SwapEndian($iSize) & _ ; cmp ebx, $iSize; <- compare ebx with $iSize "75" & Hex(256 - 53, 2) & _ ; jne -53 bytes; <- this is saying go back and do it again if not equal "C3" _ ; ret ) DllCall("user32.dll", "int", "CallWindowProcW", _ "ptr", $pRemoteCode, _ "int", 0, _ "int", 0, _ "int", 0, _ "int", 0) #EndRegion Assembly ;DllCall("gdi32.dll", "int", "DeleteObject", "ptr", $hBitmap) $aCall = DllCall("gdi32.dll", "hwnd", "CreateBitmap", _ "int", $iWidth, _ "int", $iHeight, _ "dword", 1, _ "dword", 32, _ "ptr", $pBits) $hBitmap = $aCall[0] $iHMsg = GUICtrlSendMsg($hPic, $STM_SETIMAGE, 0, $hBitmap) DllCall("gdi32.dll", "int", "DeleteObject", "ptr", $iHMsg) Sleep(10) WEnd Func SwapEndian($iValue) Return Hex(Binary($iValue)) EndFunc ;==>SwapEndian Func _Quit() Exit EndFunc ;==>_QuitIf you observe it you will see that there is no AutoIt loop (don't tease me with While... WEnd ). And if you run it the results will be visually the same as before. But check CPU usage! It should be 0%. And this time I'm slowing it down with Sleep(10). You can make it bigger now (110x70 is ridiculously small).I'm closing this rather fast because the post is getting too big to follow.Before the end here's another script. This one transforms even larger part of the code from AutoIt to assembly (just for fun):expandcollapse popup#include <GUIConstantsEx.au3> #include <Memory.au3> Opt("GUIOnEventMode", 1) Global Const $STM_SETIMAGE = 370 Global Const $iWidth = 810 Global Const $iHeight = 470 GUICreate("", $iWidth, $iHeight) GUISetOnEvent(-3, "_Quit") GUISetBkColor(0) Global $hPic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight) Global $iSize = $iWidth * $iHeight Global $tBits = DllStructCreate("int[" & $iSize & "]") Global $pBits = DllStructGetPtr($tBits) Global $hBitmap, $aCall, $iHMsg Global $hPicHandle = GUICtrlGetHandle($hPic) Global $tRandom = DllStructCreate("dword") Global $pRandom = DllStructGetPtr($tRandom) GUISetState() Global $aRtlRandomEx = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("ntdll.dll"), "str", "RtlRandomEx") Global $pRtlRandomEx = $aRtlRandomEx[0] Global $aRtlMoveMemory = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "RtlMoveMemory") Global $pRtlMoveMemory = $aRtlMoveMemory[0] Global $aSendMessageW = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("user32.dll"), "str", "SendMessageW") Global $pSendMessageW = $aSendMessageW[0] Global $aDeleteObject = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("gdi32.dll"), "str", "DeleteObject") Global $pDeleteObject = $aDeleteObject[0] Global $aCreateBitmap = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("gdi32.dll"), "str", "CreateBitmap") Global $pCreateBitmap = $aCreateBitmap[0] Global $pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) Local $tCodeBuffer = DllStructCreate("byte[512]", $pRemoteCode) While 1 #region Assembly DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "33DB" & _ ; xor ebx, ebx "68" & SwapEndian($pRandom) & _ ; push $pRandom "B8" & SwapEndian($pRtlRandomEx) & _ ; mov eax, RtlRandomEx "FFD0" & _ ; call eax "8BCB" & _ ; mov ecx, ebx "69C9" & SwapEndian(4) & _ ; imul ecx, 4 "81C1" & SwapEndian($pBits) & _ ; add ecx, $pBits "68" & SwapEndian(3) & _ ; push 3 bytes "68" & SwapEndian($pRandom) & _ ; push $pRandom "51" & _ ; push ecx "B8" & SwapEndian($pRtlMoveMemory) & _ ; mov eax, RtlMoveMemory "FFD0" & _ ; call eax "43" & _ ; inc ebx "81FB" & SwapEndian($iSize) & _ ; cmp ebx, $iSize; <- compare ebx with $iSize "75" & Hex(256 - 53, 2) & _ ; jne -53 bytes; <- this is saying go back and do it again if not equal "68" & SwapEndian($pBits) & _ ; push $pBits "68" & SwapEndian(32) & _ ; push BitsPerPel "68" & SwapEndian(1) & _ ; push Planes "68" & SwapEndian($iHeight) & _ ; push $iHeight "68" & SwapEndian($iWidth) & _ ; push $iWidth "B8" & SwapEndian($pCreateBitmap) & _ ; mov eax, CreateBitmap "FFD0" & _ ; call eax "50" & _ ; push eax "68" & SwapEndian(0) & _ ; push IMAGE_BITMAP "68" & SwapEndian($STM_SETIMAGE) & _ ; push STM_SETIMAGE "68" & SwapEndian($hPicHandle) & _ ; push $hPicHandle "B8" & SwapEndian($pSendMessageW) & _ ; mov eax, SendMessageW "FFD0" & _ ; call eax "50" & _ ; push eax "B8" & SwapEndian($pDeleteObject) & _ ; mov eax, DeleteObject "FFD0" & _ ; call eax "C3" _ ; ret ) DllCall("user32.dll", "int", "CallWindowProcW", _ "ptr", $pRemoteCode, _ "int", 0, _ "int", 0, _ "int", 0, _ "int", 0) #endregion Assembly Sleep(10) WEnd Func SwapEndian($iValue) Return Hex(Binary($iValue)) EndFunc ;==>SwapEndian Func _Quit() Exit EndFunc ;==>_QuitIt's 810x470 and not even close to heating up your processor as the original script.Btw, I'm no expert in functions that deals with generating random numbers, so maybe seed needs changing with new run (on Vista not).Assembly code is executed using CallWindowProc function in these examples.edit: corrected most of the misspellings Edited June 7, 2009 by trancexx ♡♡♡ . eMyvnE
Acidut Posted June 7, 2009 Posted June 7, 2009 are you sure it's random? cause i definately see some patterns here:) other than that nice job
martin Posted June 7, 2009 Posted June 7, 2009 @trancexx you didn't mention that it's about 60 times faster! BTW Sleep(0) is the same as Sleep(10) Can you make a little udf so that we can have _TXLoop("Function", $from, $to, $step) or something near that? Me want Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
monoceres Posted June 7, 2009 Posted June 7, 2009 (edited) Nice work as usual trancexx, this whole machine code stuff is a newly opened gold mine, maybe we should start making an assembler soon? BTW Sleep(0) is the same as Sleep(10)Actually no, Sleep(0) is a very special case, more info here in the remarks section.Can you make a little udf so that we can have_TXLoop("Function", $from, $to, $step)The problem is that for this to get the positive effect the code inside the function needs to be converted to assembly code and then to raw machine code. So what this actually means is to create a true compiler for autoit, something that is extremely hard, time consuming and is in fact the same as creating a new language. Of course your request could be done with a DllCallbackRegister() method, but that would mean that the optimized part of the loop would only be the start (example: While $a=1). Edited June 7, 2009 by monoceres Broken link? PM me and I'll send you the file!
UEZ Posted June 7, 2009 Posted June 7, 2009 That's absolutely crazy (idea born from here?)To understand it I need to learn assembler 'cause it gives me new ideas about graphical stuff...Respectfull work!!!Btw, how can I set the pixel size? Currently 1x1.Keep your good work up trancexx!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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Zedna Posted June 7, 2009 Posted June 7, 2009 I have seen calling assembly code from AutoIt already but this is nicely commented valuable example for the masses :-) My skills in ASM are quite poor so I doubt I will use it but it's good to see the possibilities :-) Five stars from me Resources UDF ResourcesEx UDF AutoIt Forum Search
colafrysen Posted June 7, 2009 Posted June 7, 2009 (edited) Wow... Just awesome, that speed... you just gave me a project this summer, to learn Assembly. and just curious, how much speed do you actually get in % of processor Ghz (with something simple, such as adding counting 1,2,3...) Btw very well written post, i've seen this stuff before but i haven't even tried to get my mind into it, but these examples and the comments really help. Edited June 7, 2009 by colafrysen [font="Impact"]Use the helpfile, It´s one of the best exlusive features of Autoit.[/font]http://support.microsoft.com/kb/q555375ALIBI Run - a replacement for the windows run promptPC Controller - an application for controlling other PCs[size="1"]Science flies us to the moon. Religion flies us into buildings.[/size][size="1"]http://bit.ly/cAMPZV[/size]
martin Posted June 7, 2009 Posted June 7, 2009 Nice work as usual trancexx, this whole machine code stuff is a newly opened gold mine, maybe we should start making an assembler soon? Actually no, Sleep(0) is a very special case, more info here in the remarks section.Oh, thanks. I thought the minimum sleep was 10 and in fact sleep(1) is the same as sleep(10), but I ddn't realize sleep(0) was different.The problem is that for this to get the positive effect we want the code inside the function needs to be converted to assembly code and then to raw machine code. So what this actually means is to create a true compiler for autoit, something that is extremely hard, time consuming and is in fact the same as creating a new language. Of course your request could be done with a DllCallbackRegister() method, but that would mean that the optimized part of the loop would only be the start (example: While $a=1).Yes, I see. I got a little over excited there. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
monoceres Posted June 7, 2009 Posted June 7, 2009 (edited) and just curious, how much speed do you actually get in % of processor Ghz (with something simple, such as adding counting 1,2,3...)The ADD instruction is one of the most fundamental instruction in the x86 tool set (and in all processors) and for Intel Pentium processors it only require 1 or 2 clock cycles to complete (lets say 1). This mean that a Intel Pentium 4 processor @ 2.40 GHz can in theory do 2.4 billion add operations per second. Quite impressive I have to say.However in practice you need to have the processor keep going and you will probably do this with the JMP instruction, this is a much more greedy instruction (7 cycles).So in practice it will reach a speed at (2'400'000'000 / 8)= 300 million adds per second.Edit: Instruction, not function Edited June 7, 2009 by monoceres Broken link? PM me and I'll send you the file!
colafrysen Posted June 7, 2009 Posted June 7, 2009 I have to say that 300 million is extreme, 0.3 million is much. and i thought my 1.7 Ghz computer was slow, Well I am convinced. I'll learn assembly, you guys got any tips or resources? how did you learn? give me a PM (I do not want to hijack the thread) [font="Impact"]Use the helpfile, It´s one of the best exlusive features of Autoit.[/font]http://support.microsoft.com/kb/q555375ALIBI Run - a replacement for the windows run promptPC Controller - an application for controlling other PCs[size="1"]Science flies us to the moon. Religion flies us into buildings.[/size][size="1"]http://bit.ly/cAMPZV[/size]
Zedna Posted June 7, 2009 Posted June 7, 2009 (edited) @trancexxIt would be awesome to have ASM optimized version of some (just few) core functions from standard array include filelike _ArraySearch(), _ArrayMaxIndex(), _ArrayMinIndex(), _ArrayToString(), ...all thouse functions containing very simple FOR NEXT loops which may be very slow on large arrays.I think arrays are often used by scripters (including me) and in some cases are source of slow scripts.So end scripters doesn't need to have knowledge of ASM, they just recompile their script with ASM optimized array include file.EDIT: Maybe something like AddressOf($var) should be added to AutoIt to have full power of this ASM optimizationsSee my old rejected request for AddressOf($var) on Trac:http://www.autoitscript.com/trac/autoit/ticket/279EDIT2:Another functions candidate for ASM optimization are some from File include:_FileCountLines() - maybe using filemapping?_FileListToArray()_FileReadToArray()_FileWriteFromArray()_ReplaceStringInFile() Edited June 7, 2009 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search
trancexx Posted June 7, 2009 Author Posted June 7, 2009 @trancexxIt would be awesome to have ASM optimized version of some (just few) core functions from standard array include filelike _ArraySearch(), _ArrayMaxIndex(), _ArrayMinIndex(), _ArrayToString(), ...all thouse functions containing very simple FOR NEXT loops which may be very slow on large arrays.I think arrays are often used by scripters (including me) and in some cases are source of slow scripts.So end scripters doesn't need to have knowledge of ASM, they just recompile their script with ASM optimized array include file.EDIT: Maybe something like AddressOf($var) should be added to AutoIt to have full power of this ASM optimizationsSee my old rejected request for AddressOf($var) on Trac:http://www.autoitscript.com/trac/autoit/ticket/279EDIT2:Another functions candidate for ASM optimization are some from File include:_FileCountLines() - maybe using filemapping?_FileListToArray()_FileReadToArray()_FileWriteFromArray()_ReplaceStringInFile()If you answer what some array is you will see that it's almost impossible to do it. Even if sombody does it, it would never be included in standard UDFs, not to mention that it would also probably resulted in a permanent ban from the forums for the coder. Am I exaggerating?File functions are differnt and that could be done (not array parts). But for example, I think _ReplaceStringInFile() would be just fine without assembly part.Acidut sees patterns. I see them too on XP. I wrote that script on Vista (to check for DEP issues) and there are no patterns there. Likely used algorithm in RtlRandomEx is changed with Vista. Someone with experience with that function or randomizing generally could give us the answer. There is also a possibility that I'm not using that function right. But it's not that important.UEZ asks about the site of pixel... again. Color four in a row and do the same thing in three following lines with the same color to get 4x4.Thanks for the comments.... and nobody noticed Hex(256 - 53, 2)? @monoceres, I hope to see some gold from you now. ♡♡♡ . eMyvnE
Inverted Posted June 7, 2009 Posted June 7, 2009 I've seen the other threads about using asm directly and it leaves a bitter taste in my mouth. This looks bad. If you want to use asm, you can assemble+link an asm dll and call its functions.
WideBoyDixon Posted June 7, 2009 Posted June 7, 2009 Truly mindblowing stuff. However, if I can reduce everything to DllCall then I'm probably thinking that I'd just write it in C/C++ and use DllCall (or COM) to call the functionality anyway. I'm a bit too long in the tooth to be learning Assembler :-) WBD [center]Wide by name, Wide by nature and Wide by girth[u]Scripts[/u]{Hot Folders} {Screen Calipers} {Screen Crosshairs} {Cross-Process Subclassing} {GDI+ Clock} {ASCII Art Signatures}{Another GDI+ Clock} {Desktop Goldfish} {Game of Life} {3D Pie Chart} {Stock Tracker}[u]UDFs[/u]{_FileReplaceText} {_ArrayCompare} {_ToBase}~ My Scripts On Google Code ~[/center]
Zedna Posted June 7, 2009 Posted June 7, 2009 Truly mindblowing stuff. However, if I can reduce everything to DllCall then I'm probably thinking that I'd just write it in C/C++ and use DllCall (or COM) to call the functionality anyway. I'm a bit too long in the tooth to be learning Assembler :-)WBDNo.It's pretty because you can use AutoIt for whole project and assembler only for core part (sensitive to speed) - optimize just few lines but speed-up application dramatically. Did you get the point now? :-) Resources UDF ResourcesEx UDF AutoIt Forum Search
UEZ Posted June 8, 2009 Posted June 8, 2009 (edited) ... UEZ asks about the site of pixel... again. Color four in a row and do the same thing in three following lines with the same color to get 4x4. ... Sorry that I bored you again with the same question! Anyway, can you explain me/us more about the assembler code? ... DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "33DB" & _ ; xor ebx, ebx "68" & SwapEndian($pRandom) & _ ; push $pRandom "B8" & SwapEndian($pRtlRandomEx) & _ ; mov eax, RtlRandomEx "FFD0" & _ ; call eax "8BCB" & _ ; mov ecx, ebx "69C9" & SwapEndian(4) & _ ; imul ecx, 4 "81C1" & SwapEndian($pBits) & _ ; add ecx, $pBits "68" & SwapEndian(3) & _ ; push 3 bytes "68" & SwapEndian($pRandom) & _ ; push $pRandom "51" & _ ; push ecx "B8" & SwapEndian($pRtlMoveMemory) & _ ; mov eax, RtlMoveMemory "FFD0" & _ ; call eax "43" & _ ; inc ebx "81FB" & SwapEndian($iSize) & _ ; cmp ebx, $iSize; <- compare ebx with $iSize "75" & Hex(256 - 53, 2) & _ ; jne -53 bytes; <- this is saying go back and do it again if not equal "C3" _ ; ret ) ... I mean not the command itself (this is more or less clear) but the why you used this in that way (meaning)! E.g, why you made a xor in the 1st line, call eax (what is called?), etc.? I'm trying to understand that code but without success THANKS, UEZ Edited June 8, 2009 by 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Inverted Posted June 8, 2009 Posted June 8, 2009 (edited) @ UEZEach line is commented, they are assembly commands, some are concatenated with addresses of memory pointers, which are in turn reversed (because they are stored in memory in reverse order)The guys just used a assembler to see what bytes make up what commands. For example you can use the Olly debugger and just start assembling commands and look at the bytes.The XOR command is the known bitwise operation, in the first line they XOR the EBX register with itself to make it zero (less bytes than mov ebx,0)"call eax" calls the address of eax, which is RtlMoveMemory, they could have used call dword ptr []After the call is done, it returns at the next command with aligned stack.Anyway, if you want to wield the awesome power of assembly, start here :http://www.masm32.com/(and ask serious question at the forum there)And check the tutorial series here :http://win32assembly.online.fr/ Edited June 8, 2009 by Inverted
UEZ Posted June 8, 2009 Posted June 8, 2009 @ UEZ Each line is commented, they are assembly commands, some are concatenated with addresses of memory pointers, which are in turn reversed (because they are stored in memory in reverse order) The guys just used a assembler to see what bytes make up what commands. For example you can use the Olly debugger and just start assembling commands and look at the bytes. The XOR command is the known bitwise operation, in the first line they XOR the EBX register with itself to make it zero (less bytes than mov ebx,0) "call eax" calls the address of eax, which is RtlMoveMemory, they could have used call dword ptr [] After the call is done, it returns at the next command with aligned stack. Anyway, if you want to wield the awesome power of assembly, start here : http://www.masm32.com/ (and ask serious question at the forum there) And check the tutorial series here : http://win32assembly.online.fr/ Sorry, but the comments in each line are not really understandable for me and that's why I asked although the commands are clear to me. Currently I don't want to learn assembler but I want to understand here the code roughly. Thanks for your explanations. 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
trancexx Posted June 8, 2009 Author Posted June 8, 2009 (edited) Sorry that I bored you again with the same question! Anyway, can you explain me/us more about the assembler code? ... DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "33DB" & _ ; xor ebx, ebx "68" & SwapEndian($pRandom) & _ ; push $pRandom "B8" & SwapEndian($pRtlRandomEx) & _ ; mov eax, RtlRandomEx "FFD0" & _ ; call eax "8BCB" & _ ; mov ecx, ebx "69C9" & SwapEndian(4) & _ ; imul ecx, 4 "81C1" & SwapEndian($pBits) & _ ; add ecx, $pBits "68" & SwapEndian(3) & _ ; push 3 bytes "68" & SwapEndian($pRandom) & _ ; push $pRandom "51" & _ ; push ecx "B8" & SwapEndian($pRtlMoveMemory) & _ ; mov eax, RtlMoveMemory "FFD0" & _ ; call eax "43" & _ ; inc ebx "81FB" & SwapEndian($iSize) & _ ; cmp ebx, $iSize; <- compare ebx with $iSize "75" & Hex(256 - 53, 2) & _ ; jne -53 bytes; <- this is saying go back and do it again if not equal "C3" _ ; ret ) ... I mean not the command itself (this is more or less clear) but the why you used this in that way (meaning)! E.g, why you made a xor in the 1st line, call eax (what is called?), etc.? I'm trying to understand that code but without success THANKS, UEZYou were not boring me. Inverted explained something (though he is making some wrong assumptions), but I'm gonna go line by line comparing it with AutoIt. First of all I wanna say that no assembler would assemble it this way. It looks like this to resemble the AutoIt as much as possible. Here goes: Line 1 "33DB" & _ ; xor ebx, ebx This is the same as: Local $b = 0 Line 2, 3, 4 "68" & SwapEndian($pRandom) & _ ; push $pRandom "B8" & SwapEndian($pRtlRandomEx) & _ ; mov eax, RtlRandomEx "FFD0" & _ ; call eax This is procedure for calling function RtlRandomEx. We already have the addres of that function (that is done in AutoIt few line of code up). Several techniques could be used for this. In this case moving addres of function to eax register and calling it later is used. Line 5 "8BCB" & _ ; mov ecx, ebx Introducing, assigning new variable. It's: $c = $b Line 6 "69C9" & SwapEndian(4) & _ ; imul ecx, 4 That is multiplying: $c = $c * 4 Line 7 "81C1" & SwapEndian($pBits) & _ ; add ecx, $pBits Adding $pBits to $c. $c += $pBits Line 8, 9, 10, 11, 12 "68" & SwapEndian(3) & _ ; push 3 bytes "68" & SwapEndian($pRandom) & _ ; push $pRandom "51" & _ ; push ecx "B8" & SwapEndian($pRtlMoveMemory) & _ ; mov eax, RtlMoveMemory "FFD0" & _ ; call eax Calling function RtlMoveMemory. In AutoIt that is: DllCall("kernel32.dll", "none", "RtlMoveMemory", _ "ptr", $pBits + $i * 4, _ "ptr", $pRandom, _ "dword", 3) Line 13 "43" & _ ; inc ebx Incrementing $b by 1: $b += 1 Line 14 "81FB" & SwapEndian($iSize) & _ ; cmp ebx, $iSize; <- compare ebx with $iSize Comment there explains it. Line 15 "75" & Hex(-53, 2) & _ ; jne -53 bytes; <- this is saying go back and do it again if not equal This is causing it to loop until $b equals $iSize. When it's equal code continues. Until then it will return 53 bytes back (to line 2 of the code). $b will be increased by one (of course) and new calculations and calls done. Line 16 "C3" _ ; ret Return: Return Edited June 8, 2009 by trancexx ♡♡♡ . eMyvnE
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