HotKeyIt / ahkdll-v2-release

AutoHotkey_H v2 release
http://hotkeyit.github.io/v2/
GNU General Public License v2.0
61 stars 15 forks source link

Unable To Run Ahk2Exe to Compile Custom Code #15

Closed ghost closed 3 years ago

ghost commented 4 years ago

Issue: Unable to run Ahk2Exe to allow compilation of AHK_H V2 Scripts due to AHK V2 updating VarSetCapacity() to VarSetStrCapacity().

Steps to Reproduce:

  1. Extract Compiler folder from this Repository into C:\Program Files\AutoHotkey\Compiler
  2. Extract files from x64w folder from this Repository into C:\Program Files\AutoHotkey\Compiler
  3. Rename AutoHotkey.exe to Ahk2Exe.exe (deleting/backing up old)
  4. Run Ahk2Exe.exe
  5. Errors appear, e.g. https://i.imgur.com/jIXvsG9.png https://i.imgur.com/7y1Mds7.png

Cause: AHK V2 Updated VarSetCapacity() to VarSetStrCapacity() Old: https://www.autohotkey.com/docs/commands/VarSetCapacity.htm New: https://lexikos.github.io/v2/docs/commands/VarSetStrCapacity.htm

Version: Latest AHK_H V2

ghost commented 4 years ago

After manually resolving the VarSetCapacity() errors without properly dealing with the fillValue being removed (due to a lack of core understanding), I have now come across this error. https://i.imgur.com/0ChQA5h.png

I have resolved this for my personal use by manually adding the required keys.

ghost commented 4 years ago

Next bottleneck appears to be a GuiCreate error which I am currently unfamiliar with how to resolve. https://i.imgur.com/dQpg4AP.png

ghost commented 4 years ago

Further research shows that this issue has been confirmed on the AutoHotkey Forums by another user. This issue was last resolved by HotKeyIt in May, but has since returned.

Source: https://www.autohotkey.com/boards/viewtopic.php?p=338701#p338701

ghost commented 4 years ago

For better representation as to when the issue was merged into the code, I went back and downloaded the repo as of commit 95923923f8aaec1a192b611b7244c7b7a594191c and tested the Ahk2Exe, it opens without throwing any errors.

ghost commented 4 years ago

Due to v2.110 VarSetCapacity errors, I attempted a v2.109 custom compiled bin BinRun() alongside the v2.109 Ahk2Exe. This did not work as expected either with the resulting message: ERROR: e_magic not found.

For now I'll go ahead and merge my 11 files into 1 massive bloated file, but I'd like to resolve this moving forward, I'm just not sure how at this time after posting a forum thread and asking a few people in the Discord server.

010: file := FileRead("testTwo.exe","RAW")
011: PID := BinRun(&file)
---- BinRun.ahk
004: if !MEM_COMMIT
005: IMAGE_DOS_HEADER :="WORD e_magic;WORD e_cblp;WORD e_cp;WORD e_crlc;WORD e_cparhdr;WORD e_minalloc;WORD e_maxalloc;WORD e_ss;WORD e_sp;WORD e_csum;WORD e_ip;WORD e_cs;WORD e_lfarlc;WORD e_ovno;
024: if (Type(pData)!="Integer")
037: if InStr(cmdLine,"
")
044: IDH := Struct(IMAGE_DOS_HEADER,pData)
045: if (IDH.e_magic != IMAGE_DOS_SIGNATURE)
046: MsgBox("ERROR: e_magic not found") (145.36)
ghost commented 3 years ago

@HotKeyIt I apologize for the ping, I am sure you are busy external to this project. I would love to know if you plan on resolving this issue.

Thanks for your time, Deafwave

HotKeyIt commented 3 years ago

Many thanks for your report and findings, I will surely resolve the issue. I think I will find some time to look into it this or next week after I merge latest v2 ;)

ghost commented 3 years ago

Sounds great, thanks HotKeyIt. I'm extremely glad that you're still alive! Looking forward to the updates. :)

ghost commented 3 years ago

