找回密码
 加入
搜索
查看: 663|回复: 4

【未解决】hook send函数后,调用CALL程序卡死是什么原因,有3个实例

[复制链接]
发表于 2023-7-15 07:18:35 | 显示全部楼层 |阅读模式
本帖最后由 3131210 于 2023-7-22 10:31 编辑

内附3个实例和一个小程序   



实例1是可以正常调用程序的CALL(没有hook send)   
实例2是正常hook send,也不会出问题
实例1和2分别单独运行也没有问题
实例3是实例1和2放到一起,send的封包内容也可以正常读到内容但是调用call的时候程序就卡死,是什么原因,想知道怎么解决?



钩子函数是用的p版的,但是好像5月份就没来论坛看看咯

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2023-7-19 19:54:49 | 显示全部楼层
猜测可能是跟RTApiHook32.au3里面的   _RTApiHookStartup 这个函数有关

如果是单线程导致的阻塞卡死,修改代码里的句柄指向其他进程,都会hook失败,只能指向本进程   $hWnd = ControlGetHandle("___AutoIt3_ApiHook_", "", "Edit1")

不知道有没有大神能找到原因

Func _RTApiHookStartup()
        Local Static $iFlags

        If $iFlags Then Return
        AutoItWinSetTitle("___AutoIt3_ApiHook_")

        Local $hWnd, $bCode, $hThread, $pCallAddr

        Local Const $pSetWindowLongW = _RTGetProcAddress("User32.dll", "SetWindowLongW")
        Local Const $pCallWindowProcW = _RTGetProcAddress("User32.dll", "CallWindowProcW")
        Local Const $pReadProcessMemory = _RTGetProcAddress("Kernel32.dll", "ReadProcessMemory")

        $hWnd = ControlGetHandle("___AutoIt3_ApiHook_", "", "Edit1")

        $pCallAddr = _RTVirtualAlloc(512)
        $bCode = "0x" & _
                "55" & _
                "8BEC" & _
                "FF7508" & _
                "6AFC" & _
                "68" & _RTLongPtrToBytes($hWnd) & _
                "B8" & _RTLongPtrToBytes($pSetWindowLongW) & _
                "FFD0" & _
                "A3" & _RTLongPtrToBytes($pCallAddr + 508) & _
                "5DC20400" & _
                "90" & _
                "55" & _
                "8BEC" & _
                "817D0C8A3F0000" & _
                "74" & Hex(29, 2) & _
                "FF7514" & _
                "FF7510" & _
                "FF750C" & _
                "FF7508" & _
                "FF35" & _RTLongPtrToBytes($pCallAddr + 508) & _
                "B8" & _RTLongPtrToBytes($pCallWindowProcW) & _
                "FFD0" & _
                "5D" & _
                "C21000" & _
                "53" & _                        ; push ebx
                "51" & _                        ; push ecx
                "83EC08" & _                        ; sub esp, 8
                "8BDC" & _                        ; mov ebx, esp
                "53" & _                        ; push ebx
                "6A04" & _                        ; push 4
                "8D4B04" & _                        ; lea ecx, dword ptr [ebx+4]
                "51" & _                        ; push ecx
                "8B4D14" & _                        ; mov ecx, dword ptr [ebp+14]
                "83C11C" & _                        ; add ecx, 1c
                "51" & _                        ; push ecx
                "FF7510" & _                        ; push dword ptr [ebp+10], hProcess
                "B8" & _RTLongPtrToBytes($pReadProcessMemory) & _
                "FFD0" & _                        ; call eax
                "8B442404" & _                        ; mov eax, dword ptr [esp+4]
                "FF7514" & _                        ; push dword ptr [ebp+14]
                "FF7510" & _                        ; push dword ptr [ebp+10]
                "FFD0" & _                        ; call eax
                "83C408" & _                        ; add esp, 8
                "59" & _                        ; pop ecx
                "5B" & _                        ; pop ebx
                "5D" & _                        ; pop ebp
                "C21000"                        ; ret 10

        _RTInject($pCallAddr, $bCode)

        $hThread = _RTCreateThread($pCallAddr, $pCallAddr + 30)
        _RTWaitForObject($hThread)
        _RTCloseHandle($hThread)

        $iFlags = 1
        Return $hWnd
EndFunc        ;==>_RTApiHookStartup


发表于 2023-7-20 16:27:32 | 显示全部楼层
主线程和远程线程互相等待导致卡死。NewMemoryDll.au3文件中,把 _CallAsmCreate 函数 的
 $_Wait = _WinAPI_WaitForSingleObject($hRThwnd, $iTimeOut)  
这一句代码改成
 Sleep(100) 
试试。

评分

参与人数 1金钱 +30 收起 理由
3131210 + 30 很给力!

查看全部评分

 楼主| 发表于 2023-7-20 22:40:33 | 显示全部楼层
本帖最后由 3131210 于 2023-7-21 10:41 编辑

改成这样后,确实不卡死了
但是CALL的结果就变了,返回变成00 00 00 00
本来CALL的返回值应该是 94 17 7F 00


