Jump to content

RegisterSyncCallback


Go to solution Solved by Danyfirex,

Recommended Posts

RegisterSyncCallback from autohotkey forum by @lexikos
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=21223

/*
    RegisterSyncCallback
    
    A replacement for RegisterCallback for use with APIs that will call
    the callback on the wrong thread.  Synchronizes with the script's main
    thread via a window message.
    
    This version tries to emulate RegisterCallback as much as possible
    without using RegisterCallback, so shares most of its limitations,
    and some enhancements that could be made are not.
    
    Other differences from v1 RegisterCallback:
      - Variadic mode can't be emulated exactly, so is not supported.
      - A_EventInfo can't be set in v1, so is not supported.
      - Fast mode is not supported (the option is ignored).
      - ByRef parameters are allowed (but ByRef is ignored).
      - Throws instead of returning "" on failure.
*/
RegisterSyncCallback(FunctionName, Options:="", ParamCount:="")
{
    if !(fn := Func(FunctionName)) || fn.IsBuiltIn
        throw Exception("Bad function", -1, FunctionName)
    if (ParamCount == "")
        ParamCount := fn.MinParams
    if (ParamCount > fn.MaxParams && !fn.IsVariadic || ParamCount+0 < fn.MinParams)
        throw Exception("Bad param count", -1, ParamCount)
    
    static sHwnd := 0, sMsg, sSendMessageW
    if !sHwnd
    {
        Gui RegisterSyncCallback: +Parent%A_ScriptHwnd% +hwndsHwnd
        OnMessage(sMsg := 0x8000, Func("RegisterSyncCallback_Msg"))
        sSendMessageW := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "user32.dll", "ptr"), "astr", "SendMessageW", "ptr")
    }
    
    if !(pcb := DllCall("GlobalAlloc", "uint", 0, "ptr", 96, "ptr"))
        throw
    DllCall("VirtualProtect", "ptr", pcb, "ptr", 96, "uint", 0x40, "uint*", 0)
    
    p := pcb
    if (A_PtrSize = 8)
    {
        /*
        48 89 4c 24 08  ; mov [rsp+8], rcx
        48 89 54'24 10  ; mov [rsp+16], rdx
        4c 89 44 24 18  ; mov [rsp+24], r8
        4c'89 4c 24 20  ; mov [rsp+32], r9
        48 83 ec 28'    ; sub rsp, 40
        4c 8d 44 24 30  ; lea r8, [rsp+48]  (arg 3, &params)
        49 b9 ..        ; mov r9, .. (arg 4, operand to follow)
        */
        p := NumPut(0x54894808244c8948, p+0)
        p := NumPut(0x4c182444894c1024, p+0)
        p := NumPut(0x28ec834820244c89, p+0)
        p := NumPut(  0xb9493024448d4c, p+0) - 1
        lParamPtr := p, p += 8
        
        p := NumPut(0xba, p+0, "char") ; mov edx, nmsg
        p := NumPut(sMsg, p+0, "int")
        p := NumPut(0xb9, p+0, "char") ; mov ecx, hwnd
        p := NumPut(sHwnd, p+0, "int")
        p := NumPut(0xb848, p+0, "short") ; mov rax, SendMessageW
        p := NumPut(sSendMessageW, p+0)
        /*
        ff d0        ; call rax
        48 83 c4 28  ; add rsp, 40
        c3           ; ret
        */
        p := NumPut(0x00c328c48348d0ff, p+0)
    }
    else ;(A_PtrSize = 4)
    {
        p := NumPut(0x68, p+0, "char")      ; push ... (lParam data)
        lParamPtr := p, p += 4
        p := NumPut(0x0824448d, p+0, "int") ; lea eax, [esp+8]
        p := NumPut(0x50, p+0, "char")      ; push eax
        p := NumPut(0x68, p+0, "char")      ; push nmsg
        p := NumPut(sMsg, p+0, "int")
        p := NumPut(0x68, p+0, "char")      ; push hwnd
        p := NumPut(sHwnd, p+0, "int")
        p := NumPut(0xb8, p+0, "char")      ; mov eax, &SendMessageW
        p := NumPut(sSendMessageW, p+0, "int")
        p := NumPut(0xd0ff, p+0, "short")   ; call eax
        p := NumPut(0xc2, p+0, "char")      ; ret argsize
        p := NumPut((InStr(Options, "C") ? 0 : ParamCount*4), p+0, "short")
    }
    NumPut(p, lParamPtr+0) ; To be passed as lParam.
    p := NumPut(&fn, p+0)
    p := NumPut(ParamCount, p+0, "int")
    return pcb
}

