找回密码
 加入
搜索
楼主: chishingchan

[网络通信] 【已解决】关于在可执行文件中查找数据

[复制链接]
发表于 2019-9-17 23:19:39 | 显示全部楼层
本帖最后由 afan 于 2019-9-18 11:36 编辑
chishingchan 发表于 2019-9-17 21:57
老大,顶楼的附件已换了


以下代码已完善至26#

MsgBox(0, '', _BinarySearch('snapshot.exe', '0x534E415345524E554D008F0A'))

Func _BinarySearch($FilePath, $sBin)
        If StringLeft($sBin, 2) = '0x' Then $sBin = StringTrimLeft($sBin, 2)

        Local $hFile = _WinAPI_CreateFile($FilePath, 2, 2, 1)
        If Not $hFile Then Return SetError(1)
        Local $Result = _WinAPI_SetFilePointer($hFile, 0)

        Local $Buffer = DllStructCreate('byte[1024]')
        Local $ptr = DllStructGetPtr($Buffer)
        Local $Read, $Pos
        Do
                $Read = 0
                $Result = _WinAPI_ReadFile($hFile, $ptr, 1024, $Read)
                If Not $Result Then
                        _WinAPI_CloseHandle($hFile)
                        Return SetError(2)
                EndIf
                $Result = StringTrimLeft(DllStructGetData($Buffer, 1), 2)
                $Result = StringInStr($Result, $sBin)
                If $Result > 0 Then
                        $Result = ($Result - 1) / 2
                        ExitLoop
                EndIf
                $Pos += $Read
        Until 0

        _WinAPI_CloseHandle($hFile)
        If Not $Result Then Return SetError(3)
        Return $Pos + $Result
EndFunc   ;==>_BinarySearch

评分

参与人数 1威望 +10 金钱 +200 贡献 +25 收起 理由
chishingchan + 10 + 200 + 25 赞一个!

查看全部评分

发表于 2019-9-17 23:21:05 | 显示全部楼层
晕倒  搞了半天  原来是有人在后台搞动作  代码标签没了
发表于 2019-9-17 23:30:32 | 显示全部楼层
压成ZIP不就好了么。老少皆宜
发表于 2019-9-18 00:55:22 | 显示全部楼层

A大这样定义,如果碰到查找的数据刚好在上组和下组之间呢,还需要再将上次读取的数据连接当前的查找一次

评分

参与人数 1威望 +2 金钱 +50 贡献 +8 收起 理由
chishingchan + 2 + 50 + 8 神马都是浮云

查看全部评分

发表于 2019-9-18 01:28:01 | 显示全部楼层

a版辛苦了,stringinstr完全可以啊,楼主非要挖坑
MsgBox(0, 0, _BinarySearch2($File, $Hex))
Func _BinarySearch2($sFile, $sBin)
        If Not FileExists($sFile) Then Return SetError(1, 0, -1)        
        Local $hFile = FileOpen($sFile, 16)
        Local $bData = FileRead($hFile)
        FileClose($hFile)
        Local $ipos = StringInStr(StringTrimLeft($bData,2), StringTrimLeft($sBin, 2))
        If Not @error Then Return ($ipos - Mod($ipos, 2)) / 2
        Return SetError(2, 0, -1)
EndFunc   ;==>_BinarySearch2

评分

参与人数 1威望 +10 金钱 +200 贡献 +23 收起 理由
chishingchan + 10 + 200 + 23 很给力!

查看全部评分

发表于 2019-9-18 02:48:26 | 显示全部楼层
afan 发表于 2019-9-17 23:21
晕倒  搞了半天  原来是有人在后台搞动作  代码标签没了

折腾插件,最开始,搞的 code  au3 不能共存。

