Jump to content

Smuggling AutoIt into IE embedded

Recommended Posts

In my >previous adventures, I got a bare-bones AutoIt proxy object injected into MSScriptControl.ScriptControl.

The proxy had just enough functionality that a basic form application could be coded from Javascript. That was kind of fun but the ScriptControl is old and iffy, its environment is like using an old version of JScript, sometimes mere comments would trigger non-compilation.

What would be really good is to get a full-fledged proxy injected into IE, so that you had ECMA5-ish language features and a more stable platform. I had no idea how to do this though, so I was shocked when it worked, which is why I call it 'smuggling'.

Once you had a decked out proxy in there, you could code your entire app in Js, and use IE as a GUI (or not). I am most interested in coding in an OOP language, so that is what is driving my attempts.

Long story short, it worked. So now I have an initial framework for doing this, and I put together this stress test of an application and demo.

The clip from the header:

;  Name: Jsaioie -- Javascript, AutoItObject, Internet Explorer
;  This is an advanced demo of using an embedded IE control as a GUI.
;  What is noteworthy is that the main application code is in javascript, which makes calls
;  to core AutoIt functions via an imported AutoItObject which has been constructed.
;  This means that virtually all of the application can be coded as JS, which means OOP.
;  JS OOP is really not demonstrated here within this demo however.
;  What is demonstrated in the JS code is how JS can be persuaded to behave asynch, and emulate
;  a threaded application.
;  When the application starts, it will analyze all the files in the users AutoIt include directory in order
;  to build a series of collapsable divs with information on the constants and functions found.
;  While this process is occuring, the UI is still relatively responsive, and you can watch the nested div
;  items being added, or even filter them while it is loading.
;  The application will pick up about 14k identifiers from the include directory, each having its own div
;  and tt tag containing documentation. Some research shows that IE8 has problems when the div count exceeds
;  1000, but I am using IE 10. Your results will depend on your IE version. It is said that IE9+ should have
;  not much problem with 100k divs. The real lag is filtering them, which could be optimized.
;  Parsing the files, loading and building html and listeners for 14k items takes 5.5 minutes on my machine.
;  That breaks down to 42 items per second, or 24k bytes per second. Tweaking seems to have no effect. The
;  goal is to keep the thing responsive during load, the html I mean, but the application will hourglass
;  when it encounters the bigger files, probably a IO thing.
;  The application consists of the following files:
;   Jsaioie.au3         - Backbone code file
;   Jsaioie.au3.ini     - Config, will be created
;   Jsaioie.au3.js      - Application code
;   Jsaioie.au3.html    - Simple html skeleton
;   Jsaio-inc-AiFn.au3  - Constructs the AutoIt proxy AutoItObject
;   Jsaio-utils.au3     - Some misc utils
;   jquery-1.10.2.js    - For dom manipulation
;   Jsaioie.au3.log.txt - Output log for debugging
;   Jsaio-loaded.js     - A preview of the javascipt to be loaded after preprocessing
;   1. $AutoItForCom AutoItObject is created and core AutoIt functionality appended to it
;   2. Small amount of application specific functionality is also appended
;   3. Form with Embedded IE constructed
;   4. Html is constructed from assets, preprocessed and injected into IE
;   5. $AutoItForCom is injected into IE (the real magic part)
;   6. Javascript init() function is called which grabs the injected $AutoItForCom and assigns it to window.A var
;   7. Javascript Main() function is called which begins the application
;   1. Getting file list from include directory
;   2. Getting file contents
;   3. Logging
;   4. Running a specified editor to edit file
;   5. Placing text on clipboard
;   6. Reading config ini
;   7. Browse for folder
;   8. Browse for file
;   9. Getting ScriptFullPath
;  10. Checking @Error
;    1. Dynamic html nested accordian browser
;    2. Filter for file, or for identifier
;    3. Up Down, Page Up Page Down keys while in filter boxes will scroll document
;    4. Clear filter will collapse all
;    5. Click on Icon to copy signatures to clip
;    6. Unfold Items to see documentation if exists
;    7. Click on file link to edit file
;    8. Specify your editor, saved in config
;    9. Specify your include dir, saved in config
;   10. Asynch loading, file icons change color
;   This is not intended to be a finished app, but a stess test and demo. A lot of the JS coding has been
;   unrolled and exposed in a simplistic manner for illustration purposes. Familiarity with Javascript and
;   jQuery are neccessary for understanding how the application works. All the AutoIt code is essentially
;   a framework so that it is possible to code the app in the browser, and have access to autoit.