====================================
上面的问题应该是调用CALL的时候,调用方式的问题,感谢大佬的回复


                $_Wait = _WinAPI_WaitForSingleObject($hRThwnd, $iTimeOut)   

                $hExitCode = GetExitCodeThread($hRThwnd)      
               
                去掉上面两行代码,我改成了下面这样,如果只是sleep的话 要么太久,要么没执行完
                查了帮助 GetExitCodeThread 的返回值 $STILL_ACTIVE= 0x00000103 (259) 表示线程还在活动,没有结束,依据这个返回值进行判断是否已经结束,去执行下一步就可以了

                Local $_Wait = TimerInit()
                While 1
                        $hExitCode = GetExitCodeThread($hRThwnd)
                        If $hExitCode <> $STILL_ACTIVE Then ExitLoop
                        If $iTimeOut > -1 and TimerDiff($_Wait) > $iTimeOut Then ExitLoop
                WEnd


 楼主| 发表于 2023-7-22 10:31:44 | 显示全部楼层
本帖最后由 3131210 于 2023-7-22 10:38 编辑
haijie1223 发表于 2023-7-20 16:27
主线程和远程线程互相等待导致卡死。NewMemoryDll.au3文件中,把 _CallAsmCreate 函数 的
这一句代码改成
...

自己手动调用已经没问题了

今天发现一个问题,如果是通过定时器_WinAPI_SetTimer调用,还是不正常
GetExitCodeThread返回的值一直是 $STILL_ACTIVE = 0x00000103
如果改成sleep   就不能成功调用CALL,而是等到超时后,继续执行后面的代码  强制结束线程

是跟_WinAPI_SetTimer有冲突吗?

<NewMemoryDll.au3>
改成Sleep(1000)



实例3改了下面的代码    增加了自动调用的按钮     就不行了
Global $tHooksend, $_Auto_Timer = 1000
Global $_Auto_hTimerProc = DllCallbackRegister('_Auto', 'none', 'hwnd;uint;uint_ptr;dword')

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate($Win, 330, 260, 193, 125)
$Button1 = GUICtrlCreateButton("取PID", 56, 24, 75, 25, 0)
$Button2 = GUICtrlCreateButton("吃红", 56, 80, 75, 25, 0)
$Button3 = GUICtrlCreateButton("吃蓝", 56, 112, 75, 25, 0)
$Button4 = GUICtrlCreateButton("回城", 176, 80, 75, 25, 0)
$Button5 = GUICtrlCreateButton("冰系", 56, 160, 75, 25, 0)
$Button6 = GUICtrlCreateButton("火系", 176, 160, 75, 25, 0)
$Button7 = GUICtrlCreateButton("打开", 176, 24, 75, 25, 0)

$Button8 = GUICtrlCreateButton("自动", 56, 190, 75, 25, 0)
$Button9 = GUICtrlCreateButton("停止", 176, 190, 75, 25, 0)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        If IsDllStruct($tHooksend) Then _RTApiUnhook($w_Handle, $pSend, DllStructGetData($tHooksend, 'Entrypoint')) ;卸载钩子
                        _WinAPI_KillTimer(0, $_Auto_Timer)
                        DllCallbackFree($_Auto_hTimerProc)
                        If $w_Handle <> 0 Then _WinAPI_CloseHandle($w_Handle) ;关闭进程句柄
                        AsmExit($Asm) ;释放ASM模块
                        Exit
                Case $Button1
                        $Hawd = WinGetHandle($Name) ;取窗口句柄
                        If $Hawd <> 0 Then
                                GetWindowThreadProcessId($Hawd, $pid) ;取窗口进程PID
                                $w_Handle = OpenProcess($pid) ;打开进程句柄
                                If $w_Handle = 0 Then
                                        MsgBox(0, $Win, "打不开进程")
                                Else
                                        $tHooksend = _RTApiHookEx($w_Handle, $pSend, 4, $pCallBack, $APIHOOK_Flags_Default) ;挂钩hook send函数
                                        MsgBox(0, "取窗口ID", "窗口句柄:" & $Hawd & " 窗口PID:" & $pid & " 打开进程:" & $w_Handle)
                                EndIf
                        Else
                                MsgBox(0, $Win, "窗口《游戏找CALL练习实例one》不存在!")
                        EndIf
                Case $Button2
                        If $Hawd <> 0 Then _Send(0x00453028) ;;传参,调用CALL
                Case $Button3
                        If $Hawd <> 0 Then _Send(0x00453040)
                Case $Button4
                        If $Hawd <> 0 Then _Send(0x0045305C) ;;传参,调用CALL
                Case $Button5
                        If $Hawd <> 0 Then _SendGj(0x0045307C, 1) ;;传参,调用CALL
                Case $Button6
                        If $Hawd <> 0 Then _SendGj(0x0045309C, 2) ;;传参,调用CALL
                Case $Button7
                        If ProcessExists("游戏找CALL练习实例one.exe") = 0 Then Run("游戏找CALL练习实例one.exe")
                Case $Button8
                        $_Auto_Timer = _WinAPI_SetTimer(0, $_Auto_Timer, 3000, DllCallbackGetPtr($_Auto_hTimerProc))
                Case $Button9
                        _WinAPI_KillTimer(0, $_Auto_Timer)
        EndSwitch
WEnd

;自动
Func _Auto($hWnd, $iMsg, $iTimerId, $iTime)
        _Send(0x00453028)
EndFunc   ;==>_Auto


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-4-28 00:02 , Processed in 0.080248 second(s), 22 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表