现在Ok的了,不影响之前的。 标签 pre
发表于 2019-9-18 07:12:04 来自手机 | 显示全部楼层
繁星 发表于 2019-9-18 00:55
A大这样定义,如果碰到查找的数据刚好在上组和下组之间呢,还需要再将上次读取的数据连接当前的查找一次{ ...

有这问题  没完善
发表于 2019-9-18 07:16:15 来自手机 | 显示全部楼层
haijie1223 发表于 2019-9-18 01:28
a版辛苦了,stringinstr完全可以啊,楼主非要挖坑

我是一直用stringinstr查找定值二进制数据的,不过查找的位置和他的不同,以为不是他需要的,没想到mod一下就行,阿杰帅如发哥
发表于 2019-9-18 07:18:16 来自手机 | 显示全部楼层
绿色风 发表于 2019-9-18 02:48
折腾插件,最开始,搞的 code  au3 不能共存。

现在Ok的了,不影响之前的。 标签 pre
...

奈斯 辛苦了~
 楼主| 发表于 2019-9-18 07:33:43 | 显示全部楼层
谢谢两位老大!
发表于 2019-9-18 11:17:25 | 显示全部楼层
本帖最后由 afan 于 2019-9-18 11:33 编辑

对于大文件,一次性读取再匹配还是存在效率问题的,因此,分段读取还是有必要,特别是搜索的数据越靠前优势越大,因此完善了一下
#include-once
#include <WinAPI.au3>

Func _BinarySearch($FilePath, $sBin)
        If StringLeft($sBin, 2) = '0x' Then $sBin = StringTrimLeft($sBin, 2)

        Local $hFile = _WinAPI_CreateFile($FilePath, 2, 2, 1)
        If Not $hFile Then Return SetError(1)
        Local $Result = _WinAPI_SetFilePointer($hFile, 0)

        Local $Buffer = DllStructCreate('byte[1024]')
        Local $ptr = DllStructGetPtr($Buffer)
        Local $len = StringLen($sBin)
        Local $Read, $last = '', $_Result, $iPos
        Do
                $Read = 0
                $Result = _WinAPI_ReadFile($hFile, $ptr, 1024, $Read)
                If Not $Result Then
                        _WinAPI_CloseHandle($hFile)
                        Return SetError(2)
                EndIf
                If ($Read / 2) < $len Then
                        _WinAPI_CloseHandle($hFile)
                        Return -1
                EndIf
                
                $Result = StringTrimLeft(DllStructGetData($Buffer, 1), 2)
                $_Result = StringInStr($Result, $sBin)
                If $_Result > 0 Then
                        $_Result = ($_Result - 1) / 2
                        ExitLoop
                Else
                        $_Result = $last & StringMid($Result, 1, $len)
                        $_Result = StringInStr($_Result, $sBin)
                        If $_Result > 0 Then
                                $_Result = ($_Result - 1) / 2
                                $iPos -= $len / 2
                                ExitLoop
                        Else
                                $last = StringMid($Result, 1024 * 2 - $len + 1)
                        EndIf
                EndIf
                $iPos += $Read
        Until 0

        _WinAPI_CloseHandle($hFile)
        If Not $_Result Then Return SetError(3)
        Return $iPos + $_Result
EndFunc   ;==>_BinarySearch

评分

参与人数 1威望 +6 金钱 +100 贡献 +8 收起 理由
chishingchan + 6 + 100 + 8 很给力!

查看全部评分

发表于 2019-9-18 13:16:16 | 显示全部楼层
难得这么多高手一起粗现....
发表于 2019-9-25 14:19:15 | 显示全部楼层
不错不错,学习了
发表于 2019-9-27 10:32:01 | 显示全部楼层
与A版一样,下面这个是替换二进制文件字符串,修改未压缩的autoit程序中类窗口别名


#Region ;**** 由 AccAu3Wrapper_GUI 创建指令 ****
#AccAu3Wrapper_Icon=water_melon.ico
#AccAu3Wrapper_Outfile=Compresspackage.exe
#AccAu3Wrapper_UseX64=n
#AccAu3Wrapper_Res_Language=2052
#AccAu3Wrapper_Res_requestedExecutionLevel=None
#EndRegion ;**** 由 AccAu3Wrapper_GUI 创建指令 ****
#include <math.au3>
#include <file.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#include '_Res.au3'
DllCall('User32.dll', 'BOOL', 'ChangeWindowMessageFilter', 'UINT', 0x0233, 'DWORD', 1)
DllCall('User32.dll', 'BOOL', 'ChangeWindowMessageFilter', 'UINT', 0x0049, 'DWORD', 1)
Global $aDroppedFiles
Global $sSearchStr = 'AutoIt v3 GUI'
Global $rReplaceStr = 'Tubaba GUI'
Global $hGUI = GUICreate('Autoit Exe类名修改', 200, 80, -1, -1, BitOR($WS_POPUPWINDOW, $WS_CAPTION), BitOR($GUI_WS_EX_PARENTDRAG, $WS_EX_ACCEPTFILES))
Global $iButton = GUICtrlCreateButton('打開', 40, 37, 120, 40)
Global $iPic = GUICtrlCreatePic('', 0, 0, 200, 80, BitOR($SS_NOTIFY, $WS_GROUP, $WS_BORDER, $WS_CLIPSIBLINGS), $GUI_WS_EX_PARENTDRAG)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOW)
WinSetOnTop($hGUI, '', 1)
GUIRegisterMsg(0x0233, "WM_DROPFILES")