RegisterSyncCallback_Msg(wParam, lParam)
{
    if (A_Gui != "RegisterSyncCallback")
        return
    fn := Object(NumGet(lParam + 0))
    paramCount := NumGet(lParam + A_PtrSize, "int")
    params := []
    Loop % paramCount
        params.Push(NumGet(wParam + A_PtrSize * (A_Index-1)))
    return %fn%(params*)
}

contain machine code which I don't understand.
Anyone knowledgeable about using machine code willing to convert it to Autoit :P :D

Link to comment
Share on other sites

don't know if I translate it correct or not :baby: as I am also not familiar with AHK :D

__ExampleA()
Func __ExampleA()
#cs
    p := NumPut(0x68, p+0, "char")      ; push ... (lParam data)
    lParamPtr := p, p += 4
    p := NumPut(0x0824448d, p+0, "int") ; lea eax, [esp+8]
    p := NumPut(0x50, p+0, "char")      ; push eax
    p := NumPut(0x68, p+0, "char")      ; push nmsg
    p := NumPut(sMsg, p+0, "int")
    p := NumPut(0x68, p+0, "char")      ; push hwnd
    p := NumPut(sHwnd, p+0, "int")
    p := NumPut(0xb8, p+0, "char")      ; mov eax, &SendMessageW
    p := NumPut(sSendMessageW, p+0, "int")
    p := NumPut(0xd0ff, p+0, "short")   ; call eax
    p := NumPut(0xc2, p+0, "char")      ; ret argsize
    p := NumPut((InStr(Options, "C") ? 0 : ParamCount*4), p+0, "short")
#ce

    $sMsg = '0x8000'                ;~ WM_APP
    $sHwnd = '0x000203B8'           ;~ Dummy Gui Hwnd
    $sSendMessageW = '0x76695539'   ;~ ProcAddress SendMessageW
    $ParamCount = 2
    $TParam = $ParamCount*4

    $bytecode = '0x' & '68' & '0824448d' & '50' & '68' & StringTrimLeft($sMsg, 2) & '68' & _
                StringTrimLeft($sHwnd, 2) & 'b8' & StringTrimLeft($sSendMessageW, 2) & 'd0ff' & 'c2' & $TParam
    ConsoleWrite($bytecode & @crlf)
    ConsoleWrite(BinaryLen($bytecode) & @crlf)  ;~ BinaryLen = 47
EndFunc

 

what confuse me is if BinaryLen = 47 then why the number of bytes allocate is 96 :unsure:

DllCall("GlobalAlloc", "uint", 0, "ptr", 96, "ptr")

 

Edited by jugador
Link to comment
Share on other sites

Just guess :sweating: maybe we could solved this type of problem using such function(RegisterSyncCallback) :D

 

