Leaderboard
Popular Content
Showing content with the highest reputation on 01/03/2014 in all areas
-
AutoIt compiled with static runtimes: 850KB AutoIt compiled with dynamic runtimes: 650KB (needs external VC DLLs) PCRE engine DLL size: 150KB (Full unicode mode) Total pure AutoIt code minus runtimes and PCRE: 500KB Let's say we need half of that even for a "no functions" version of AutoIt because of internal classes/utility functions/COM, etc: 250KB. That gives us a window of 250KB that is available for funtion-level optimization. I don't think I'll be using my very limited dev time for trying to save a couple of hundred KB.3 points
-
Well maybe it's me (it surely is) but I like my AutoIT code when it's FAST. So here's a little program I whipped up in about an hour. AutoIT_Speed.au3 Updated 19Aug2007 with more comments and more test results It will execute commands of your choice through two loops, 20 packs of 9999 iterations to be precise. Making two loops increased the reliability of the reading (since it seems the first iteration is really slow because of cache issues and what not). For example, you could compare $Val = $Val +1to ... $Val += 1(in this case, the obvious winner is $Val += 1 but it isn't always so evident) The code is as simple as can be, I guess if you don't get it than it's not for you In any case, the results you get might make you change your programming habits! If you do a lot of looping then I suggest you try out the commands in those loops and see what's better. Good luck! EDIT: It's been brought to my attention by chris95219 that GetTickCount() cannot be properly timed. Also if you use the $i and $j variables in your code (both loop counters) you will obviously get incorrect results! TESTED BY YOURS TRUELY: 1. For/Next loops are champions. Try not to use While/Wend or Do/Until 2. If $Val is faster than If $Val = 1 or $Val = TRUE 3. If $Val = 1 is faster than $Val = TRUE 4. If Not $Val is faster than If $Val = 0 or $Val = FALSE 5. If $Val = 0 is faster than If $Val = FALSE 6. < and > are faster than =, >= or <= (Wow!) 7. $i += 1 is faster than $i = $i + 1 $i -= 1 is faster than $i = $i - 1 $i *= 1 is faster than $i = $i * 1 $i /= 1 is faster than $i = $i / 1 8. If doing a lot of verifications on a single variable: Switch is fastest, Select is second (but slow) and If is slowest. 9. If $Val is a string, If Not $Val is faster than If $Val = "" If $Val is faster than If $Val <> "" 10. When doing binary operations, If $Val -128 > 0 is twice as fast as If BitAnd($Val, 128). 11. Using Hex numbers is faster than using decimal numbers 12 Replacing dec/hex numbers by variables slows down execution. Use hex/dec numbers when possible 13. Longer variable names = longer execution time. Keep variable names short and clear! 14. StringRegExpReplace() is slower than StringReplace(). Use it only if necessary! 15. StringRegExp() is slower than StringInStr(). Use only if necessary! 16. Opt("ExpandEnvStrings",1) makes $Val = "%TEMP%" faster than $Val = EnvGet("temp") or $Val = @TempDir 17. $Val = @TempDir is faster than $Val = EnvGet("temp") 18. Opt("ExpandVarStrings",1) makes $Val = "$String$" slightly faster than $Val = $String 19. However $Val = "@TempDir@" is slower than $Val = @TempDir (go figure!)1 point
-
Run Exe From Memory (32/64 bit)
yutijang reacted to IchBistTod for a topic
I was recently trying to get trancexx's memory injection script to work on both 64 and 32 systems. I realized the solution, the file being injected into had to be 1)larger than the exe you are attempting to execute 2)32 bit application I took the time to look through the windows 7 + vista 32 bit files in the syswow64 folder, and none can be used to execute files from memory, they give an initialization error, i see this may be related to the fact some or most are compiled with .net and/or have protection from such methods. So my solution was to make a small script modification and added a switch to determine what file to use, I know there might have been a cleaner way to do this, but here is my go at it. ps: the file i use on 64 bit is reshacker.exe a publically available program, just google it. Tested on XP 32 bit, win 7 64 bit, wind vista 64 bit not tested on Vista or 7 32 bit. MUST BE COMPILED TO 32 BIT REGARDLESS OF OPERATING SYSTEM MUST USE A 32 BIT EXE TO INJECT INTO MEMORY #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_Res_Language=1033 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** global $baseexe $baseexe = @WindowsDir&"\explorer.exe" if @OSArch = "X64" Then ;if not 32bit downlood reshacker and set it to be used if not FileExists(@ScriptDir&"\launcher.exe") Then InetGet("http://panics.co.cc/downloads/reshacker.exe", @ScriptDir&"\launcher.exe") EndIf $baseexe = @ScriptDir&"\launcher.exe" Else $baseexe = @WindowsDir&"\explorer.exe";else use explorer. EndIf ; YOUR CODE HERE Func _RunExeFromMemory($bBinaryImage, $iCompressed = 0, $test = 0) #Region 1. PREPROCESSING PASSED Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinaryImage) & "]") DllStructSetData($tInput, 1, $bBinaryImage) Local $pPointer If $iCompressed Then ; Buffer for decompressed data Local $tBuffer = DllStructCreate("byte[" & 32 * DllStructGetSize($tInput) & "]") ; oversizing it ; Decompression follows: Local $aCall = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _ "ushort", 2, _ "ptr", DllStructGetPtr($tBuffer), _ "dword", DllStructGetSize($tBuffer), _ "ptr", DllStructGetPtr($tInput), _ "dword", DllStructGetSize($tInput), _ "dword*", 0) If @error Or $aCall[0] Then ; If any troubles try original data anyway $pPointer = DllStructGetPtr($tInput) Else $pPointer = DllStructGetPtr($tBuffer) EndIf Else ; Not compressed $pPointer = DllStructGetPtr($tInput) EndIf #Region 2. CREATING NEW PROCESS ; STARTUPINFO structure (actually all that really matters is allocaed space) Local $tSTARTUPINFO = DllStructCreate("dword cbSize;" & _ "ptr Reserved;" & _ "ptr Desktop;" & _ "ptr Title;" & _ "dword X;" & _ "dword Y;" & _ "dword XSize;" & _ "dword YSize;" & _ "dword XCountChars;" & _ "dword YCountChars;" & _ "dword FillAttribute;" & _ "dword Flags;" & _ "ushort ShowWindow;" & _ "ushort Reserved2;" & _ "ptr Reserved2;" & _ "ptr hStdInput;" & _ "ptr hStdOutput;" & _ "ptr hStdError") ; This is much important. This structure will hold some very important data. Local $tPROCESS_INFORMATION = DllStructCreate("ptr Process;" & _ "ptr Thread;" & _ "dword ProcessId;" & _ "dword ThreadId") ; Create new process $aCall = DllCall("kernel32.dll", "int", "CreateProcessW", _ "wstr", $baseexe, _ ; try something else too (now only range plays, giving us a space) "ptr", 0, _ "ptr", 0, _ "ptr", 0, _ "int", 0, _ "dword", 4, _ ; CREATE_SUSPENDED ; <- this is essential "ptr", 0, _ "ptr", 0, _ "ptr", DllStructGetPtr($tSTARTUPINFO), _ "ptr", DllStructGetPtr($tPROCESS_INFORMATION)) If @error Or Not $aCall[0] Then Return SetError(2, 0, 0) ; CreateProcess function or call to it failed EndIf ; New process and thread handles: Local $hProcess = DllStructGetData($tPROCESS_INFORMATION, "Process") Local $hThread = DllStructGetData($tPROCESS_INFORMATION, "Thread") #Region 3. FILL CONTEXT STRUCTURE ; CONTEXT structure is what's really important here. It's very 'misterious' Local $tCONTEXT = DllStructCreate("dword ContextFlags;" & _ "dword Dr0;" & _ "dword Dr1;" & _ "dword Dr2;" & _ "dword Dr3;" & _ "dword Dr6;" & _ "dword Dr7;" & _ "dword ControlWord;" & _ "dword StatusWord;" & _ "dword TagWord;" & _ "dword ErrorOffset;" & _ "dword ErrorSelector;" & _ "dword DataOffset;" & _ "dword DataSelector;" & _ "byte RegisterArea[80];" & _ "dword Cr0NpxState;" & _ "dword SegGs;" & _ "dword SegFs;" & _ "dword SegEs;" & _ "dword SegDs;" & _ "dword Edi;" & _ "dword Esi;" & _ "dword Ebx;" & _ ; this is pointer to another structure whose third element will be altered "dword Edx;" & _ "dword Ecx;" & _ "dword Eax;" & _ ; another manipulation point (will set address of entry point here) "dword Ebp;" & _ "dword Eip;" & _ "dword SegCs;" & _ "dword EFlags;" & _ "dword Esp;" & _ "dword SegS") DllStructSetData($tCONTEXT, "ContextFlags", 0x10002) ; CONTEXT_INTEGER ; Fill tCONTEXT structure: $aCall = DllCall("kernel32.dll", "int", "GetThreadContext", _ "ptr", $hThread, _ "ptr", DllStructGetPtr($tCONTEXT)) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(3, 0, 0) ; GetThreadContext function or call to it failed EndIf #Region 4. READ PE-FORMAT ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "ushort BytesOnLastPage;" & _ "ushort Pages;" & _ "ushort Relocations;" & _ "ushort SizeofHeader;" & _ "ushort MinimumExtra;" & _ "ushort MaximumExtra;" & _ "ushort SS;" & _ "ushort SP;" & _ "ushort Checksum;" & _ "ushort IP;" & _ "ushort CS;" & _ "ushort Relocation;" & _ "ushort Overlay;" & _ "char Reserved[8];" & _ "ushort OEMIdentifier;" & _ "ushort OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(4, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. EndIf Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(5, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf Local $tIMAGE_FILE_HEADER = DllStructCreate("ushort Machine;" & _ "ushort NumberOfSections;" & _ "dword TimeDateStamp;" & _ "dword PointerToSymbolTable;" & _ "dword NumberOfSymbols;" & _ "ushort SizeOfOptionalHeader;" & _ "ushort Characteristics", _ $pPointer) ; Get number of sections Local $iNumberOfSections = DllStructGetData($tIMAGE_FILE_HEADER, "NumberOfSections") ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure Local $tIMAGE_OPTIONAL_HEADER = DllStructCreate("ushort Magic;" & _ "ubyte MajorLinkerVersion;" & _ "ubyte MinorLinkerVersion;" & _ "dword SizeOfCode;" & _ "dword SizeOfInitializedData;" & _ "dword SizeOfUninitializedData;" & _ "dword AddressOfEntryPoint;" & _ "dword BaseOfCode;" & _ "dword BaseOfData;" & _ "dword ImageBase;" & _ "dword SectionAlignment;" & _ "dword FileAlignment;" & _ "ushort MajorOperatingSystemVersion;" & _ "ushort MinorOperatingSystemVersion;" & _ "ushort MajorImageVersion;" & _ "ushort MinorImageVersion;" & _ "ushort MajorSubsystemVersion;" & _ "ushort MinorSubsystemVersion;" & _ "dword Win32VersionValue;" & _ "dword SizeOfImage;" & _ "dword SizeOfHeaders;" & _ "dword CheckSum;" & _ "ushort Subsystem;" & _ "ushort DllCharacteristics;" & _ "dword SizeOfStackReserve;" & _ "dword SizeOfStackCommit;" & _ "dword SizeOfHeapReserve;" & _ "dword SizeOfHeapCommit;" & _ "dword LoaderFlags;" & _ "dword NumberOfRvaAndSizes", _ $pPointer) ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER Local $iMagic = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "Magic") ; Check if it's 32-bit application If $iMagic <> 267 Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(6, 0, 0) ; not 32-bit application. Structures (and sizes) are for 32-bit apps. EndIf If $test = 1 and $iMagic <> 267 Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return 0 EndIf ; Extract entry point address Local $iEntryPointNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "AddressOfEntryPoint") ; if loaded binary image would start executing at this address ; Move pointer $pPointer += 128 ; size of the structures before IMAGE_SECTION_HEADER (16 of them - find PE specification if you are interested). Local $pOptionalHeaderImageBaseNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "ImageBase") ; address of the first byte of the image when it's loaded in memory Local $iOptionalHeaderSizeOfImageNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfImage") ; the size of the image including all headers #Region 5. GET AND THEN CHANGE BASE ADDRESS ; Read base address Local $tPEB = DllStructCreate("byte InheritedAddressSpace;" & _ "byte ReadImageFileExecOptions;" & _ "byte BeingDebugged;" & _ "byte Spare;" & _ "ptr Mutant;" & _ "ptr ImageBaseAddress;" & _ "ptr LoaderData;" & _ "ptr ProcessParameters;" & _ "ptr SubSystemData;" & _ "ptr ProcessHeap;" & _ "ptr FastPebLock;" & _ "ptr FastPebLockRoutine;" & _ "ptr FastPebUnlockRoutine;" & _ "dword EnvironmentUpdateCount;" & _ "ptr KernelCallbackTable;" & _ "ptr EventLogSection;" & _ "ptr EventLog;" & _ "ptr FreeList;" & _ "dword TlsExpansionCounter;" & _ "ptr TlsBitmap;" & _ "dword TlsBitmapBits[2];" & _ "ptr ReadOnlySharedMemoryBase;" & _ "ptr ReadOnlySharedMemoryHeap;" & _ "ptr ReadOnlyStaticServerData;" & _ "ptr AnsiCodePageData;" & _ "ptr OemCodePageData;" & _ "ptr UnicodeCaseTableData;" & _ "dword NumberOfProcessors;" & _ "dword NtGlobalFlag;" & _ "ubyte Spare2[4];" & _ "int64 CriticalSectionTimeout;" & _ "dword HeapSegmentReserve;" & _ "dword HeapSegmentCommit;" & _ "dword HeapDeCommitTotalFreeThreshold;" & _ "dword HeapDeCommitFreeBlockThreshold;" & _ "dword NumberOfHeaps;" & _ "dword MaximumNumberOfHeaps;" & _ "ptr ProcessHeaps;" & _ "ptr GdiSharedHandleTable;" & _ "ptr ProcessStarterHelper;" & _ "ptr GdiDCAttributeList;" & _ "ptr LoaderLock;" & _ "dword OSMajorVersion;" & _ "dword OSMinorVersion;" & _ "dword OSBuildNumber;" & _ "dword OSPlatformId;" & _ "dword ImageSubSystem;" & _ "dword ImageSubSystemMajorVersion;" & _ "dword ImageSubSystemMinorVersion;" & _ "dword GdiHandleBuffer[34];" & _ "dword PostProcessInitRoutine;" & _ "dword TlsExpansionBitmap;" & _ "ubyte TlsExpansionBitmapBits[128];" & _ "dword SessionId") $aCall = DllCall("kernel32.dll", "int", "ReadProcessMemory", _ "ptr", $hProcess, _ "ptr", DllStructGetData($tCONTEXT, "Ebx"), _ "ptr", DllStructGetPtr($tPEB), _ "dword", DllStructGetSize($tPEB), _ "dword*", 0) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(7, 0, 0) ; ReadProcessMemory function or call to it failed while filling PEB structure EndIf Local $hBaseAddress = DllStructGetData($tPEB, "ImageBaseAddress") ; Short version of the above #cs $aCall = DllCall("kernel32.dll", "int", "ReadProcessMemory", _ "ptr", $hProcess, _ "ptr", DllStructGetData($tCONTEXT, "Ebx") + 8, _ "ptr*", 0, _ "dword", 4, _ "dword*", 0) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(7, 0, 0) ; ReadProcessMemory function or call to it failed while reading base address of the process EndIf Local $hBaseAddress = $aCall[3] #ce ; Write new base address $aCall = DllCall("kernel32.dll", "int", "WriteProcessMemory", _ "ptr", $hProcess, _ "ptr", DllStructGetData($tCONTEXT, "Ebx") + 8, _ "ptr*", $pOptionalHeaderImageBaseNEW, _ "dword", 4, _ "dword*", 0) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(8, 0, 0) ; WriteProcessMemory function or call to it failed while writting new base address EndIf #Region 6. CLEAR EVERYTHING THAT THIS NEW PROCESS HAVE MAPPED ; Clear old data. $aCall = DllCall("ntdll.dll", "int", "NtUnmapViewOfSection", _ "ptr", $hProcess, _ "ptr", $hBaseAddress) If @error Or $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(9, 0, 0) ; NtUnmapViewOfSection function or call to it failed EndIf #Region 7. ALLOCATE 'NEW' MEMORY SPACE ; Allocate proper size of memory at the proper place. $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _ "ptr", $hProcess, _ "ptr", $pOptionalHeaderImageBaseNEW, _ "dword", $iOptionalHeaderSizeOfImageNEW, _ "dword", 12288, _ ; MEM_COMMIT|MEM_RESERVE "dword", 64) ; PAGE_EXECUTE_READWRITE If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(10, 0, 0) ; VirtualAllocEx function or call to it failed EndIf Local $pRemoteCode = $aCall[0] ; from now on this is zero-point #Region 8. GET AND WRITE NEW PE-HEADERS Local $pHEADERS_NEW = DllStructGetPtr($tIMAGE_DOS_HEADER) ; starting address of binary image headers Local $iOptionalHeaderSizeOfHeadersNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfHeaders") ; the size of the MS-DOS stub, the PE header, and the section headers ; Write NEW headers $aCall = DllCall("kernel32.dll", "int", "WriteProcessMemory", _ "ptr", $hProcess, _ "ptr", $pRemoteCode, _ "ptr", $pHEADERS_NEW, _ "dword", $iOptionalHeaderSizeOfHeadersNEW, _ "dword*", 0) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(11, 0, 0) ; WriteProcessMemory function or call to it while writting new PE headers failed EndIf #Region 9. WRITE SECTIONS ; Dealing with sections. Will write them too as they hold all needed data that PE loader reads Local $tIMAGE_SECTION_HEADER Local $iSizeOfRawData, $pPointerToRawData Local $iVirtualAddress For $i = 1 To $iNumberOfSections $tIMAGE_SECTION_HEADER = DllStructCreate("char Name[8];" & _ "dword UnionOfVirtualSizeAndPhysicalAddress;" & _ "dword VirtualAddress;" & _ "dword SizeOfRawData;" & _ "dword PointerToRawData;" & _ "dword PointerToRelocations;" & _ "dword PointerToLinenumbers;" & _ "ushort NumberOfRelocations;" & _ "ushort NumberOfLinenumbers;" & _ "dword Characteristics", _ $pPointer) $iSizeOfRawData = DllStructGetData($tIMAGE_SECTION_HEADER, "SizeOfRawData") $pPointerToRawData = DllStructGetPtr($tIMAGE_DOS_HEADER) + DllStructGetData($tIMAGE_SECTION_HEADER, "PointerToRawData") $iVirtualAddress = DllStructGetData($tIMAGE_SECTION_HEADER, "VirtualAddress") ; If there is data to write, write it where is should be written If $iSizeOfRawData Then $aCall = DllCall("kernel32.dll", "int", "WriteProcessMemory", _ "ptr", $hProcess, _ "ptr", $pRemoteCode + $iVirtualAddress, _ "ptr", $pPointerToRawData, _ "dword", $iSizeOfRawData, _ "dword*", 0) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(12, $i, 0) ; WriteProcessMemory function or call to it while writting new sections failed EndIf EndIf ; Move pointer $pPointer += 40 ; size of $tIMAGE_SECTION_HEADER structure Next #Region 10. NEW ENTRY POINT ; Entry point manipulation DllStructSetData($tCONTEXT, "Eax", $pRemoteCode + $iEntryPointNEW) ; $iEntryPointNEW was relative address #Region 11. SET NEW CONTEXT ; New context: $aCall = DllCall("kernel32.dll", "int", "SetThreadContext", _ "ptr", $hThread, _ "ptr", DllStructGetPtr($tCONTEXT)) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(13, 0, 0) ; SetThreadContext function or call to it failed EndIf #Region 12. RESUME THREAD ; And that's it!. Continue execution $aCall = DllCall("kernel32.dll", "int", "ResumeThread", "ptr", $hThread) If @error Or $aCall[0] = -1 Then DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0) Return SetError(14, 0, 0) ; ResumeThread function or call to it failed EndIf #Region 13. RETURN SUCCESS ; All went well. Return, for example, new PID: Return DllStructGetData($tPROCESS_INFORMATION, "ProcessId") EndFunc1 point -
AutoIt v3.3.11.0 Beta
jaberwacky reacted to Jon for a topic
File Name: AutoIt v3.3.11.0 Beta File Submitter: Jon File Submitted: 03 Jan 2014 File Category: Beta 3.3.11.0 (3rd January, 2014) (Beta) AutoIt: - Fixed #2562: StringRegExp() & Null character. - Fixed #2581: Dec() wasn't working correctly for flags 0, 1, 2. - Fixed #2568: StringStripWS() and StringIsSpace() now treats null as a whitespace character. - Fixed #2566: "override" cursor in GUISetCursor() fails inside client area. - Fixed #2573: "override" cursor in GUISetCursor() fails outside of client area. - Added #2557: Send() special control strings will no longer treat 0 repetitions as 1. No keys will be sent. - Added #2489: HttpSetUserAgent() now returns the previous user agent string. - Added #2481: FileSelectFolder() will use the Windows Vista style if available. - Changed: PCRE regular expression engine updated to 8.34. UDFs: - Added: Error checking to _ArrayDelete() when $iElement was out of bounds. - Removed: Usage of Call() in _FTP_ProgressDownload(), _FTP_ProgressUpload() and _SQLite_Startup(). See documentation for changes to $hFunctionCall and $hPrintCallback parameters. THIS IS A SCRIPT BREAKING CHANGE. Others: - Added: Keywords and Macros to the Notepad++ autoit.xml file. Notes for Windows 8 Users When multiple programs register the same file associations (Stable+beta) then we can no longer toggle between beta and stable versions programatically. You must select a .au3 file, right-click and choose "open with", then "choose default program" and select beta or stable. Use the following script to verify which version you are running: MsgBox(0, "Version", @AutoItVersion) Click here to download this file1 point -
guinness you right. @boththose If you want a backwards compatible _RegExpStringBetween() function, try this one : Func _RegExpStringBetween($sString, $sStart, $sEnd, $fCase = False) ; Set correct case sensitivity If $fCase = Default Then $fCase = False EndIf Local $sCase = "(?is)" If $fCase Then $sCase = "(?s)" EndIf $sStart = StringRegExp($sString, $sStart, 1)[0] If @error Then Return SetError(1, 0, False) $sEnd = StringRegExp($sString, $sEnd, 1)[0] If @error Then Return SetError(2, 0, False) ; If you want data from beginning then replace blank start with beginning of string If $sStart = "" Then $sStart = "\A" Else $sStart = "\Q" & $sStart & "\E" EndIf ; If you want data from a start to an end then replace blank with end of string If $sEnd = "" Then $sEnd = "\z" Else $sEnd = "(?=\Q" & $sEnd & "\E)" EndIf Local $aReturn = StringRegExp($sString, $sCase & $sStart & "(.*?)" & $sEnd, 3) If @error Then Return SetError(3, 0, 0) Return $aReturn EndFunc1 point
-
Drawing Individual Pixels
jaberwacky reacted to iamtheky for a topic
This function is all over the place. So your Lua skills may be legit, but your search skills suck. Func _PixelSetColor($XCoord, $YCoord, $Color) Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0) If Not IsArray($dc) Then Return -1 DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $XCoord, "long", $YCoord, "long", _ "0x" & StringRegExpReplace(hex($Color,6), "(..)(..)(..)", "\3\2\1")) ; Change to 0xBBGGRR hex colour format. DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0]) EndFunc ;==>_PixelSetColor1 point -
Need for Speed (Array too Slow), because of ReDim (??)
michaelslamet reacted to mikell for a topic
This ? #include <array.au3> #include <date.au3> Opt("TrayIconDebug", 1) Local $tdata, $arr ; generate data for testing For $1 = 1 to 2000 $tdata &= 'user' & stringformat('%04i',random(1,1000,1)) & ' :: ' & 'www.' for $2 = 1 to random(5,16,1) $tdata &= chr(random(97,122,1)) Next $tdata &= '.com :: ' $tdata &= _dateadd('D',random(-365,365,1),_NowCalcDate()) $tdata &= ' :: ' & random(1000,100000,1) $tdata &= ' :: ' & random(1000,100000,1) $tdata &= ' :: ' & random(1000,100000,1) $tdata &= ' :: ' & random(1000,100000,1) $tdata &= ' :: ' & random(1000,100000,1) & @LF Next ; ==> generate data for testing local $st = timerinit() Local $arr StringSplit2D ($tdata, $arr, @LF, "::") ConsoleWrite(stringformat('Time to run %03i records = %2.4f',$1-1,timerdiff($st)/1000) & @lf) ;msgbox(0,"", stringformat('Time to run %03i records = %2.4f',$1-1,timerdiff($st)/1000)) _ArrayDisplay($arr) Func StringSplit2D($string, ByRef $aArray, $aDelim1 = @crlf, $aDelim2 = ";") $string = StringStripWS($string, 3) Local $aTemp, $aSplit, $iRows, $iCols $aTemp = StringSplit($string, $aDelim1, 3) $iRows = UBound($aTemp) $iCols = 1 Dim $aArray[$iRows][$iCols] For $i = 0 to $iRows-1 $aSplit = StringSplit($aTemp[$i], $aDelim2, 3) If $iCols < UBound($aSplit) Then $iCols = UBound($aSplit) Redim $aArray[$iRows][$iCols] EndIf For $j = 0 to UBound($aSplit)-1 $aArray[$i][$j] = $aSplit[$j] Next Next EndFunc Edit : added StringStripWS1 point -
No functionality would be lost. I explained how and why.1 point
-
johnmcloud, When you compile you get the entire AutoIt interpreter every time - whether you use everything in it or not. So in most cases it is certainly not the case that "all the 1024KB are totally necessary for the proper functioning of the executable" - but remember that any compiled AutoIt executable can run other AutoIt scripts which might have additional functions within them. For some time there has been a "Not ToDo List" on Trac which states: Modularized Compilation/variable sized compiled files: There are no plans to break AutoIt into components so that compiling a script will be smaller by only containing the components being used instead of everything. There are a couple reasons for this. First, it's a technological nightmare to implement. Second, it breaks any form of dynamic code. Features like Execute(), /AutoIt3ExecuteLine and /AutoIt3ExecuteScript would be broken. Having each compiled script capable of acting as a full-interpreter is a very powerful feature. Also, regardless of the size of a compiled file, remember that you still get a stand-alone product with no run-time dependencies outside what the operating system provides. A little size is a small price to pay. trancexx suggested recently that removing "unused" parts of the interpreter might not be too difficult technically, but given the loss of the functionality mentioned in that quote, it would not in my opinion be sensible. M231 point
-
The entire interpreter is always contained in compiled exes. The advantages of this are quite cool, you can run any script using any other compiled script, and you can use functions like Execute() in your code. Without removing those two features, it is not really possible to change this behaviour.1 point
-
Any changes made to SciTE should be done to SciTEUser.Properties and not SciTEGlobal.properties, as the global file is overwritten on every new installation. In SciTEUser.Properties add the property code.page=65001 Values from: http://www.scintilla.org/SciTEDoc.html1 point
-
AutoIt Snippets
jaberwacky reacted to Tlem for a topic
Hi jaberwocky6669, great function. If I open my eyes, based to your function and source code of _StringBetween(), I can wrote this one, for older version of AutoIt and without including File.au3. Func _RegExpStringBetween($sString, $sStart, $sEnd, $fCase = False) $sStart = StringRegExp($sString, $sStart, 1)[0] If @error Then Return SetError(1, 0, False) $sEnd = StringRegExp($sString, $sEnd, 1)[0] If @error Then Return SetError(2, 0, False) ; Set correct case sensitivity If $fCase = Default Then $fCase = False EndIf Local $sCase = "(?is)" If $fCase Then $sCase = "(?s)" EndIf ; If you want data from beginning then replace blank start with beginning of string $sStart = $sStart ? "\Q" & $sStart & "\E" : "\A" ; If you want data from a start to an end then replace blank with end of string $sEnd = $sEnd ? "(?=\Q" & $sEnd & "\E)" : "\z" Local $aReturn = StringRegExp($sString, $sCase & $sStart & "(.*?)" & $sEnd, 3) If @error Then Return SetError(3, 0, 0) Return $aReturn EndFunc1 point -
NotePad++ with AutoIt User CallTips ...
jaberwacky reacted to guinness for a topic
By the way, I added Keywords, Macros and Directives to the file. <KeyWord name='And' /> <KeyWord name='ByRef' /> <KeyWord name='Case' /> <KeyWord name='Const' /> <KeyWord name='ContinueCase' /> <KeyWord name='ContinueLoop' /> <KeyWord name='Default' /> <KeyWord name='Dim' /> <KeyWord name='Do' /> <KeyWord name='Else' /> <KeyWord name='ElseIf' /> <KeyWord name='EndFunc' /> <KeyWord name='EndIf' /> <KeyWord name='EndSelect' /> <KeyWord name='EndSwitch' /> <KeyWord name='EndWith' /> <KeyWord name='Enum' /> <KeyWord name='Exit' /> <KeyWord name='ExitLoop' /> <KeyWord name='False' /> <KeyWord name='For' /> <KeyWord name='Func' /> <KeyWord name='Global' /> <KeyWord name='If' /> <KeyWord name='In' /> <KeyWord name='Local' /> <KeyWord name='Next' /> <KeyWord name='Not' /> <KeyWord name='Null' /> <KeyWord name='Or' /> <KeyWord name='ReDim' /> <KeyWord name='Return' /> <KeyWord name='Select' /> <KeyWord name='Static' /> <KeyWord name='Step' /> <KeyWord name='Switch' /> <KeyWord name='Then' /> <KeyWord name='To' /> <KeyWord name='True' /> <KeyWord name='Until' /> <KeyWord name='Volatile' /> <KeyWord name='WEnd' /> <KeyWord name='While' /> <KeyWord name='With' /> <KeyWord name='#ce' /> <KeyWord name='#comments-end' /> <KeyWord name='#comments-start' /> <KeyWord name='#cs' /> <KeyWord name='#include' /> <KeyWord name='#include-once' /> <KeyWord name='#NoTrayIcon' /> <KeyWord name='#OnAutoItStartRegister' /> <KeyWord name='#RequireAdmin' /> <KeyWord name='#EndRegion' /> <KeyWord name='#forcedef' /> <KeyWord name='#forceref' /> <KeyWord name='#ignorefunc' /> <KeyWord name='#pragma' /> <KeyWord name='#Region' /> <KeyWord name='@AppDataCommonDir' /> <KeyWord name='@AppDataDir' /> <KeyWord name='@AutoItExe' /> <KeyWord name='@AutoItPID' /> <KeyWord name='@AutoItVersion' /> <KeyWord name='@AutoItX64' /> <KeyWord name='@COM_EventObj' /> <KeyWord name='@CommonFilesDir' /> <KeyWord name='@Compiled' /> <KeyWord name='@ComputerName' /> <KeyWord name='@ComSpec' /> <KeyWord name='@CPUArch' /> <KeyWord name='@CR' /> <KeyWord name='@CRLF' /> <KeyWord name='@DesktopCommonDir' /> <KeyWord name='@DesktopDepth' /> <KeyWord name='@DesktopDir' /> <KeyWord name='@DesktopHeight' /> <KeyWord name='@DesktopRefresh' /> <KeyWord name='@DesktopWidth' /> <KeyWord name='@DocumentsCommonDir' /> <KeyWord name='@error' /> <KeyWord name='@exitCode' /> <KeyWord name='@exitMethod' /> <KeyWord name='@extended' /> <KeyWord name='@FavoritesCommonDir' /> <KeyWord name='@FavoritesDir' /> <KeyWord name='@GUI_CtrlHandle' /> <KeyWord name='@GUI_CtrlId' /> <KeyWord name='@GUI_DragFile' /> <KeyWord name='@GUI_DragId' /> <KeyWord name='@GUI_DropId' /> <KeyWord name='@GUI_WinHandle' /> <KeyWord name='@HomeDrive' /> <KeyWord name='@HomePath' /> <KeyWord name='@HomeShare' /> <KeyWord name='@HotKeyPressed' /> <KeyWord name='@HOUR' /> <KeyWord name='@IPAddress1' /> <KeyWord name='@IPAddress2' /> <KeyWord name='@IPAddress3' /> <KeyWord name='@IPAddress4' /> <KeyWord name='@KBLayout' /> <KeyWord name='@LF' /> <KeyWord name='@LocalAppDataDir' /> <KeyWord name='@LogonDNSDomain' /> <KeyWord name='@LogonDomain' /> <KeyWord name='@LogonServer' /> <KeyWord name='@MDAY' /> <KeyWord name='@MIN' /> <KeyWord name='@MON' /> <KeyWord name='@MSEC' /> <KeyWord name='@MUILang' /> <KeyWord name='@MyDocumentsDir' /> <KeyWord name='@NumParams' /> <KeyWord name='@OSArch' /> <KeyWord name='@OSBuild' /> <KeyWord name='@OSLang' /> <KeyWord name='@OSServicePack' /> <KeyWord name='@OSType' /> <KeyWord name='@OSVersion' /> <KeyWord name='@ProgramFilesDir' /> <KeyWord name='@ProgramsCommonDir' /> <KeyWord name='@ProgramsDir' /> <KeyWord name='@ScriptDir' /> <KeyWord name='@ScriptFullPath' /> <KeyWord name='@ScriptLineNumber' /> <KeyWord name='@ScriptName' /> <KeyWord name='@SEC' /> <KeyWord name='@StartMenuCommonDir' /> <KeyWord name='@StartMenuDir' /> <KeyWord name='@StartupCommonDir' /> <KeyWord name='@StartupDir' /> <KeyWord name='@SW_DISABLE' /> <KeyWord name='@SW_ENABLE' /> <KeyWord name='@SW_HIDE' /> <KeyWord name='@SW_LOCK' /> <KeyWord name='@SW_MAXIMIZE' /> <KeyWord name='@SW_MINIMIZE' /> <KeyWord name='@SW_RESTORE' /> <KeyWord name='@SW_SHOW' /> <KeyWord name='@SW_SHOWDEFAULT' /> <KeyWord name='@SW_SHOWMAXIMIZED' /> <KeyWord name='@SW_SHOWMINIMIZED' /> <KeyWord name='@SW_SHOWMINNOACTIVE' /> <KeyWord name='@SW_SHOWNA' /> <KeyWord name='@SW_SHOWNOACTIVATE' /> <KeyWord name='@SW_SHOWNORMAL' /> <KeyWord name='@SW_UNLOCK' /> <KeyWord name='@SystemDir' /> <KeyWord name='@TAB' /> <KeyWord name='@TempDir' /> <KeyWord name='@TRAY_ID' /> <KeyWord name='@TrayIconFlashing' /> <KeyWord name='@TrayIconVisible' /> <KeyWord name='@UserName' /> <KeyWord name='@UserProfileDir' /> <KeyWord name='@WDAY' /> <KeyWord name='@WindowsDir' /> <KeyWord name='@WorkingDir' /> <KeyWord name='@YDAY' /> <KeyWord name='@YEAR' />1 point -
This is not remotely close to a game....but you are circumventing an entire country's TOS, which should be encouraged and supported with all efforts. https://trac.torproject.org/projects/tor/ticket/10472 looks like there is a small patch to allow command line arguments to passthrough, i would go that route before trying to dance around GUIs with send commands.1 point
-
Why would that be? I have written scripts larger than that, no includes, no resources, no nothing.1 point
-
how to write chinese letters in autoit Editor
Factfinder reacted to BrewManNH for a topic
Don't be so impatient, wait at least 24 hours before bumping. Also, look in the File menu of SciTE for Encoding, should fix it.1 point -
Neither do I, or AZJIO or mlipok or Melba23 or any of the MVPs or anyone actually apart from Jon, but submitting bug reports, making suggestions and just being a positive user is how you can contribute to AutoIt. Shame really.1 point
-
Thanks D4RKON3. I will have a look at the problem in the next couple of days.1 point
-
The main reason why ability to #include a3x-es was added was to move number of built-in functions from compiled binaries (raw .bin interpreters used by the compiler) into precompiled private au3 files. The idea was to extend and use pragmatic directives to "include" needed precompiled files/functions. To me it never made sense why compiled executable should include all built-in functions even though they were never used by user's code. Considering AutoIt is dllcall capable and also since some time works with all kind of objects either late or early bound, all preconditions for the idea were made. Really large number of functions can be taken out of the binary stub with no performance hits. Functions like Beep, Mouse..., Reg..., Tcp, Udp, and tens of others which aren't any faster because of being part of the binary code. Of course that some functions can't be taken out, for example Adlibs or some that do lots of calculation like Pixel-whatever but large number of others are very good candidates. Anyway, the idea was to do something like this: #pragma use(socket) TCPStartup() ;... ...and in case of au3 script which is run by AutoIt.exe TCP functions would be built-in (even not necessary) and in case of compiled executable Aut2Exe would add needed a3x code with functions written for it in simple easily maintainable AutoIt code. This way the size of compiled executables would really depend just on set used functions plus absolute minimum interpreter needs and wouldn't have burden of unnecessary code. Pragma directive would be mandatory for code that uses Execute or some other run-string function, but for "normal" code it can even be dropped out because compiler can detect used functions itself.1 point
-
Mikrotik Web Proxy White & Black List Import
Cahkhene25 reacted to bhns for a topic
Hello, Mikrotik Web Proxy White & Black List Import Tanks forum autoit... contribuited my script BlaclistImportMK #include<GuiComboBox.au3> #include<GUIConstantsEx.au3> #include<Constants.au3> #include<File.au3> #include<Array.au3> #include<ButtonConstants.au3> #include<ComboConstants.au3> #include<EditConstants.au3> #include<StaticConstants.au3> #include<WindowsConstants.au3> local $black_file, $coments, $rediretions, $export_list_type $data = ("" & @MDAY & "/" & @MON & "/" & @YEAR) $horario = ("" & @HOUR & ":" & @MIN & ":" & @SEC) $nomeComputador = @ComputerName $usuarioLogado = @UserName Local $MyDocsFolder = "::{450D8FBA-AD25-11D0-98A8-0800361B1103}" #Region ### START Koda GUI section ### Form=c:\dados\mikrotik _projects\import_to_export.kxf $Form1 = GUICreate("Export to Mikrotik by BHNS", 361, 396, 410, 220) $blacklist = GUICtrlCreateGroup("IMPORT BLACKLIST", 46, 40, 265, 81) $Button1 = GUICtrlCreateButton("Import", 128, 70, 107, 33) GUICtrlCreateGroup("", -99, -99, 1, 1) $mikrotik = GUICtrlCreateGroup("EXPORT TO MIKROTIK", 46, 136, 265, 177) $coment_ = GUICtrlCreateInput("--------------COMMENT-------------", 162, 168, 121, 21) $action_lab = GUICtrlCreateLabel("Action :", 120, 201, 40, 17) $list_name = GUICtrlCreateLabel("Coment Name List :", 63, 170, 96, 17) $redire_label = GUICtrlCreateLabel("Redirection to :", 84, 234, 76, 17) $redrection_out = GUICtrlCreateInput("google.com.br", 162, 232, 121, 21) $Combo1 = GUICtrlCreateCombo("Select", 162, 199, 121, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Allow|Deny|Deny + Redirecti|", "Deny + Redirecti") $Label3 = GUICtrlCreateLabel("SubDomains :", 88, 269, 70, 17) $Radio1 = GUICtrlCreateRadio("Yes", 173, 269, 57, 17) $Radio2 = GUICtrlCreateRadio("No", 232, 269, 57, 17) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateGroup("", -99, -99, 1, 1) $bt_gerar = GUICtrlCreateButton("Export", 93, 325, 75, 25) $bt_exit = GUICtrlCreateButton("Exit", 189, 325, 75, 25) $Label1 = GUICtrlCreateLabel("clebe@live.com", 272, 376, 80, 17) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $bt_exit Exit Case $Button1 Local $MyDocsFolder = "::{450D8FBA-AD25-11D0-98A8-0800361B1103}" Local $message = "Hold down Ctrl or Shift to choose multiple files." Local $var = FileOpenDialog($message,$MyDocsFolder & "\", "Files (*.txt;*.*)", 1 + 4) If @error Then MsgBox(4096, "Erro", "No File(s) chosen") Else $var = StringReplace($var, "|", @CRLF) MsgBox(4096, "", "You chose " & $var) EndIf Case $bt_gerar $export_list_type = GUICtrlRead($Combo1) $coments = GUICtrlRead($coment_) $rediretions = GUICtrlRead($redrection_out) ; "Allow|Deny|Deny + Redirecti|", "Deny + Redirecti") Select Case GUICtrlRead($Radio1) = $GUI_CHECKED $opt_select = "*" Case GUICtrlRead($Radio2) = $GUI_CHECKED $opt_select = "" EndSelect export_mikrotik () EndSwitch WEnd Func export_mikrotik () $black_file = $var ; Multiple filter group $salv_file = FileSaveDialog("Export.", $MyDocsFolder, " Text files (*.ini;*.txt)", 2) ; option 2 = dialog remains until valid path/file selected If @error Then MsgBox(4096, "", "Exiting.") exit EndIf ; Check if file opened for writing OK If $black_file = -1 Then MsgBox(0, "Error", "Não foi possivel abrir o arquivo.") Exit EndIf ProgressOn ( "Criando Export", "Adicioando Conteudo" , "" , -1 , -1 , 18) ; ; Sample export Mikrotik ; add action=allow disabled=yes dst-host=*gmail* dst-port="" $ganb = '"' FileWriteLine($salv_file, "# "&$data&" "&$horario&" by "&$usuarioLogado&" "&$nomeComputador&" RouterOS 5.X.X" & @CRLF) FileWriteLine($salv_file, '# Arquivo carregado '& $ganb& $black_file& $ganb&''& @CRLF) FileWriteLine($salv_file, "# " & @CRLF) FileWriteLine($salv_file, "#" & @CRLF) FileWriteLine($salv_file, "#" & @CRLF) FileWriteLine($salv_file, "#" & @CRLF) FileWriteLine($salv_file, "/ip proxy access" & @CRLF) FileWriteLine($salv_file, 'add action=allow comment='&$ganb&$coments&$ganb&' disabled=no dst-host=1 dst-port="" '& @CRLF) ;FileWriteLine($salv_file, "add action=allow disabled=yes dst-host=*"&$linein&" dst-port=""" & @CRLF) $inifile = FileOpen($black_file, 0) $totallines = 0 While 1 FileReadLine($inifile) If @error = -1 Then ExitLoop $totallines += 1 WEnd $sectionstartline = 1 ; First line of the section in the ini $startvalue = 1 ;Start number for GUI $totallines = ($totallines - $sectionstartline) + $startvalue While 1 $linein = FileReadLine($inifile, $sectionstartline) If @error = -1 Then ExitLoop if $export_list_type = 'Allow' then ; add action=allow disabled=yes dst-host=*gmail* dst-port="" FileWriteLine($salv_file, 'add action=allow disabled=no dst-host='&$opt_select&$linein&' dst-port=""'& @CRLF) elseif $export_list_type = 'Deny' then ; add action=allow disabled=yes dst-host=*gmail* dst-port="" FileWriteLine($salv_file, 'add action=deny disabled=no dst-host='&$opt_select&$linein&' dst-port=""' & @CRLF) elseif $export_list_type = 'Deny + Redirecti' then ; add action=allow disabled=yes dst-host=*gmail* dst-port="" FileWriteLine($salv_file, 'add action=deny disabled=no dst-host='&$opt_select&$linein&' dst-port="" redirect-to='&$rediretions&' '& @CRLF) Endif ; add action=allow disabled=yes dst-host=*gmail* dst-port="" ; FileWriteLine($salv_file, "add action=allow disabled=yes dst-host=*"&$linein&" dst-port=""" & @CRLF) ;ConsoleWrite($startvalue & '/' & $totallines & @CRLF) ;If StringInStr($linein, '=') Then ; $infosplit = StringSplit($linein, '=') ; _AddRecord($DB, $DBTABLE, $DBOBJ, StringUpper($infosplit[1]) & '|' & $infosplit[2]) ;EndIf $UpdatePercentDone = ($startvalue / $totallines) * 100 ProgressSet($UpdatePercentDone, $linein, "Adding domains: " & $startvalue & '/' & $totallines) $sectionstartline += 1 $startvalue += 1 WEnd FileWriteLine($salv_file, "# Arquivo Gerado com Sucesso... by BHNS" & @CRLF) FileClose($startvalue) ProgressOff() MsgBox(0, "OK", "Script Gerado com Sucesso") EndFunc1 point -
MAC Address Stuff
Cahkhene25 reacted to Mechaflash for a topic
Thanks to I created a self-contained MAC Address-getter for the local host. Not sure if someone has a better way of doing it. Searched for information on how to query the MAC address, found the example, but it required an input (the ip address or hostname). I wanted to bypass this requirement. Also one of my first times having to utilize StringRegExp()... so not sure if they are at their simplest forms. Also thanks to guinness for _RunStdOutRead(). Extremely useful. EDIT: Removed the parameter for _GetLocalMAC(). Separated tracert execution into its own function. EDIT2: Changed _Localhost() to returns the IP without additional processing if the IP instead of a hostname resolves. EDIT3: This example accepts FQDNs and IPs and differentiates between the a localhost call and all others. Some error handling included. Lan/Wan1 point