While 1
        $msg = GUIGetMsg()
        Select
                Case $msg = -3
                        Exit
                Case $msg = $iButton
                        $OpenFile = FileOpenDialog('目标文件', @ScriptDir & '\', '所有文件(*.*)', 1 + 2, '', $hGUI)
                        If @error Then ContinueLoop
                        _Check($OpenFile)
                Case $msg = $GUI_EVENT_DROPPED
                        $OpenFile = $aDroppedFiles[1]
                        _Check($OpenFile)
        EndSelect
WEnd

Func _Check($OpenFile)
        Local $szDrive, $szDir, $szFName, $szExt
        Local $TestPath = _PathSplit($OpenFile, $szDrive, $szDir, $szFName, $szExt)
        Local $UpxPath = _UpxBin()
        Local $sCmd = @ComSpec & ' /c ""' & $UpxPath & '"'
        $sCmd &= ' -t ' & '"' & $OpenFile & '"'
        Local $res = _Std($sCmd)
        Switch $res[0]
                Case 1
                        If StringInStr($res[1], 'NotPackedException: not packed by UPX') Then
                                _Patch($OpenFile)
                        EndIf
                Case 0
                        If StringInStr($res[1], 'Tested 1 file') Then
                                Local $TipPos[2]
                                _WindowGetPos($hGUI, $TipPos)
                                ToolTip('正在备份程序->"' & $OpenFile & '"', $TipPos[0], $TipPos[1], Default, 0, 4)
                                FileCopy($OpenFile, $TestPath[1] & $TestPath[2] & $TestPath[3] & $TestPath[4] & '.packed', 1)
                                _WindowGetPos($hGUI, $TipPos)
                                ToolTip('正在备份程序->"' & $OpenFile & '"', $TipPos[0], $TipPos[1], Default, 0, 4)
                                $sCmd = @ComSpec & ' /c ""' & $UpxPath & '"'
                                $sCmd &= ' -d ' & '"' & $OpenFile & '"'
                                Local $res1 = _Std($sCmd)
                                Switch $res1[0]
                                        Case 0
                                                If StringInStr($res1[1], 'Unpacked 1 file') Then
                                                        _Patch($OpenFile)
                                                EndIf
                                EndSwitch
                        EndIf
                Case Else
                        MsgBox(0, 0, 1)
        EndSwitch
;~         _Patch($OpenFile)
EndFunc   ;==>_Check

Func _Patch($OpenFile)
        WinSetTitle($hGUI, '', '正在處理..' & $OpenFile)
        Local $hFile, $sText, $nBytes, $tBuffer, $Replaced, $TipPos[2]
        Local $szDrive, $szDir, $szFName, $szExt
        Local $TestPath = _PathSplit($OpenFile, $szDrive, $szDir, $szFName, $szExt)
        $hFile = FileOpen($OpenFile, 16)
        $sText = FileRead($hFile)
        FileClose($hFile)
        If Not StringInStr($sText, _Str2UnicodeStr($sSearchStr)) Then
                _WindowGetPos($hGUI, $TipPos)
                ToolTip('无法识别->"' & $OpenFile & '"', $TipPos[0], $TipPos[1], Default, 0, 4)
                AdlibRegister('_CloseToolTip', 3000)
                        WinSetTitle($hGUI, '', 'Compresspackage')
                Return SetError(1, 0, 0)
        EndIf
        _WindowGetPos($hGUI, $TipPos)
        ToolTip('正在备份程序->"' & $OpenFile & '"', $TipPos[0], $TipPos[1], Default, 0, 4)
        FileCopy($OpenFile, $TestPath[1] & $TestPath[2] & $TestPath[3] & $TestPath[4] & '.bak', 1)
        _WindowGetPos($hGUI, $TipPos)
        ToolTip('正在修补程序->"' & $OpenFile & '"', $TipPos[0], $TipPos[1], Default, 0, 4)
        $tBuffer = DllStructCreate("byte[" & BinaryLen($sText) & "]")
        $Search = _Str2UnicodeStr($sSearchStr)
        $Replace = _Str2UnicodeStr($rReplaceStr)
        If StringLen($Search) > StringLen($Replace) Then
                Do
                        $Replace = $Replace & '0'
                Until StringLen($Replace) = StringLen($Search)
                ElseIf StringLen($Search) < StringLen($Replace) Then
                $Replace = StringMid($Replace,1,StringLen($Search))
        EndIf
        
        
        
        
        $Replaced = StringReplace($sText, $Search, $Replace)
        DllStructSetData($tBuffer, 1, $Replaced)
        $hFile = _WinAPI_CreateFile($OpenFile, 2)
        _WinAPI_WriteFile($hFile, DllStructGetPtr($tBuffer), BinaryLen($Replaced), $nBytes)
        _WinAPI_CloseHandle($hFile)
        WinSetTitle($hGUI, '', 'Compresspackage')
        ToolTip('')
        _MSGBOXEX($hGUI, 0, '', '完成')
EndFunc   ;==>_Patch

Func _Str2UnicodeStr($Str)
        Local $Return='',$n = 1
        $Return = StringTrimLeft(StringToBinary($Str,2),2)
        Return $Return
EndFunc

Func _CloseToolTip()
        AdlibUnRegister('_CloseToolTip')
        ToolTip('')
EndFunc   ;==>_CloseToolTip

Func WM_DROPFILES($hWnd, $msgID, $wParam, $lParam)
        Local $nSize, $pFileName
        Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
        $aDroppedFiles = 0
        Dim $aDroppedFiles[$nAmt[0] + 1]
        For $i = 0 To $nAmt[0] - 1
                $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
                $nSize = $nSize[0] + 1
                $pFileName = DllStructCreate("char[" & $nSize & "]")

                DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", _
                                DllStructGetPtr($pFileName), "int", $nSize)
                $aDroppedFiles[0] += 1
                $aDroppedFiles[$aDroppedFiles[0]] = DllStructGetData($pFileName, 1)
                $pFileName = 0
        Next
        ReDim $aDroppedFiles[$aDroppedFiles[0] + 1]