Func __Dummy_Logic()
    $pcb = DllCall("GlobalAlloc", "uint", 0, "ptr", 96, "ptr")[0]
    $sMsg = 0x8000                ;~ WM_APP
    $sHwnd = 0x000203B8           ;~ Dummy Gui Hwnd
    $sSendMessageW = 0x76695539   ;~ ProcAddress SendMessageW
    $ParamCount = 2
    $TParam = $ParamCount*4

    $lParamPtr = $pcb
    Local $tSTRUCT1 = DllStructCreate("Char[5];uint_ptr", $pcb)
    DllStructSetData($tSTRUCT1, 1, 0x68)
    DllStructSetData($tSTRUCT1, 2, $lParamPtr)

    Local $tSTRUCT2 = DllStructCreate("Int;Char[5];Char[5];Int;Char[5];Int;Char[5];Int;Short;Char[5];Short", $pcb + 4)
    DllStructSetData($tSTRUCT2, 1, 0x0824448d)
    DllStructSetData($tSTRUCT2, 2, 0x50)
    DllStructSetData($tSTRUCT2, 3, 0x68)
    DllStructSetData($tSTRUCT2, 4, $sMsg)
    DllStructSetData($tSTRUCT2, 5, 0x68)
    DllStructSetData($tSTRUCT2, 6, $sHwnd)
    DllStructSetData($tSTRUCT2, 7, 0xb8)
    DllStructSetData($tSTRUCT2, 8, $sSendMessageW)
    DllStructSetData($tSTRUCT2, 9, 0xd0ff)
    DllStructSetData($tSTRUCT2, 10, 0xc2)
    DllStructSetData($tSTRUCT2, 11, $TParam)
EndFunc

Op code out of my reach :no:
So it's upto the MVP of Autoit forum to decide to add such function(RegisterSyncCallback) or not ^_^

:bye:

Edited by jugador
Link to comment
Share on other sites

Hello, I don't think it's going to help much but just convert it for fun.

 

#include <winapi.au3>
#include <Memory.au3>





MsgBox(0, "Main Thread", "GetCurrentThreadId: " & DllCall("kernel32.dll", "handle", "GetCurrentThread")[0])


Local $pCB = _RegisterSyncCallback(_MyFn)
;~ Local $pCB = _DllCallBackRegisterNormal(_MyFn)

;~ DllCallAddress("int", $pCB, "int", 123)

DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $pCB, "ptr", 124, "long", 0, "int*", 0)


MsgBox(0, "", "Click To Exit")

Exit


Func _MyFn($arg)
    MsgBox(0, "_MyFn - Child Thread", "GetCurrentThreadId: " & DllCall("kernel32.dll", "handle", "GetCurrentThread")[0] & @CRLF & "$arg:  " & Int($arg))
EndFunc   ;==>_MyFn


Func _DllCallBackRegisterNormal($Function)
    Local $hHandle = DllCallbackRegister($Function, "int", "ptr")
    Return DllCallbackGetPtr($hHandle)
EndFunc   ;==>_DllCallBackRegisterNormal