@HotKeyIt Is there some place where I can donate to you for spending your time creating this?

HotKeyIt commented 3 years ago

This should be working fine now, I have updated v1 Compiler to support all #Directives and v2 compiling.

ghost commented 3 years ago

Thanks for this! Unfortunately, I'm running into a couple other issues updating to the latest compiled version in this repo.

These were all tested pre-compile using the AutoHotkey.exe, AutoHotkey.dll, and vcruntime140.dll in x64w of this repo.

1.

Hotkey("F1", "createMessageBox") ; <--- Error: Invalid callback function
; Hotkey("F1", createMessageBox) ; <--- Warning: This variable appears to never be assigned a value. Specifically: global createMessageBox -> Error: Nonexistent hotkey. Specifically: F1
; Hotkey("F1", createMessageBox()) ; <--- Immediately invokes MsgBox with asdasd. Upon pressing OK it throws: Error: Nonexistent hotkey. Specifically: F1
Return

createMessageBox() {
    global
    MsgBox("asdasd")
    Return
}

2.

defaultObject := {
    testVar: "yay, it worked"
}

CritObj := CriticalObject(defaultObject)

additionalThread := "
(
    CritObj := CriticalObject(A_Args[1])
    CritObj.testVar := "Manipulated CritObj String"
    MsgBox(CritObj.testVar)
)"

; exampleThread := AHKThread(additionalThread, &CritObj "", "testSecondThread", false) ; <-- Error: Syntax error Specifically &CritObj ""
exampleThread := AHKThread(additionalThread, &CritObj, "testSecondThread", false) ; <-- Error: Syntax error Specifically &CritObj
; exampleThread := AHKThread(additionalThread, CritObj, "testSecondThread", false) ; <-- Error in #include file This value of type "Object" has no property named "Ptr".
; exampleThread := AHKThread(additionalThread, CritObj "", "testSecondThread", false) ; <-- Error: Expected a String but got an Object.

Sleep(10000) ; Janky Test
Return

Thanks for your time, Deafwave

HotKeyIt commented 3 years ago
  1. If Callback is a function, it is called with one parameter, the name of the hotkey.
    
    Hotkey("F1", "createMessageBox")
    Return

createMessageBox(hotkey) { global MsgBox hotkey Return }

2. Parameter must be a string, also now & is not used for address, instead StrPtr and ObjPtr are used:

defaultObject := { testVar: "yay, it worked" }

CritObj := CriticalObject(defaultObject)

additionalThread := " ( CritObj := CriticalObject(A_Args[1]) CritObj.testVar := "Manipulated CritObj String" MsgBox(CritObj.testVar) )"

exampleThread := AHKThread(additionalThread, "" ObjPtr(CritObj), "testSecondThread", false)

Sleep(2000) ; Janky Test MsgBox CritObj.testVar Return



I have also updated Ahk2Exe.exe in compiler (using v1) in the downloads and fixed not to add Exit in the end of script.
ghost commented 3 years ago

I see you have been making documentation updates, but I did not see anything on this last remaining issue.

Q: When I compile the script with includes, what is the proper way to start an AHKThread?

My working out: https://github.com/Deafwave/ahkdll-v2-release/tree/testCompiler/src

Primary File:

; src/exampleOne.ahk

defaultObject := {
    testVar: "test failed"
}

CritObj := CriticalObject(defaultObject)

;;;;;;;;

; Non-compiled: MessageBox with "Manipulated CritObj String"
; Compiled: Script File Not Found exampleTwo.ahk
exampleThread := AHKThread(A_ScriptDir "\exampleTwo.ahk", "" ObjPtr(CritObj), "exampleTwo", true)

;;;;;;;;

; Non-compiled: MessageBox with "Manipulated CritObj String"
; Compiled: Function library not found #include <exampleLibrary>
#include <exampleThree>
exampleThread := AHKThread(exampleThreeString, "" ObjPtr(CritObj), "exampleThree", false)

; addFile appears to be the same issue