EndFunc   ;==>WM_DROPFILES

Func _MSGBOXEX($hWnd, $flag, $title, $text, $timeout = 0) ;hook msgbox
        Local $hInst = _WinAPI_GetWindowLong($hWnd, $GWL_HINSTANCE)
        Local $iThreadId = _WinAPI_GetCurrentThreadId()
        Local $hCallBack = DllCallbackRegister("_CallBack", "int", "int;hWnd;hWnd")
        Local $pCallBack = DllCallbackGetPtr($hCallBack)
        Local $hHook = _WinAPI_SetWindowsHookEx($WH_CBT, $pCallBack, $hInst, $iThreadId)
        Local $Mkmsg = MsgBox($flag, $title, $text, $timeout, $hWnd)
        _WinAPI_UnhookWindowsHookEx($hHook)
        DllCallbackFree($hCallBack)
        Return $Mkmsg
EndFunc   ;==>_MSGBOXEX

Func _CallBack($iCode, $wParam, $lParam)
        ;If ($iCode = 5) And ($wParam <> $hGUI) Then
        If ($iCode = $WH_CBT) And (_WinAPI_GetParent($wParam) > 0) Then
                Local $WINDOWRECT = DllStructCreate($tagRECT)
                Local $MSGBOXRECT = DllStructCreate($tagRECT)
                Local $WINDOWRECT = _WinAPI_GetWindowRect(_WinAPI_GetParent($wParam))
                Local $MSGBOXRECT = _WinAPI_GetWindowRect($wParam)
                Local $WLeft = DllStructGetData($WINDOWRECT, 'Left')
                Local $WTop = DllStructGetData($WINDOWRECT, 'Top')
                Local $WRight = DllStructGetData($WINDOWRECT, 'Right')
                Local $WBottom = DllStructGetData($WINDOWRECT, 'Bottom')
                Local $MLeft = DllStructGetData($MSGBOXRECT, 'Left')
                Local $MTop = DllStructGetData($MSGBOXRECT, 'Top')
                Local $MRight = DllStructGetData($MSGBOXRECT, 'Right')
                Local $MBottom = DllStructGetData($MSGBOXRECT, 'Bottom')


                Local $X = $WLeft + (($WRight - $WLeft) - ($MRight - $MLeft)) / 2
                Local $Y = $WTop + (($WBottom - $WTop) - ($MBottom - $MTop)) / 2
                WinMove($wParam, "", $X, $Y, Default, Default)

        EndIf
        Return 0