Func _RegisterSyncCallback($Function, $iOptions = 0, $iParamCount = 0)
    Local Static $hGUI
    Local Static $pSendMessage
    Local Static $iMsg

    If Not $hGUI Then
        $hGUI = GUICreate("RegisterSyncCallback_Msg", 300, 200)
        $iMsg = 0x8000
        GUIRegisterMsg($iMsg, RegisterSyncCallback_Msg)
        $pSendMessage = DllCall("Kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("user32.dll"), "str", "SendMessageW")[0]
        ConsoleWrite("$hGUI: " & Hex($hGUI) & @CRLF)
        ConsoleWrite("$pSendMessage: " & Hex($pSendMessage) & @CRLF)
        ConsoleWrite("$iMsg: " & Hex($iMsg) & @CRLF)
    EndIf

    If @AutoItX64 Then Return MsgBox(0, "Error", "This is a x86 Sample :(")  ;add x64 code yourself

    Local $pRemoteCode = _MemVirtualAlloc(0, 96, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
    If Not $pRemoteCode Then MsgBox(0, "Error", "_MemVirtualAlloc :(")
    Local $tCodeBuffer = DllStructCreate("byte[96]", $pRemoteCode)
    Local $hHandle = DllCallbackRegister($Function, "int", "ptr") ;hardcode one parameter

    Local $sOPCode = "0x68" & SwapEndian($pRemoteCode + 30) & _
            "8D4424085068" & SwapEndian($iMsg) & "68" & SwapEndian($hGUI) & _
            "B8" & SwapEndian($pSendMessage) & "FFD0C20400" & _
            SwapEndian(DllCallbackGetPtr($hHandle)) & "01000000"

    DllStructSetData($tCodeBuffer, 1, $sOPCode)
    ConsoleWrite("$tCodeBuffer: " & DllStructGetData($tCodeBuffer, 1) & @CRLF)

    Return $pRemoteCode

EndFunc   ;==>_RegisterSyncCallback

Func RegisterSyncCallback_Msg($hWnd, $iMsg, $wParam, $lParam)
    ConsoleWrite(">RegisterSyncCallback_Msg Called" & @CRLF)
    ConsoleWrite("$hWnd: " & Hex($hWnd) & @CRLF)
    ConsoleWrite("$iMsg: " & Hex($iMsg) & @CRLF)
    ConsoleWrite("$wParam: " & Hex($wParam) & @CRLF)
    ConsoleWrite("$lParam: " & Hex($lParam) & @CRLF)
    Local $tStruct = DllStructCreate("ptr pFunction", $lParam)
    Local $tStructParameters = DllStructCreate("ptr NParameters", $lParam + 4)
    Local $tStructParametersValue = DllStructCreate("ptr Value", $wParam)

    ConsoleWrite("$tStruct.pFunction: " & $tStruct.pFunction & @CRLF)
    ConsoleWrite("$tStructParameters.NParameters: " & $tStructParameters.NParameters & @CRLF)
    ConsoleWrite("$tStructParametersValue.Value: " & $tStructParametersValue.Value & @CRLF)
    DllCallAddress("int", $tStruct.pFunction, "int", $tStructParametersValue.Value)
    Return 1
EndFunc   ;==>RegisterSyncCallback_Msg

Func SwapEndian($hex)
    Return Hex(BitOR(BitOR(BitOR(BitShift($hex, 24), _
            BitAND(BitShift($hex, -8), 0x00FF0000)), _
            BitAND(BitShift($hex, 8), 0x0000FF00)), _
            BitShift($hex, -24)), 8)
EndFunc   ;==>SwapEndian

 

 

Saludos

Link to comment
Share on other sites

@Danyfirex Thanks for the code :)
I do not understand Assembly code so I will not be able to modify the code as per my need.

few question:
1) _DllCallBackRegisterNormal create 2 different thread then why no new thread created in case of _RegisterSyncCallback?

2) when use CreateThread in loop _DllCallBackRegisterNormal create 5 different thread but _RegisterSyncCallback run only once why?

For $i = 1 to 5
    DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $pCB, "ptr", 124, "long", 0, "int*", 0)
Next

3) If I want to change this from 1 param to 4 param what change should I made to Assembly code?

DllCallbackRegister($Function, "int", "ptr") ;hardcode one parameter

 

test code:

#include <winapi.au3>
#include <Memory.au3>

MsgBox(0, "Main Thread", "GetCurrentThreadId: " & DllCall("kernel32.dll", "dword", "GetCurrentThreadId")[0])

Local $pCB = _RegisterSyncCallback(_MyFn)
;Local $pCB = _DllCallBackRegisterNormal(_MyFn)

;~ DllCallAddress("int", $pCB, "int", 123)

For $i = 1 to 5
    DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $pCB, "ptr", 124, "long", 0, "int*", 0)
Next

MsgBox(0, "", "Click To Exit")
Exit



Func _MyFn($arg)
    MsgBox(0, "_MyFn - Child Thread", "GetCurrentThreadId: " & DllCall("kernel32.dll", "dword", "GetCurrentThreadId")[0] & @CRLF & "$arg:  " & Int($arg))
EndFunc   ;==>_MyFn


Func _DllCallBackRegisterNormal($Function)
    Local $hHandle = DllCallbackRegister($Function, "int", "ptr")
    Return DllCallbackGetPtr($hHandle)
EndFunc   ;==>_DllCallBackRegisterNormal