And a pretty pic:


And the zip:



Link to post
Share on other sites

This >old project use ScriptControl, but already has wrapper for AutoIt and JScript to communicate with ease (calling methods, passing variables, arrays etc). The bridge is closure compiled but the unpacked version is included, hopefully readable :)
And FYI Chakra JScript Engine can be used directly without ScriptControl nor IE, see here for hint, use Chakra's GUID instead.

Link to post
Share on other sites

This >old project use ScriptControl, but already has wrapper for AutoIt and JScript to communicate with ease (calling methods, passing variables, arrays etc). The bridge is closure compiled but the unpacked version is included, hopefully readable :)

And FYI Chakra JScript Engine can be used directly without ScriptControl nor IE, see here for hint, use Chakra's GUID instead.


Yes. Your code is what got me started! I even made a helper so that you can set the property of an AutoItObject using a property name string : >Index into an AutoItObject? Back then I was just using the JSOs for Assoc Arrays.

I tried to get AIO proxy into Moz, but it wouldn't accept the same technique.

Is Chakra the same obj as ScriptControl, or a newer version. My coding experience with ScriptControl has been too full of gotchas for me to use it.

Long term, what needs to be done is wrap the imported AutoIt proxy with OO oriented facade, so all the AI UI controls can be dealt with as objects. Then the entire app can be coded in Js. Though moving across com has a slight delay, my testing shows that Js is going to be much faster as an overall language.

Can you give any pointers as to capturing Js errors, and debugging? That part seems really bad, especially when you have a syntax error in js.

Link to post
Share on other sites

I tried to get AIO proxy into Moz, but it wouldn't accept the same technique.


If you refer Mozilla Firefox then we can't use AIO with javascript other than IE.

Is Chakra the same obj as ScriptControl


Chakra (used since IE9) is the core JS engine, M$ Active Scripting version of V8. ScriptControl and IE are Active Scripting Hosts, where you can select the engine you like (JS, VB, Python, etc).

But Chakra by default is not visible to ScriptControl, only for IE. By implementing IActiveScriptSite you can instantiate it.

You can make script host wrapper dll for AutoIt, or implement it directly (yes AutoIt CAN implement Interface :) ) I'm onto the later but my responsibilities lately hold me from messing with the idea.

Can you give any pointers as to capturing Js errors, and debugging? That part seems really bad, especially when you have a syntax error in js.


Try google for 'javascript stacktrace', to get detailed info about exception/error thrown. As for syntax checking you can first pass the code into JSLint or similar.

Good luck digging :)