EndFunc   ;==>_CallBack

Func _WindowGetPos($hWnd, ByRef $aArray)
        Local $tRect = _WinAPI_GetWindowRect($hWnd)
        Local $cLeft = DllStructGetData($tRect, 'Left')
        Local $cTop = DllStructGetData($tRect, 'Top')
        Local $cRight = DllStructGetData($tRect, 'Right')
        Local $cBottom = DllStructGetData($tRect, 'Bottom')
        $aArray[0] = $cLeft
        $aArray[1] = $cBottom
EndFunc   ;==>_WindowGetPos

Func _Std($cmdline)
        Local $res[2], $line, $sout, $serr
        Local $pid = Run($cmdline, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
        ProcessWaitClose($pid)
        While 1
                $line = StdoutRead($pid,False,True)
                If @error Then ExitLoop
                $sout &= $line
        WEnd
        While 1
                $line = StderrRead($pid,False,True)
                If @error Then ExitLoop
                $serr &= $line
        WEnd
        StdioClose($pid)
        If Not $serr = '' And Not $pid = 0 Then
                $res[0] = 1
                $Res[1] = BinaryToString($serr)
        Else
                $res[0] = 0
                $Res[1] = BinaryToString($sout)
        EndIf
        Return $res
EndFunc   ;==>_Std


评分

参与人数 1威望 +2 金钱 +50 贡献 +10 收起 理由
chishingchan + 2 + 50 + 10 赞一个!

查看全部评分

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

本版积分规则

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

GMT+8, 2024-12-23 17:44 , Processed in 0.207338 second(s), 15 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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