Func _RegisterSyncCallback($Function, $iOptions = 0, $iParamCount = 0)
    Local Static $hGUI
    Local Static $pSendMessage
    Local Static $iMsg

    If Not $hGUI Then
        $hGUI = GUICreate("RegisterSyncCallback_Msg", 300, 200)
        $iMsg = 0x8000
        GUIRegisterMsg($iMsg, RegisterSyncCallback_Msg)
        $pSendMessage = DllCall("Kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("user32.dll"), "str", "SendMessageW")[0]
        ConsoleWrite("$hGUI: " & Hex($hGUI) & @CRLF)
        ConsoleWrite("$pSendMessage: " & Hex($pSendMessage) & @CRLF)
        ConsoleWrite("$iMsg: " & Hex($iMsg) & @CRLF)
    EndIf

    If @AutoItX64 Then Return MsgBox(0, "Error", "This is a x86 Sample :(")  ;add x64 code yourself

    Local $pRemoteCode = _MemVirtualAlloc(0, 96, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
    If Not $pRemoteCode Then MsgBox(0, "Error", "_MemVirtualAlloc :(")
    Local $tCodeBuffer = DllStructCreate("byte[96]", $pRemoteCode)
    Local $hHandle = DllCallbackRegister($Function, "int", "ptr") ;hardcode one parameter

    Local $sOPCode = "0x68" & SwapEndian($pRemoteCode + 30) & _
            "8D4424085068" & SwapEndian($iMsg) & "68" & SwapEndian($hGUI) & _
            "B8" & SwapEndian($pSendMessage) & "FFD0C20400" & _
            SwapEndian(DllCallbackGetPtr($hHandle)) & "01000000"

    DllStructSetData($tCodeBuffer, 1, $sOPCode)
    ConsoleWrite("$tCodeBuffer: " & DllStructGetData($tCodeBuffer, 1) & @CRLF)

    Return $pRemoteCode

EndFunc   ;==>_RegisterSyncCallback

Func RegisterSyncCallback_Msg($hWnd, $iMsg, $wParam, $lParam)
    ConsoleWrite(">RegisterSyncCallback_Msg Called" & @CRLF)
    ConsoleWrite("$hWnd: " & Hex($hWnd) & @CRLF)
    ConsoleWrite("$iMsg: " & Hex($iMsg) & @CRLF)
    ConsoleWrite("$wParam: " & Hex($wParam) & @CRLF)
    ConsoleWrite("$lParam: " & Hex($lParam) & @CRLF)
    Local $tStruct = DllStructCreate("ptr pFunction", $lParam)
    Local $tStructParameters = DllStructCreate("ptr NParameters", $lParam + 4)
    Local $tStructParametersValue = DllStructCreate("ptr Value", $wParam)

    ConsoleWrite("$tStruct.pFunction: " & $tStruct.pFunction & @CRLF)
    ConsoleWrite("$tStructParameters.NParameters: " & $tStructParameters.NParameters & @CRLF)
    ConsoleWrite("$tStructParametersValue.Value: " & $tStructParametersValue.Value & @CRLF)
    DllCallAddress("int", $tStruct.pFunction, "int", $tStructParametersValue.Value)
    Return 1
EndFunc   ;==>RegisterSyncCallback_Msg

Func SwapEndian($hex)
    Return Hex(BitOR(BitOR(BitOR(BitShift($hex, 24), _
            BitAND(BitShift($hex, -8), 0x00FF0000)), _
            BitAND(BitShift($hex, 8), 0x0000FF00)), _
            BitShift($hex, -24)), 8)
EndFunc   ;==>SwapEndian

 

Edited by jugador
Link to comment
Share on other sites

  • Solution

Here a sample for passing two parameters (You would need to make it more dinamically)

#include <winapi.au3>
#include <Memory.au3>





MsgBox(0, "Main Thread", "GetCurrentThreadId: " & DllCall("kernel32.dll", "handle", "GetCurrentThread")[0])


Local $pCB = _RegisterSyncCallback(_MyFn, 2)
;~ Local $pCB = _DllCallBackRegisterNormal(_MyFn)

Local $tParameters = DllStructCreate("int Value1;int Value2")
$tParameters.Value1 = 10
$tParameters.Value2 = 30
;~ DllCallAddress("int", $pCB, "ptr", DllStructGetPtr($tParameters))

ConsoleWrite("DllStructGetPtr($tParameters): " & DllStructGetPtr($tParameters) & @CRLF)
DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $pCB, "ptr", DllStructGetPtr($tParameters), "long", 0, "int*", 0)


MsgBox(0, "", "Click To Exit")

Exit


Func _MyFn($arg1,$arg2)
    MsgBox(0, "_MyFn - Child Thread", "GetCurrentThreadId: " & DllCall("kernel32.dll", "handle", "GetCurrentThread")[0] & @CRLF & "$arg1:  " & Int($arg1) & @CRLF & "$arg2:  " & Int($arg2))
EndFunc   ;==>_MyFn


Func _DllCallBackRegisterNormal($Function)
    Local $hHandle = DllCallbackRegister($Function, "int", "ptr")
    Return DllCallbackGetPtr($hHandle)
EndFunc   ;==>_DllCallBackRegisterNormal


Func _RegisterSyncCallback($Function, $iParamCount = 0, $iOptions = 0)
    Local Static $hGUI
    Local Static $pSendMessage
    Local Static $iMsg

    If Not $hGUI Then
        $hGUI = GUICreate("RegisterSyncCallback_Msg", 300, 200)
        $iMsg = 0x8000
        GUIRegisterMsg($iMsg, RegisterSyncCallback_Msg)
        $pSendMessage = DllCall("Kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("user32.dll"), "str", "SendMessageW")[0]
        ConsoleWrite("$hGUI: " & Hex($hGUI) & @CRLF)
        ConsoleWrite("$pSendMessage: " & Hex($pSendMessage) & @CRLF)
        ConsoleWrite("$iMsg: " & Hex($iMsg) & @CRLF)
    EndIf

    If @AutoItX64 Then Return MsgBox(0, "Error", "This is a x86 Sample :(")  ;add x64 code yourself

    Local $pRemoteCode = _MemVirtualAlloc(0, 96, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
    If Not $pRemoteCode Then MsgBox(0, "Error", "_MemVirtualAlloc :(")
    Local $tCodeBuffer = DllStructCreate("byte[96]", $pRemoteCode)
    Local $hHandle = DllCallbackRegister($Function, "int", "int;int") ;hardcode one parameter

    Local $sOPCode = "0x68" & SwapEndian($pRemoteCode + 30) & _
            "8D4424085068" & SwapEndian($iMsg) & "68" & SwapEndian($hGUI) & _
            "B8" & SwapEndian($pSendMessage) & "FFD0C2" & StringLeft(SwapEndian($iParamCount * 4), 4) & _
            SwapEndian(DllCallbackGetPtr($hHandle)) & SwapEndian($iParamCount)

    DllStructSetData($tCodeBuffer, 1, $sOPCode)
    ConsoleWrite("$tCodeBuffer: " & DllStructGetData($tCodeBuffer, 1) & @CRLF)

    Return $pRemoteCode

EndFunc   ;==>_RegisterSyncCallback

Func RegisterSyncCallback_Msg($hWnd, $iMsg, $wParam, $lParam)
    ConsoleWrite(">RegisterSyncCallback_Msg Called" & @CRLF)
    ConsoleWrite("$hWnd: " & Hex($hWnd) & @CRLF)
    ConsoleWrite("$iMsg: " & Hex($iMsg) & @CRLF)
    ConsoleWrite("$wParam: " & Hex($wParam) & @CRLF)
    ConsoleWrite("$lParam: " & Hex($lParam) & @CRLF)
    Local $tStruct = DllStructCreate("ptr pFunction", $lParam)
    Local $tNParameters = DllStructCreate("ptr NParameters", $lParam + 4)
    Local $tStructParameters = DllStructCreate("ptr", $wParam)

    ConsoleWrite("$tStruct.pFunction: " & $tStruct.pFunction & @CRLF)
    ConsoleWrite("$tNParameters.NParameters: " & $tNParameters.NParameters & @CRLF)
    Local $aValues[$tNParameters.NParameters]
    For $i = 0 To $tNParameters.NParameters - 1
        $aValues[$i] = DllStructGetData(DllStructCreate("int", DllStructGetData($tStructParameters, 1) + ($i * 4)),1)
        ConsoleWrite($aValues[$i] & @CRLF)
    Next
    DllCallAddress("int", $tStruct.pFunction, "int", $aValues[0],"int",$aValues[1])
    Return 1
EndFunc   ;==>RegisterSyncCallback_Msg

Func SwapEndian($hex)
    Return Hex(BitOR(BitOR(BitOR(BitShift($hex, 24), _
            BitAND(BitShift($hex, -8), 0x00FF0000)), _
            BitAND(BitShift($hex, 8), 0x0000FF00)), _
            BitShift($hex, -24)), 8)
EndFunc   ;==>SwapEndian

1: Don't now ask to the owner of the function haha (just don't want to look deeply)

 

2:I seems to be it needs some code interaction  before run the other threads, sleep works

For $i = 1 to 5
    $tParameters.Value1=$i
    DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $pCB, "ptr",DllStructGetPtr($tParameters), "long", 0, "int*", 0)
    Sleep(100) ;need some autoit interaction
Next

3: Already added using to struct and checking in the structure parameters but AutoIt does not allow to push parameters as ahk so you need to probably add some if with @NumParams.  

 

Saludos

Link to comment
Share on other sites

I tried @trancexx _WinHttpSetStatusCallback example using @Danyfirex _RegisterSyncCallback funcation it worked :)

 

