Popular Post Beege Posted September 15, 2013 Popular Post Share Posted September 15, 2013 (edited) Spoiler Here is an extended version of wards fasm udf. It uses his original udf as the heart, but is structured a bit differently to make writing assembly functions in a way that's a little more familiar and also adds some memory management. My initial main purpose for all the memory management was so that you never have to use the org instruction. Never having to use org makes it so I can easily turn any assembly function into a full machine code version that doesn't require the library. Variables: Before I get into the structure I mentioned, I want to quickly explain one bit about the variable format. One of Fasm features is that it allows you to create a label that is equivalent to some location, but at the same time declare its type. For example "Label var1 dword at ebp-4". From there on, fasm know that var1 is equivalent to ebp-4, but also knows its a dword so you don't ever need to specify the type in any operation. Because ebp-4 is a memory location that would need brackets to access, you would need the same for your label eg: [var1]. Since all the variables you create are going to be ebp-##, this allows me add one more feature that says "$" is equal to [***]. Now we can refer to it as either $var1 or [var1]. Additionally, by default I automatically create a pointer to every variable that gets created. You can then refer to the address of a variable using the '*' operator. So $var1* equals a pointer to $var1. Format/Structure As with most languages, we are going to have a start and end declaration. In autoit its "Func" and "EndFunc". For this library its functions _FasmFunc() and _FasmEndFunc(). _FasmFunc allows you to declare the paramaters and types being passed to the function. These parms should match the same as your main dllcalladdress(), minus the function address and return parm. Thats including the types. All autoit types are allowed when declaring params and variables. Internally it will get converted to its equivalent fasm type, but I keep track of what it really is. This becomes a key role in the Debug functions I setup which Ill talk about in a bit. One other difference from wards original is that Im doing managed global object for all functions instead of passing the object around byref. This means for all functions, you dont have to specify the fasm object as the first variable, you can go straight into typing your assembly code. I have forwards setup for all the original functions to support this. All of wards functions start with Fasm*** so I made mine start with _Fasm***. Main reason I did this is cause 90% of the time, Im not jumping back and forth between different assembly functions, Im normally just working on the one. If are going to be going back and forth between assembly functions, _FasmFunc() returns an index that you can use with _FasmSetFunc() to set the current object your working on. _FasmFunc("'handle', $hLV, 'ptr', $pItems, int, $iNum") ;*fasm code* ;*fasm code* ;*fasm code* _FasmEndFunc() DllCallAddress('int', $pFunc, 'handle', $hLV, 'ptr', $pItems, 'int', $iNum) Variables Again: You create variables using _FasmLocalVar(). This will increment the local stack value and create a label at that positon. As stated above, you can use autoit types when creating. Important to note though that All variable names must be different. If not fasm will give a "label already exists" error. During creation you can optionally assign it a value using '=' operator. The value can be a number, float, previous variable, register, or pointer in a register. ex: _FasmLocalVar("int $var1 = [eax]"). This would assign $var1 to the value that eax is pointing to. Strings: Strings get created usings _FasmLocalstr(). You can make the string wide when calling the function, or by setting _FasmSetOpts() to make all string functions I have use wide string. The variable you use declare the string with gets assigned a pointer to the string. So for strings, using the '$var1*' is the same as $var1. DllStructures: There are 3 functions included for working with dllstructures. _FasmDllStructCreate, _FasmDllStructSetData, _FasmDllStructGetPtr. The functionality of these is basically the same as autoits. Like _FasmLocalstr(), the variable you declare it with gets assigned a pointer to the structure. This is because the memory gets allocated using VirtualAlloc. code to free the memory is automattically added at the end of the function. If you need to retain the data between funtion calls, you should create and pass it in from autoit as a parm. Like autoits dllstructcreate(), _FasmDllStructCreate can use a pointer supplied instead of allocating memory. _FasmDllStructSetData has the same suppport as variables getting initially assigned. GetProcAddress: _FasmGetProcAddress is used to get the address of a dll function. On first call it will add assembly code to get the handle to kernel32.dll, along with code to walk kernel32 to find the address of GetProcAddress. It will then call Getprocessaddress to get the actual address you requested. A variable gets created that by default is the name of the function. You can optionally change the name if you want. Debug functions: There are 5 debug functions: . They are _DBug_DisplayStruct, _DBug_PrintVar, _DBug_PrintStr, _DBug_TimerInit, _DBug_TimerDiff. These are very handy for quickly seeing the value of a var, register, or structure during assembly call. When debuging a var that you created, you don't need to specify a type as this is already known. This is the main reason I recommend declaring your variables with autoit types. That is the type that will be used during dbug. All debug functions use global callbacks so they are for runtime only and cant be included when generating a machine code version. Extras: _FasmStdCall, _FasmCdCall, are for calling dll functions and work basically the same way as the macros stdcall and cdcall mentioned in fasm documentation. The main reason I added functions to manually create the code is because if there is an error in any of the calls that use the macro, the error line number ends up pointing to the macro declaration instead of the actual line that has the error in it. This includes something like a typo in a variable name. That really sucks if say for example you have 5 stdcalls. All you know is one of them is wrong. Not which one. Generating the code that pushes all the parms and calls the function will make it clear if you make a typo or something somewhere. _FasmJumpIf works the same, only supports operators as well. So for example: _FasmJumpIf("$var1 <= ebx, Loop1"); jump to Loop1 if $var1 <= ebx. Making Machine Code Functions: _FasmCompileMC is for generating mc versions. The function will compile the asm code, read in the current script and generate the same function that the fasm code is currently in, only replacing all removing all _Fasm function with the mc version. Uncomment the function call in the examples to see. There are a few more functions included that Im not going to cover here but have descriptions and examples using them. Last topic I need to talk about is _FasmLocalStruct(). You will see this marked as "unstable" in the udf. Talk about the biggest f***ing wild goose chase I've ever been on. My original design for dll structures was to create them on the stack and only use virtualalloc when it was really big. The first few functions I made and tested worked fine as expected. Then on the last test function which just adds items to a listview, I removed the callback function I was using to debug the LVItem structure. (This is before I created the _dbug** functions) After removal the items would not get added to the listview. I put the callback functions back in and all fine. Remove them, nothing. I troubleshooted this for days! At some point I removed all the calls to the debug functions and accidentally forgot to remove the callback parms from the dllcalladdress() and notice it was still working. Then replaced the callback functions with ptr, 0. Still worked. Removed the parms (that were doing nothing), no items. This was killing me. Why the hell would passing an empty value make it work? Turns out it is something to do with the offset of were the structure gets created. I have an example that repeats the function and increments the offset each call. I then check the listview for items and print to the console if that offset worked or not. The example goes from ebp-0 to ebp-1024. Towards the end of the offset you can see a little bit of pattern, but in the beginning its all over the place in my eyes. If anyone has any knowledge of what that's about, please let me know. As always thanks for looking and please feel free to ask any questions if confused or find issues. Special thanks to Ward for his udf and Trancexx for her assembly examples as they have played a huge role in my learning of asm. UDF Requires >Beta version 3.3.9.19 or higher. Also Requires >Wards Fasm UDF. Direct Download Link FASMEx.zip FasmEx 9-29-2013.zip This is dead. See new version here : Edited January 20, 2019 by Beege UEZ, Mobius, Zmy and 5 others 8 Assembly Code: fasmg . fasm . BmpSearch . Au3 Syntax Highlighter . Bounce Multithreading Example . IDispatchASMUDFs: Explorer Frame . ITaskBarList . Scrolling Line Graph . Tray Icon Bar Graph . Explorer Listview . Wiimote . WinSnap . Flicker Free Labels . iTunesPrograms: Ftp Explorer . Snipster . Network Meter . Resistance Calculator Link to comment Share on other sites More sharing options...
Beege Posted September 30, 2013 Author Share Posted September 30, 2013 (edited) Updates: Added support for assignment operator (=) usage in _FasmAdd() . Ex: _FasmAdd('eax = 100') Added Ternary operator support as well.. Ex: _FasmAdd('$var1 <> eax ? $var2 = 37 : add $var2, 50') Added few more examples. Base64 encode/decode Reworte StrInStr function. (Should have been called CharInStr. Not sure what I was thinking..) Reworte _Listview_AddArray example. Previous would not work correctly if passed 1d array. X64 Support: I remember quite a while back reading the FASM forum thread where the fasm.dll is posted and there is some talk about x64 support and pretty much goes on to say that it is indeed not supported and would take a lot of rewrite to get it there. As of now nothing has changed about that, BUT it is a little misleading..expecially for the way we are using it. The other day while reviewing the fasm.dll source, I noticed that it included "x86_64.inc" file and it dawned on me. Just because the dll cant run in 64bit mode doesn't mean it cant generate 64bit code. Thats two totally different things. So I did some quick tests were I generate the 64bit opcode while running in a 32bit process, then take the opcode and place it in a 64bit process. All worked good So right now for a quick work around to get 64bit support, I made a few modifications to wards library that when running in 64bit mode, at compile time I simply place the source on the clipboard, launch a separate script in 32bit mode, generate the code and then pass it back. So far its been working pretty well. I don't have full support to all my original functions yet but definitely plan to. I have written a few examples to show the functionality and whats currently supported. Pretty much anything you don't see me using has not been included. The examples are testing strings, getting the address of "GetProcAddress", and Base64 Decode.If you decide to play around with it, remember the calling convention is much different than x86 in how the parameters get passed. I'm still learning myself so I'm not going to sit hear and try to educate anyone, just wanted to point that out. Note that due to the modifications of wards libaray, I have now included it in the package. Edited September 30, 2013 by Beege Assembly Code: fasmg . fasm . BmpSearch . Au3 Syntax Highlighter . Bounce Multithreading Example . IDispatchASMUDFs: Explorer Frame . ITaskBarList . Scrolling Line Graph . Tray Icon Bar Graph . Explorer Listview . Wiimote . WinSnap . Flicker Free Labels . iTunesPrograms: Ftp Explorer . Snipster . Network Meter . Resistance Calculator Link to comment Share on other sites More sharing options...
UEZ Posted September 30, 2013 Share Posted September 30, 2013 (edited) I would be cool to have some lessions how to use Asm e.g. for doing some calculations, array r/w, struct r/w, etc., something like "Asm for dummies". Thanks for efforts on this project. Br, UEZ Edited September 30, 2013 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Beege Posted September 30, 2013 Author Share Posted September 30, 2013 Hey UEZ, Thanks for the comments. For structures and arrays Ive really tried to take all the confusion away by making the _FASMDllStuct*** functions. The operate the same way autoit functions do but handle all the calculations for you. A small tutorial on how its being done could be arranged though Assembly Code: fasmg . fasm . BmpSearch . Au3 Syntax Highlighter . Bounce Multithreading Example . IDispatchASMUDFs: Explorer Frame . ITaskBarList . Scrolling Line Graph . Tray Icon Bar Graph . Explorer Listview . Wiimote . WinSnap . Flicker Free Labels . iTunesPrograms: Ftp Explorer . Snipster . Network Meter . Resistance Calculator Link to comment Share on other sites More sharing options...
LarsJ Posted April 15, 2016 Share Posted April 15, 2016 I've been playing with this. It's not working in 3.3.14 or 3.3.12, but it's working in 3.3.10.2. To make it work in 3.3.14 insert _ArrayAdd from 3.3.10.2 in bottom of FASMEx.au3: Func _ArrayAdd_33102(ByRef $avArray, $vValue) If Not IsArray($avArray) Then Return SetError(1, 0, -1) If UBound($avArray, 0) <> 1 Then Return SetError(2, 0, -1) Local $iUBound = UBound($avArray) ReDim $avArray[$iUBound + 1] $avArray[$iUBound] = $vValue Return $iUBound EndFunc ;==>_ArrayAdd_33102 and replace all occurrences of _ArrayAdd with _ArrayAdd_33102. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
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