Link to post
Share on other sites
  • 1 month later...

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Pured
      I am looking to create a script which refreshes/reads a webpage every few seconds. My goal is to see if the page has changed, then I will send myself a notification that the webpage has been updated.
      However, rather than downloading the entire webpage every single time, is there a way to check when the webpage last updated?
      If not, is there away to partially download/read html source until a specific tag is hit?
      Goal: I would like to increase my poll rate and not excessively waste data.
    • By SEuBo
      Hi there,
      while I created an example script to generate and execute a function during runtime, I stumbled across a neat way to share data between running autoit scripts.
      This is done using the amazing magic of  AutoItObject_Internal . (You'll need at least Version 3.0.0 of AutoItObject_Internal)
      Using this UDF, you can create a shared data storage, basically an empty "AutoitObject_Internal-"Object which you can then use to write / read data Inline. no set/get methods, just
      #include "AutoItSharedData.au3" $oShare = _AutoIt_SharedData_CreateOrAttach("MyCustomID") $oShare.some_data = 'foo' and you're done. any other script accessing this data will have to do:
      #include "AutoItSharedData.au3" $oShare = _AutoIt_SharedData_CreateOrAttach("MyCustomID") ConsoleWrite($oShare.some_data & @LF)  
      Basically it's Larsj's Implementing IRunningObjectTable Interface, but you dont have a Dictionary, but an IDIspatch Object instead.
      There are already a bunch of IPC options available - and this is another one.
      Example Script 1
      Example Script 2
      To test: run Example Script 1, Then run example Script 2.. or the other way around.
      Example Script 3
      To test: run Example_sharedata3.au3.
       Example SharedData4:
      /Edit: Please note that there's a limitation with the Running object table :
      The Script accessing a variable first, will be the "server" for this variable. This means, access to that variable from other scripts should only be possible, as long the "server" script is running! Use appropriate Object Error handlers in case you don't want the surviving "clients" to crash.
      Feedback and/or improvements appreciated
      version 2.0
      Removed need for AutoItObject, as AutoItObject_Internal now comes with ROT support Added UDF Header Fixed typo on "#include AutoItObjectInternal.au3" -> "#include AutoItObject_Internal.au3" Added ObjGet() after registering the object fails (in case 2 programs tried to register the same ID simultaneously) Updated Examples & zip archive. Cheers,
    • By mLipok
      In the past there was many questions about how to: "Automatic file upload using without user interaction"

      I found solution here: 
      And I translate this code to AutoIt3 code:
      ; Upload file using http protocol And multipart/form-data ; v1.01 ; 2001 Antonin Foller, PSTRUH Software Global $oErrorHandler = ObjEvent("AutoIt.Error", _ErrFunc) do_vbsUpload() Func do_vbsUpload() #cs ; We need at least two arguments (File & URL) ConsoleWrite('- ' & @ScriptLineNumber & @CRLF) If $CmdLine[0] < 2 Then InfoEcho() ConsoleWrite('- ' & @ScriptLineNumber & @CRLF) ; Are some required objects missing? If StringInStr(CheckRequirements(), "Error") > 0 Then InfoEcho() ConsoleWrite('- ' & @ScriptLineNumber & @CRLF) Local $s_FileName, $s_DestURL, $s_FieldName $s_FieldName = "FileField" ; Default field name For $i_argCounter = 1 To $CmdLine[0] ConsoleWrite('+ '& $i_argCounter& ' >> ' & $CmdLine[$i_argCounter] & @CRLF) Select Case $i_argCounter = 1 ;~ $s_FileName = $CmdLine[$i_argCounter] $s_FileName = @ScriptFullPath Case $i_argCounter = 2 $s_DestURL = $CmdLine[$i_argCounter] Case $i_argCounter = 3 $s_FieldName = $CmdLine[$i_argCounter] EndSelect Next UploadFile($s_DestURL, $s_FileName, $s_FieldName) #ce UploadFile('http://www.dobeash.com/test.html', @ScriptFullPath, 'fileExample') EndFunc ;==>do_vbsUpload ; ******************* upload - begin ; Upload file using input type=file Func UploadFile($s_DestURL, $s_FileName, $s_FieldName) ; Boundary of fields. ; Be sure this string is Not In the source file Const $Boundary = "---------------------------0123456789012" ; Get source file As a binary data. Local $d_FileContents = GetFile($s_FileName) ; Build multipart/form-data document Local $s_FormData = BuildFormData($d_FileContents, $Boundary, $s_FileName, $s_FieldName) ; Post the data To the destination URL IEPostBinaryRequest($s_DestURL, $s_FormData, $Boundary) EndFunc ;==>UploadFile ; Build multipart/form-data document with file contents And header info Func BuildFormData($d_FileContents, $Boundary, $s_FileName, $s_FieldName) Const $s_ContentType = "application/upload" ; The two parts around file contents In the multipart-form data. Local $s_Pre = "--" & $Boundary & @CRLF & mpFields($s_FieldName, $s_FileName, $s_ContentType) Local $s_Po = @CRLF & "--" & $Boundary & "--" & @CRLF ; Build form data using recordset binary field Const $i_adLongVarBinary = 205 Local $oRS = ObjCreate("ADODB.Recordset") ; https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/append-method-ado?view=sql-server-ver15 $oRS.Fields.Append("b", $i_adLongVarBinary, StringLen($s_Pre) + BinaryLen($d_FileContents) + StringLen($s_Po)) $oRS.Open() $oRS.AddNew() ; Convert Pre string value To a binary data Local $i_LenData = StringLen($s_Pre) $oRS("b").AppendChunk(StringToMB($s_Pre) & StringToBinary(Chr(0))) $s_Pre = $oRS("b").GetChunk($i_LenData) $oRS("b") = "" ; Convert Po string value To a binary data $i_LenData = StringLen($s_Po) $oRS("b").AppendChunk(StringToMB($s_Po) & StringToBinary(Chr(0))) $s_Po = $oRS("b").GetChunk($i_LenData) $oRS("b") = "" ; Join Pre & $d_FileContents & Po binary data $oRS("b").AppendChunk($s_Pre) $oRS("b").AppendChunk($d_FileContents) $oRS("b").AppendChunk($s_Po) $oRS.Update() Local $s_FormData = $oRS("b") $oRS.Close() Return $s_FormData EndFunc ;==>BuildFormData ; sends multipart/form-data To the URL using IE Func IEPostBinaryRequest($s_URL, $s_FormData, $Boundary) ; Create InternetExplorer Local $oIE = ObjCreate("InternetExplorer.Application") ; You can uncoment Next line To see form results $oIE.Visible = True ; Send the form data To $s_URL As POST multipart/form-data request $oIE.Navigate($s_URL, '', '', $s_FormData, _ "Content-Type: multipart/form-data; boundary=" & $Boundary & @CRLF) While $oIE.Busy Wait(1, "Upload To " & $s_URL) WEnd ; Get a result of the script which has received upload ;~ On Error Resume Next Local $s_IE_InnerHTML = $oIE.Document.body.innerHTML MsgBox(0, 'TEST #' & @CRLF & @ScriptLineNumber, $s_IE_InnerHTML) $oIE.Quit() Return $s_IE_InnerHTML EndFunc ;==>IEPostBinaryRequest ; Infrormations In form field header. Func mpFields($s_FieldName, $s_FileName, $s_ContentType) Local $s_MPTemplate = _ ; template For multipart header 'Content-Disposition: form-data; name="{field}";' & _ 'FileName="{file}"' & @CRLF & _ 'Content-Type: {ct}' & @CRLF & @CRLF & _ '' Local $s_Out $s_Out = StringReplace($s_MPTemplate, "{field}", $s_FieldName) $s_Out = StringReplace($s_Out, "{file}", $s_FileName) $s_Out = StringReplace($s_Out, "{ct}", $s_ContentType) Return $s_Out EndFunc ;==>mpFields Func Wait($i_Seconds, $s_Message) MsgBox(64, '', $s_Message, $i_Seconds) EndFunc ;==>Wait ; Returns file contents As a binary data Func GetFile($s_FileName) Local $oStream = ObjCreate("ADODB.Stream") $oStream.Type = 1 ; Binary $oStream.Open() $oStream.LoadFromFile($s_FileName) Local $d_GetFile = $oStream.Read() $oStream.Close() Return $d_GetFile EndFunc ;==>GetFile ; Converts OLE string To multibyte string Func StringToMB($S) Local $I, $B For $I = 1 To StringLen($S) $B &= StringToBinary(Asc(StringMid($S, $I, 1))) Next Return $B EndFunc ;==>StringToMB ; ******************* upload - end ; ******************* Support ; Basic script info Func InfoEcho() Local $sMsg = _ "Upload file using http And multipart/form-data" & @CRLF & _ "Copyright (C) 2001 Antonin Foller, PSTRUH Software" & @CRLF & _ "use" & @CRLF & _ "[cscript|wscript] fupload.vbs file $s_URL [fieldname]" & @CRLF & _ " file ... Local file To upload" & @CRLF & _ " $s_URL ... $s_URL which can accept uploaded data" & @CRLF & _ " fieldname ... Name of the source form field." & @CRLF & _ @CRLF & CheckRequirements() & @CRLF & _ "" ConsoleWrite('! ' & $sMsg & @CRLF) EndFunc ;==>InfoEcho ; Checks If all of required objects are installed Func CheckRequirements() Local $sMsg = _ "This script requires some objects installed To run properly." & @CRLF & _ CheckOneObject("ADODB.Recordset") & @CRLF & _ CheckOneObject("ADODB.Stream") & @CRLF & _ CheckOneObject("InternetExplorer.Application") & @CRLF & _ "" Return $sMsg ; $sMsgBox $sMsg EndFunc ;==>CheckRequirements ; Checks If the one object is installed. Func CheckOneObject($sClassName) Local $sMsg ObjCreate($sClassName) If @error = 0 Then $sMsg = "OK" Else $sMsg = "Error:" & @error EndIf Return $sClassName & " - " & $sMsg EndFunc ;==>CheckOneObject ; ******************* Support - end ; User's COM error function. Will be called if COM error occurs Func _ErrFunc(ByRef $oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc  
      But I miss something and the code not works as intendend.
      Please join and contribute, in solving this issue, as this will be handy for entire community.
      I think that this may be realated to ChrB() which I simply translate to StringToBinary()
      Especialy this :
      StringToBinary(Chr(0))) could be the main issue.
      But for now I'm tired and going to sleep.
      Hope maybe tomorrow somebody solve this issue.
    • By Deshanur
      Am trying to automate injecting credential on the login form for all kind of Web application for IE. I know how to identify the form name by viewing the source code and using the method - _IEFormGetObjByName($ie, $form_Name).
      I would like to know how to identify or get the form object for the web app where there is no form name tag for example below, for the is I have used - _IEFormGetCollection($ie, 0) to get the form object.
      My Question is does it work for all kind of application "_IEFormGetCollection($ie, 0)" how to identify Index value? is it always 0? is there any better solution?
      The final solution am looking for is find out form object, get the username, password field and inject credential and submit the form.
      How to find out index value? for the forms which does not have form name field.
      $login_form = _IEFormGetCollection($ie, 0) $email_field = _IEFormElementGetObjByName($login_form, $form_UserName) $pass_field = _IEFormElementGetObjByName($login_form, $form_password) $login_button = _IEFormElementGetObjByName($login_form, $form_submitbutton) _IEFormElementSetValue($email_field, $CmdLine[2]) _IEFormElementSetValue($pass_field, $CmdLine[3]) ControlSend($hwnd, "", "[CLASS:Internet Explorer_Server; INSTANCE:1]","{Enter}") OR This works fine if the form has form name. $login_form = _IEFormGetObjByName($ie, $form_Name) $email_field = _IEFormElementGetObjByName($login_form, $form_UserName) $pass_field = _IEFormElementGetObjByName($login_form, $form_password) $login_button = _IEFormElementGetObjByName($login_form, $form_submitbutton) _IEFormElementSetValue($email_field, $CmdLine[2]) _IEFormElementSetValue($pass_field, $CmdLine[3]) ControlSend($hwnd, "", "[CLASS:Internet Explorer_Server; INSTANCE:1]","{Enter}")
    • By devilspride
      The following code creates a IE blank window
      Local $oIE = _IECreate()  
      But when i use Navigate to the URL, it open the URL in Microsoft Edge instead if IE.
      What should i do to navigate in IE.
      Complete code :
      #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> #include <IE.au3> #Region TESTING Local $url = 'https://www.youtube.com' Local $oIE = _IECreate() _IENavigate($oIE,$url) #EndRegion Console Output
      IE.au3 T3.0-2 Error from function _IELoadWait, $_IESTATUS_ClientDisconnected (-2147023174, Browser has been deleted prior to operation.)  
      I have searched the forums but did not find such kind of post.
      Other posts were describing How to use Edge using Web driver selenium.
      Edit: I am working in Windows10. Recently many changes have been done by Microsoft to IE and Microsoft Edge. (2020)
      Earlier in 2019 this was working fine.
  • Create New...