next is to try @ProgAndy _WinHttpSetStatusCallback code to see if it work without crash :sweating:

Edit:
_WinHttpSetStatusCallback code by @ProgAndy run smoothly without crash using @Danyfirex _RegisterSyncCallback funcation :)
for testing try EnumWindows using _RegisterSyncCallback funcation that also worked :cheer:.

 

again Thanks @Danyfirex for helping me :) :) :) :)

Edited by jugador
Link to comment
Share on other sites

@Danyfirex Hopefully one last question to understand code better :D

1) How you get value 30 ? => ($pRemoteCode + 30)        
what this 30 define :sweating:

Local $sOPCode = "0x68" & SwapEndian($pRemoteCode + 30) & _
.......

 

2) If I want to send more data using $lParam then there is nothing wrong?
because I send extra data using DllStruct and it worked.

Local $sOPCode = "0x68" & SwapEndian($pRemoteCode + 30) & _
        "8D4424085068" & SwapEndian($iMsg) & "68" & SwapEndian($hGUI) & _
        "B8" & SwapEndian($pSendMessage) & "FFD0C2" & StringLeft(SwapEndian($iParamCount * 4), 4) & _
        SwapEndian(DllCallbackGetPtr($hHandle)) & SwapEndian($iParamCount) & _
        SwapEndian(DllStructGetPtr($tExtradata))    ;<<== added this line and it worked.
Edited by jugador
Link to comment
Share on other sites

30 is the number of bytes in the opcode till 

 p := NumPut((InStr(Options, "C") ? 0 : ParamCount*4), p+0, "short")
"char"  1
  p+4   4
"int"   4
"char"  1
"char"  1
"int"   4
"char"  1
"int"   4
"char"  1
"int"   4
"short" 2
"char"  1
"short" 2

 

 

Saludos

Edited by Danyfirex
Link to comment
Share on other sites

@argumentum what better code :huh2: as I know nothing about machine code :sweating:.
I used the code provided by @Danyfirex and to me that's the better code {marked as solved:)

and to make the @ProgAndy code work you have make change to the DllCallAddress.

DllCallAddress("none", $tStruct.pFunction, _
                        "handle",       $aValues[0], _          ;~ $hInternet
                        "dword_ptr",    $aValues[1], _          ;~ $iContext
                        "dword",        $aValues[2], _          ;~ $iInternetStatus
                        "ptr",          $aValues[3], _          ;~ $pStatusInformation
                        "dword",        $aValues[4])            ;~ $iStatusInformationLength

 

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...