Jump to content

mLipok

MVPs
  • Posts

    11,553
  • Joined

  • Last visited

  • Days Won

    61

mLipok last won the day on September 13

mLipok had the most liked content!

About mLipok

  • Birthday 07/19/1978

Profile Information

  • Member Title
    I'm nitpicky sometimes.
  • Location
    Europe, Poland, Upper Silesia, Zabrze
  • Interests
    ¯\_(ツ)_/¯

Recent Profile Visitors

28,018 profile views

mLipok's Achievements

  1. So here is my recent snippet which uses new function: Json_ArrayPut() inspired by @Jos AddLocation() #include "Json.au3" ConsoleWrite("- Test8d() :" & @CRLF & Test8d() & @CRLF) Func Test8d() ; Your three JSON strings ;~ Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json1 = '{"name":"John","age":30}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; create object from first JSON string Local $obj1 = Json_Decode($Json1) ConsoleWrite('counting elements in "locations" = ' & UBound(Json_ObjGet($obj1, "locations")) & ' ERR=' & @error & ' EXT=' & @extended & @CRLF) ; add second JSON string to the object as an last elemnt of "JSON_ARRAY" structure called "locations" Json_ArrayPut($obj1, "locations", $Json2) ;~ Json_ArrayPut($obj1, "locations.main", $Json2) ConsoleWrite('counting elements in "locations" = ' & UBound(Json_ObjGet($obj1, "locations")) & ' ERR=' & @error & ' EXT=' & @extended & @CRLF) ; add third JSON string to the object as an last elemnt of "JSON_ARRAY" structure called "locations" Json_ArrayPut($obj1, "locations", $Json3) ;~ Json_ArrayPut($obj1, "locations.addtional", $Json3) ConsoleWrite('counting elements in "locations" = ' & UBound(Json_ObjGet($obj1, "locations")) & ' ERR=' & @error & ' EXT=' & @extended & @CRLF) Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8d Func Json_ArrayPut(ByRef $oObj, $Key, $vJson_toAdd) Json_IsObject($oObj) If @error Then Return SetError(1, 1) ;~ Local $current = Json_Encode($oObj, $JSON_PRETTY_PRINT) ;~ ConsoleWrite('$current = ' & $current & @CRLF) ;~ ConsoleWrite('$vJson_toAdd = ' & $vJson_toAdd & @CRLF) Local $count = UBound(Json_ObjGet($oObj, $Key)) ;~ ConsoleWrite($count & @CRLF) ;~ ConsoleWrite(VarGetType($aFound) & @CRLF) Local $oJson_snippet If (IsString($vJson_toAdd) And StringLen($vJson_toAdd)) Then $oJson_snippet = Json_Decode($vJson_toAdd) If @error Then Return SetError(3, 3) ElseIf Json_IsObject($vJson_toAdd) Then $oJson_snippet = $vJson_toAdd ; just $vJson_toAdd be passed to Json_Put() Else Return SetError(4, 3) EndIf Json_Put($oObj, "." & $Key & "[" & $count & "]", $oJson_snippet) If @error Then Return SetError(5, 0) EndFunc ;==>Json_ArrayPut
  2. #include "Json.au3" ;~ ConsoleWrite("- Test8a() :" & @CRLF & Test8a() & @CRLF) ;~ ConsoleWrite("- Test8b() :" & @CRLF & Test8b() & @CRLF) ConsoleWrite("- Test8c() :" & @CRLF & Test8c() & @CRLF) Func Test8a() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; Decode Local $obj1 = Json_Decode($Json1) Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "," & $Json3 & "]")) Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8a Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; and a while later I was notified about new location, so here to add them ; firstly get current known locations Local $oLocations = Json_ObjGet($obj1, "locations") Local $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used Local $sJson_concatenated = "[" & StringTrimRight($sCurrentLocations, 1) & ',' & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8b Func Test8c() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30}' ; Decode Local $obj1 = Json_Decode($Json1) ; add empty "locations" JSOR ARRAY element Json_ObjPut($obj1, "locations", Json_Decode('[]')) Local $step0 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step0= ' & $step0 & @CRLF) Local $oLocations, $sCurrentLocations, $sJson_concatenated ; get current known locations $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; as for first step - here we know only the first location Local $Json2 = '{"City":"Paris","Country":"France"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json2 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) Local $step1 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step1= ' & $step1 & @CRLF) ; and a while later I was notified about new location, so here to add them ; second step - again get current "Locations" STRING $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8c as for now I was working on: ;~ https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn/page/20/#comment-1547453 #include "Json.au3" ;~ ConsoleWrite("- Test8a() :" & @CRLF & Test8a() & @CRLF) ;~ ConsoleWrite("- Test8b() :" & @CRLF & Test8b() & @CRLF) ConsoleWrite("- Test8c() :" & @CRLF & Test8c() & @CRLF) Func Test8a() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; Decode Local $obj1 = Json_Decode($Json1) Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "," & $Json3 & "]")) Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8a Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; and a while later I was notified about new location, so here to add them ; firstly get current known locations Local $oLocations = Json_ObjGet($obj1, "locations") Local $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used Local $sJson_concatenated = "[" & StringTrimRight($sCurrentLocations, 1) & ',' & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8b Func Test8c() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30}' ; Decode Local $obj1 = Json_Decode($Json1) ; add empty "locations" JSOR ARRAY element Json_ObjPut($obj1, "locations", Json_Decode('[]')) Local $step0 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step0= ' & $step0 & @CRLF) Local $oLocations, $sCurrentLocations, $sJson_concatenated ; get current known locations $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; as for first step - here we know only the first location Local $Json2 = '{"City":"Paris","Country":"France"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json2 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) Local $step1 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step1= ' & $step1 & @CRLF) ; and a while later I was notified about new location, so here to add them ; second step - again get current "Locations" STRING $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8c but yours solutions looks nice. Will take a look on them.
  3. Your answer inspire me to solve it this way: #include "Json.au3" ConsoleWrite("- Test8b() : " & Test8b() & @CRLF) Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; and a while later I was notified about new location, so here to add them ; firstly get current known locations Local $oLocations = Json_ObjGet($obj1, "locations") Local $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used Local $sJson_concatenated = "[" & StringTrimRight($sCurrentLocations, 1) & ',' & $Json3 & "]" Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite($final & @CRLF) EndFunc ;==>Test8b
  4. but I was wondering also about something like this: #include "Json.au3" ConsoleWrite("- Test8b() : " & Test8b() & @CRLF) Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; .... and a while later I was notified about new location, so here I try to add them ..... Local $Json3 = '{"City":"London","Country":"England"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json3 & "]")) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite($final & @CRLF) EndFunc ;==>Test8b as for now with no success
  5. Simple and effective. Simply brilliant. Thanks.
  6. As usually I love your answer my friend. As always, I really liked your answer, my friend. All is clear for me. Thanks. So. @Parsix In your opinion, does this example fully meet your needs for using Au3Stripper with the @trancexx script , I mean all the possibilities of the /SO /PE /RM parameters?
  7. Now it is. Thanks. So here is my solution for this script: ;~ https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/page/4/#findComment-1547476 #Region - AutoIt3Wrapper directives section ; General section #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compression=4 ; Au3Check section #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 6 -w 7 ; Au3Stripper section #AutoIt3Wrapper_Run_Au3Stripper=y ;~ #Au3Stripper_Parameters=/SO /PE #Au3Stripper_Parameters=/SO /PE /RM #AutoIt3Wrapper_Au3Stripper_OnError=f ;~ #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW ;~ #Au3Stripper_Ignore_Funcs=__AddHookApi_DllCallbackRegister_wrapper #EndRegion - AutoIt3Wrapper directives section #include <WinApi.au3> #Region - exmaple ;~ AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") AddHookApi("user32.dll", "MessageBoxW", FuncName(Intercept_MessageBoxW), "int", "hwnd;wstr;wstr;uint") MsgBox(0, 'Test', 'Some normal MsgBox text') DllStructCreate("byte[123456789097]") ; This is a deliberate action intended to display an error, as this script demonstrates how to change error handling - interact with MsgBox's title and text. #EndRegion - exmaple #Region @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _ "hwnd", $hWnd, _ "wstr", $sText, _ "wstr", $sTitle, _ "uint", $iType) If @error Or Not $aCall[0] Then Return 0 Return $aCall[0] EndFunc ;==>Intercept_MessageBoxW ; The magic is down below Func AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "") Local Static $pImportDirectory, $hInstance Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 If Not $pImportDirectory Then $hInstance = _WinAPI_GetModuleHandle(0) $pImportDirectory = ImageDirectoryEntryToData($hInstance, $IMAGE_DIRECTORY_ENTRY_IMPORT) If @error Then Return SetError(1, 0, 0) EndIf Local $iIsInt = IsInt($vFunctionName) Local $iRestore = Not IsString($vNewFunction) Local $tIMAGE_IMPORT_MODULE_DIRECTORY Local $pDirectoryOffset = $pImportDirectory Local $tModuleName Local $iInitialOffset, $iInitialOffset2 Local $iOffset2 Local $tBufferOffset2, $iBufferOffset2 Local $tBuffer, $tFunctionOffset, $pOld, $fMatch, $pModuleName, $pFuncName Local Const $PAGE_READWRITE = 0x04 While 1 $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _ "dword TimeDateStamp;" & _ "dword ForwarderChain;" & _ "dword RVAModuleName;" & _ "dword RVAFirstThunk", _ $pDirectoryOffset) If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName") $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $pModuleName) If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk") If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset $iOffset2 = 0 While 1 $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2) $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1) If Not $iBufferOffset2 Then ExitLoop If $iIsInt Then If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True ; wanted function Else $pFuncName = $hInstance + $iBufferOffset2 + 2 ; 2 is size od "word", see line below... $tBuffer = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $hInstance + $iBufferOffset2) If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True ; wanted function EndIf If $fMatch Then $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2) VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE) If @error Then Return SetError(3, 0, 0) $pOld = DllStructGetData($tFunctionOffset, 1) If $iRestore Then DllStructSetData($tFunctionOffset, 1, $vNewFunction) Else #Region ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ;~ #Au3Stripper_Off ;~ DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) ;~ #Au3Stripper_On #EndRegion ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ; for this reason __AddHookApi_DllCallbackRegister_wrapper() was added and enclosed within #Au3Stripper_Off >>> #Au3Stripper_On section __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset, $vNewFunction, $sRet, $sParams) EndIf Return $pOld EndIf $iOffset2 += DllStructGetSize($tBufferOffset2) WEnd ExitLoop EndIf $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY WEnd Return SetError(4, 0, 0) EndFunc ;==>AddHookApi #Au3Stripper_Off Func __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset__Wrapped, $vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped) DllStructSetData($tFunctionOffset__Wrapped, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped))) EndFunc ;==>__AddHookApi_DllCallbackRegister_wrapper #Au3Stripper_On Func VirtualProtect($pAddress, $iSize, $iProtection) Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>VirtualProtect Func ImageDirectoryEntryToData($hInstance, $iDirectoryEntry) ; Get pointer to data Local $pPointer = $hInstance ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "word BytesOnLastPage;" & _ "word Pages;" & _ "word Relocations;" & _ "word SizeofHeader;" & _ "word MinimumExtra;" & _ "word MaximumExtra;" & _ "word SS;" & _ "word SP;" & _ "word Checksum;" & _ "word IP;" & _ "word CS;" & _ "word Relocation;" & _ "word Overlay;" & _ "char Reserved[8];" & _ "word OEMIdentifier;" & _ "word OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header ; In place of IMAGE_NT_SIGNATURE structure Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; In place of IMAGE_FILE_HEADER structure ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure ; Determine the type Local $tMagic = DllStructCreate("word Magic;", $pPointer) Local $iMagic = DllStructGetData($tMagic, 1) Local $tIMAGE_OPTIONAL_HEADER If $iMagic = 267 Then ; x86 version ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER ElseIf $iMagic = 523 Then ; x64 version ; Move pointer $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER Else Return SetError(3, 0, 0) ; unsupported module type EndIf ; Validate input by checking available number of structures that are in the module Local Const $IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ; predefined value that PE modules always use (AutoIt certainly) If $iDirectoryEntry > $IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 Then Return SetError(4, 0, 0) ; invalid input ; Calculate the offset to wanted entry (every entry is 8 bytes) $pPointer += 8 * $iDirectoryEntry ; At place of correst directory entry Local $tIMAGE_DIRECTORY_ENTRY = DllStructCreate("dword VirtualAddress; dword Size", $pPointer) ; Collect data Local $pAddress = DllStructGetData($tIMAGE_DIRECTORY_ENTRY, "VirtualAddress") If $pAddress = 0 Then Return SetError(5, 0, 0) ; invalid input ; $pAddress is RVA, add it to base address Return $hInstance + $pAddress EndFunc ;==>ImageDirectoryEntryToData #EndRegion @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Explanations: Using @trancexx code, in order to use: #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe #AutoIt3Wrapper_Au3Stripper_OnError=f there is also a need to use: #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW Because in other way: #Au3Stripper_Parameters=/so /pe Will strip down the function as she is not called directly. Only the function name is used but as a string and not directly like a "pointer" To prevent using: #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW The Intercept_MessageBoxW can be called as a parameter for FuncName(Intercept_MessageBoxW) this way: ;~ AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") AddHookApi("user32.dll", "MessageBoxW", FuncName(Intercept_MessageBoxW), "int", "hwnd;wstr;wstr;uint") In such case Au3Stripper knows that Intercept_MessageBoxW was used and should not be stripped. REMARK: You can also notice that I used: #Au3Stripper_Parameters=/SO /PE /RM I mean the the most demanding/restrictive option /RM For this reason this following mod was added: ..... #Region ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ;~ #Au3Stripper_Off ;~ DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) ;~ #Au3Stripper_On #EndRegion ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ; for this reason __AddHookApi_DllCallbackRegister_wrapper() was added and enclosed within #Au3Stripper_Off >>> #Au3Stripper_On section __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset, $vNewFunction, $sRet, $sParams) ..... #Au3Stripper_Off Func __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset__Wrapped, $vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped) DllStructSetData($tFunctionOffset__Wrapped, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped))) EndFunc ;==>__AddHookApi_DllCallbackRegister_wrapper #Au3Stripper_On ..... The reason that I do not must to use: ;~ #Au3Stripper_Ignore_Funcs=__AddHookApi_DllCallbackRegister_wrapper is because __AddHookApi_DllCallbackRegister_wrapper() is used/called before the #Au3Stripper_Off / #Au3Stripper_Off sections occurs so Au3Stripper already dit the /RM action on the function name in entire script but at this moment do not touched $******__Wrapped variables. @Jos Does this example cover the whole topic of using Au3Stripper with this @trancexx script, I mean all releated with the /SO /PE /RM parameters? btw. I wonder whether, for the correctness of "code reading" and protection against possible changes in Au3Stripper, I should still use: #Au3Stripper_Ignore_Funcs=__AddHookApi_DllCallbackRegister_wrapper
  8. because I inform him #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi that I have already solved the problem in this function and he should not worry about it anymore. at least this is my understanding of what #Au3Stripper_Ignore_Errors_in_Funcs should do.
  9. Thanks. Now I see what is going on. the problem is related to #Au3Stripper_Parameters=/so /pe which strip down the Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _ "hwnd", $hWnd, _ "wstr", $sText, _ "wstr", $sTitle, _ "uint", $iType) If @error Or Not $aCall[0] Then Return 0 Return $aCall[0] EndFunc ;==>Intercept_MessageBoxW So once what can be done is to use: #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW but still, all warnings from Au3Stripper will appear in the console window. So I also added: #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi but still, all warnings from Au3Stripper will appear in the console window. Here is modified: #Region - AutoIt3Wrapper directives section ; General section #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compression=4 ; Au3Check section #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 6 -w 7 ; Au3Stripper section #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe #AutoIt3Wrapper_Au3Stripper_OnError=f #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi #EndRegion - AutoIt3Wrapper directives section #include <WinApi.au3> #Region - exmaple AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") MsgBox(0, 'Test', 'Some normal MsgBox text') DllStructCreate("byte[123456789097]") ; This is a deliberate action intended to display an error, as this script demonstrates how to change error handling - interact with MsgBox's title and text. #EndRegion - exmaple #Region @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _ "hwnd", $hWnd, _ "wstr", $sText, _ "wstr", $sTitle, _ "uint", $iType) If @error Or Not $aCall[0] Then Return 0 Return $aCall[0] EndFunc ;==>Intercept_MessageBoxW ; The magic is down below Func AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "") Local Static $pImportDirectory, $hInstance Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 If Not $pImportDirectory Then $hInstance = _WinAPI_GetModuleHandle(0) $pImportDirectory = ImageDirectoryEntryToData($hInstance, $IMAGE_DIRECTORY_ENTRY_IMPORT) If @error Then Return SetError(1, 0, 0) EndIf Local $iIsInt = IsInt($vFunctionName) Local $iRestore = Not IsString($vNewFunction) Local $tIMAGE_IMPORT_MODULE_DIRECTORY Local $pDirectoryOffset = $pImportDirectory Local $tModuleName Local $iInitialOffset, $iInitialOffset2 Local $iOffset2 Local $tBufferOffset2, $iBufferOffset2 Local $tBuffer, $tFunctionOffset, $pOld, $fMatch, $pModuleName, $pFuncName Local Const $PAGE_READWRITE = 0x04 While 1 $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _ "dword TimeDateStamp;" & _ "dword ForwarderChain;" & _ "dword RVAModuleName;" & _ "dword RVAFirstThunk", _ $pDirectoryOffset) If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName") $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $pModuleName) If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk") If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset $iOffset2 = 0 While 1 $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2) $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1) If Not $iBufferOffset2 Then ExitLoop If $iIsInt Then If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True ; wanted function Else $pFuncName = $hInstance + $iBufferOffset2 + 2 ; 2 is size od "word", see line below... $tBuffer = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $hInstance + $iBufferOffset2) If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True ; wanted function EndIf If $fMatch Then $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2) VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE) If @error Then Return SetError(3, 0, 0) $pOld = DllStructGetData($tFunctionOffset, 1) If $iRestore Then DllStructSetData($tFunctionOffset, 1, $vNewFunction) Else DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) EndIf Return $pOld EndIf $iOffset2 += DllStructGetSize($tBufferOffset2) WEnd ExitLoop EndIf $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY WEnd Return SetError(4, 0, 0) EndFunc ;==>AddHookApi Func VirtualProtect($pAddress, $iSize, $iProtection) Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>VirtualProtect Func ImageDirectoryEntryToData($hInstance, $iDirectoryEntry) ; Get pointer to data Local $pPointer = $hInstance ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "word BytesOnLastPage;" & _ "word Pages;" & _ "word Relocations;" & _ "word SizeofHeader;" & _ "word MinimumExtra;" & _ "word MaximumExtra;" & _ "word SS;" & _ "word SP;" & _ "word Checksum;" & _ "word IP;" & _ "word CS;" & _ "word Relocation;" & _ "word Overlay;" & _ "char Reserved[8];" & _ "word OEMIdentifier;" & _ "word OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header ; In place of IMAGE_NT_SIGNATURE structure Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; In place of IMAGE_FILE_HEADER structure ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure ; Determine the type Local $tMagic = DllStructCreate("word Magic;", $pPointer) Local $iMagic = DllStructGetData($tMagic, 1) Local $tIMAGE_OPTIONAL_HEADER If $iMagic = 267 Then ; x86 version ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER ElseIf $iMagic = 523 Then ; x64 version ; Move pointer $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER Else Return SetError(3, 0, 0) ; unsupported module type EndIf ; Validate input by checking available number of structures that are in the module Local Const $IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ; predefined value that PE modules always use (AutoIt certainly) If $iDirectoryEntry > $IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 Then Return SetError(4, 0, 0) ; invalid input ; Calculate the offset to wanted entry (every entry is 8 bytes) $pPointer += 8 * $iDirectoryEntry ; At place of correst directory entry Local $tIMAGE_DIRECTORY_ENTRY = DllStructCreate("dword VirtualAddress; dword Size", $pPointer) ; Collect data Local $pAddress = DllStructGetData($tIMAGE_DIRECTORY_ENTRY, "VirtualAddress") If $pAddress = 0 Then Return SetError(5, 0, 0) ; invalid input ; $pAddress is RVA, add it to base address Return $hInstance + $pAddress EndFunc ;==>ImageDirectoryEntryToData #EndRegion @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 @Jos could you please take a look the above script and check why this following information still shows up in console even though I use the directive : #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi
  10. When you try to use: with: #AutoIt3Wrapper_Au3Stripper_OnError=c compiled version works well. but with: #AutoIt3Wrapper_Au3Stripper_OnError=f the compiled version doesn't even show the basic MsgBox , I mean this following one doesn't show up:
  11. I also have other question. How to connactate this following string Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' to get such results: {"name":"John","age":30,"locations":[{"City":"Paris","Country":"France"},{"City":"London","Country":"England"}] The previosuly published example did similar things but as result there was "locations" as JSON_OBJECT - a dicionary element in JSON structure, but this time the "locations" it is an JSON_ARRAY - a list of elements in JSON structure
  12. I have a question about this following example: #include "Json.au3" ConsoleWrite("- Test8() : " & Test8() & @CRLF) Func Test8() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":{}}' Local $Json2 = '{"MainCity":"Paris","MainCountry":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; Decode Local $obj1 = Json_Decode($Json1) Local $obj2 = Json_Decode($Json2) Local $obj2a = $obj2 Local $obj3 = Json_Decode($Json3) ; Insert obj2 into obj1 under a key (e.g. "location") $obj1.Item("locations") = $obj2 ; <-- This puts data into object $obj1.Item("locations").Item("location1") = $obj2a ; <-- This creates a sub-object $obj1.Item("locations").Item("location2") = $obj3 ; <-- This creates a sub-object ; Encode back to JSON Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite($final & @CRLF) EndFunc ;==>Test8 Why I can't use $obj2a in the same way as I used $obj3. I know I already used $obj2 but why I can't use them again ? I know that I can use them like this: ;~ $obj1.Item("locations") = $obj2 ; <-- This puts data into object $obj1.Item("locations").Item("location1") = $obj2a ; <-- This creates a sub-object But why can't use them together ?
  13. Sorry, the newer version works.
  14. I know, I know. You need a simple example that clearly demonstrates what's going on with a very short description of the problem. So you rightly expect (as usual) that the person requesting help will put in the effort to prepare a question and test cases that clearly and concisely demonstrate what's wrong. I'll try to prepare that in the coming days - at least I hope so.
  15. Sitll we are not talking about the fact that AutoIt crashes. We are talking about: Why @trancexx code is not working in 64bit.
×
×
  • Create New...