; BinRun might work, but then I'd have to compile two or more .exe's and I'd prefer to package it into a single

;;;;;;;;

Sleep(2000) ; Jank Test
Return
HotKeyIt commented 3 years ago

You should use CreateScript to include script in your Compiled exe that is then used by AhkThread, see this post: https://www.autohotkey.com/boards/viewtopic.php?p=373780#p373780

ghost commented 3 years ago

We're close! I tried many different variations and attempted bypasses, the closest ones I found have been pushed to the same repo: https://github.com/Deafwave/ahkdll-v2-release/blob/testCompiler/src/exampleOne.ahk

I'm unsure of the difference between DynaRun() as shown in the documentation, and AhkThread(), but I followed the example you provided in the aforementioned post.

  1. All of my semi-working variations have one error after compilation, 0 before.

    ; Non-compiled: Working as Expected
    ; Compiled: Warning: This variable has not yet been assigned a value Specifically local aScript at L#73 @ https://i.imgur.com/3f2GasX.png
    exampleThread := AHKThread(CreateScript("ExampleTwoMemory:ExampleTwoMemoryEnd"), "" ObjPtr(CritObj))
  2. Placing a return after the label as you did in the aforementioned post, causes the code to not execute due to hitting a return. I have 'bypassed' this by placing a placeholder variable:

    ;; Seems to cause strange Return issues, probably because of my bypass placeholder
    ExampleTwoMemory:
    placeholder := "So label isn't looking at a function, and is not a return to prevent code execution"
    #include <exampleTwoLib>
    ExampleTwoMemoryEnd:
    Return
  3. Specifically to the non-label function style as per the documentation, it has an additional error, and a slightly different placement of the local aScript issue.

    ;; Non-compiled: Nothing happens
    ;; Compiled: Warning in #include file "CreateScript.ahk"
    ;;   This variable has not been assigned a value
    ;;   Specifically: local aScript (L#27) @ https://i.imgur.com/9DThmyq.png
    ;;   Missing "}" somewhere
    exampleThread := AHKThread(CreateScript("ExampleTwoMemory{}"), "" ObjPtr(CritObj))

Please let me know if you would like me to open additional issues for any of these findings.

Thanks, Deafwave

HotKeyIt commented 3 years ago

aScript issue is solved, download again. If the #include only contains function or classes you can simply place it in the end, then return is not a problem: AhkThread(MyScript "`n" CreateScript("ExampleTwoMemory:ExampleTwoMemoryEnd"), "" ObjPtr(CritObj))

ghost commented 3 years ago

I appear to be receiving this new error on all five compiled variations: https://i.imgur.com/ei3mTEb.png

Error: This value of type "String" has no property named "Ptr".

--

This variant still remains elusive when executing as source: https://i.imgur.com/7YbdMcI.png

It appears to remove MessageBoxFunction(string) in exampleLibrary.ahk causing this issue.

exampleThread := AHKThread(CreateScript("ExampleTwoMemory{}"), "" ObjPtr(CritObj))

ExampleTwoMemory() { ; Error: Missing "}"
    placeholder := "So label isn't looking at a function, and is not a return to prevent code execution"
    #include <exampleLibrary> ; Appears to nuke "MessageBoxFunction(string) " causing
    #include <exampleTwo>
}
HotKeyIt commented 3 years ago

The first error is because UnZipRawMemory could not extract script, did you compile with encryption, then you need to pass the passwort to CreateScript. The lookup for end of function is not very smart, so it finds the ending bracket before end, better to stick with Labels or indent code in your library.

ghost commented 3 years ago

I believe I did not compile with Encryption, or if I did, I used the default password.

I will validate this, but as shown in #17 I used:

RunWait "`"D:\ahkdll-v2-release\Compiler\Ahk2Exe.exe`" `"D:\ahkdll-v2-release\Compiler\Ahk2Exe.ahk`" /in `"D:\ahkdll-v2-release\src\exampleOne.ahk`" /out `"D:\ahkdll-v2-release\src\compiled\exampleOne.exe`" /bin `"D:\ahkdll-v2-release\x64w\AutoHotkey.exe`" /compress 1"

That being said, in the future I will use Encryption, but I do not see where the password would go in the RunWait. Save Script Settings As does not appear to save the Encrypt command/password to the file.

ghost commented 3 years ago

I attempted to compile via the AHK2Exe instead of through the RunWait. I received this error.

Error: The Script contains syntax Errors.
Specifically: CreateScript.ahk

Can find the error here: https://i.imgur.com/izngAPg.png

HotKeyIt commented 3 years ago

Try again with latest release. If you use encryption the default password is AutoHotkey, so it would be CreateScript("ExampleTwoMemory{}","AutoHotkey"). Otherwise leave empty. If you don't use encryption and compression, you can extract script from exe using ResHacker and debug to see what the problem is. Otherwise provide simple example that reproduces the problem and I will take a look.

ghost commented 3 years ago

Ah! Noted, let me take another look.

  1. Immediate Error upon executing latest AHK2Exe.exe: https://i.imgur.com/WDE1KIW.png
; File: DynaRun.ahk
; This is a pain to debug since it's a string format.
illegal character "UChar""

Passed it by updating to:

NumPut(`"`"UChar,`"`"0x h,dmp,A_Index/2-1)

Based on how https://github.com/HotKeyIt/Ahk2Exe/blob/master/Lib/DynaRun.ahk looked, it should be a variable, not a string? However, my knowledge in this area is limited and untested, so I will not submit a PR.

New error: https://i.imgur.com/dPBuNKK.png

Call to nonexistent function.
Specifically: BufferAlloc

I believe this is casued by the Hybrid v1 -> v2. BufferAlloc() is a function in v2, but is VarSetCapacity() in v1 with a very different input style. I can attempt to downgrade to VarSetCapacity, but I believe that would not be beneficial for us to move forward. I'll wait for your knowledge.

ghost commented 3 years ago

I have cleaned up an extremely basic testing directory for this repo.

https://github.com/Deafwave/ahkdll-v2-release/tree/testCompiler

It currently contains two tests that work as expected when uncompiled and fail to compile due to the aforementioned errors.

Please let me know if you would like me to make this a Pull Request.

HotKeyIt commented 3 years ago

Sorry I should have thought about that, try latest release.

ghost commented 3 years ago

No problem, I appreciate you working with me to get this resolved.

Good news is the Non-encrypt method via Ahk2Exe.exe UI is working as expected.

I am unsure how the password gets stored using /NoDecompile in the CLI version so the following attempts were all done with the UI.

That being said, compress or encrypt is breaking compilation still: https://i.imgur.com/ZJ4vVbA.png Error: This value of type "string" has no property named "Ptr".

; testFuncEncrypt.ahk
; UI: Compress with MPRESS or UPX -> aforementioned error
; UI: Compress with MPRESS or UPX + encrypt of `AutoHotkey` via UI -> aforementioned error
; UI: No Compress, No Encrypt -> Runs as Expected
exampleThread := AHKThread(CreateScript("ExampleFourMemory:ExampleFourMemoryEnd", "AutoHotkey"), "" ObjPtr(CritObj))

; testFunc.ahk
; UI: Compress with MPRESS or UPX -> Compiled runs, does nothing
; UI: Compress with MPRESS or UPX + encrypt of `AutoHotkey` via UI -> Compiled runs, does nothing
; UI: No Compress, No Encrypt -> Runs as Expected
exampleThread := AHKThread(CreateScript("ExampleFourMemory:ExampleFourMemoryEnd"), "" ObjPtr(CritObj))
HotKeyIt commented 3 years ago

CLI for password is

/pass AutoHotkey

I finally found the problem with CreateScript, it should work fine now.

ghost commented 3 years ago

Appears to be working as intended outside of a strange bug that I receive if I try to place my Custom Bin file in the Compiler Directory. I am attempting to close this brutally long ticket, so I have created #18 for this.

Compiling on Private Repo revealed a new issue, I have created #19 for this.