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')
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 晕倒搞了半天原来是有人在后台搞动作代码标签没了 压成ZIP不就好了么。老少皆宜 afan 发表于 2019-9-17 23:19
A大这样定义,如果碰到查找的数据刚好在上组和下组之间呢,还需要再将上次读取的数据连接当前的查找一次{:face (460):} afan 发表于 2019-9-17 23:19
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 afan 发表于 2019-9-17 23:21
晕倒搞了半天原来是有人在后台搞动作代码标签没了
折腾插件,最开始,搞的 code au3 不能共存。
现在Ok的了,不影响之前的。 标签 pre
繁星 发表于 2019-9-18 00:55
A大这样定义,如果碰到查找的数据刚好在上组和下组之间呢,还需要再将上次读取的数据连接当前的查找一次{ ...
有这问题没完善 haijie1223 发表于 2019-9-18 01:28
a版辛苦了,stringinstr完全可以啊,楼主非要挖坑
我是一直用stringinstr查找定值二进制数据的,不过查找的位置和他的不同,以为不是他需要的,没想到mod一下就行,阿杰帅如发哥 绿色风 发表于 2019-9-18 02:48
折腾插件,最开始,搞的 code au3 不能共存。
现在Ok的了,不影响之前的。 标签 pre
...
奈斯 辛苦了~ 谢谢两位老大! 本帖最后由 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')
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 难得这么多高手一起粗现....
:face (7): 不错不错,学习了 与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
_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
Case 1
If StringInStr($res, 'NotPackedException: not packed by UPX') Then
_Patch($OpenFile)
EndIf
Case 0
If StringInStr($res, 'Tested 1 file') Then
Local $TipPos
_WindowGetPos($hGUI, $TipPos)
ToolTip('正在备份程序->"' & $OpenFile & '"', $TipPos, $TipPos, Default, 0, 4)
FileCopy($OpenFile, $TestPath & $TestPath & $TestPath & $TestPath & '.packed', 1)
_WindowGetPos($hGUI, $TipPos)
ToolTip('正在备份程序->"' & $OpenFile & '"', $TipPos, $TipPos, Default, 0, 4)
$sCmd = @ComSpec & ' /c ""' & $UpxPath & '"'
$sCmd &= ' -d ' & '"' & $OpenFile & '"'
Local $res1 = _Std($sCmd)
Switch $res1
Case 0
If StringInStr($res1, '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
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, $TipPos, Default, 0, 4)
AdlibRegister('_CloseToolTip', 3000)
WinSetTitle($hGUI, '', 'Compresspackage')
Return SetError(1, 0, 0)
EndIf
_WindowGetPos($hGUI, $TipPos)
ToolTip('正在备份程序->"' & $OpenFile & '"', $TipPos, $TipPos, Default, 0, 4)
FileCopy($OpenFile, $TestPath & $TestPath & $TestPath & $TestPath & '.bak', 1)
_WindowGetPos($hGUI, $TipPos)
ToolTip('正在修补程序->"' & $OpenFile & '"', $TipPos, $TipPos, 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 + 1]
For $i = 0 To $nAmt - 1
$nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
$nSize = $nSize + 1
$pFileName = DllStructCreate("char[" & $nSize & "]")
DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", _
DllStructGetPtr($pFileName), "int", $nSize)
$aDroppedFiles += 1
$aDroppedFiles[$aDroppedFiles] = DllStructGetData($pFileName, 1)
$pFileName = 0
Next
ReDim $aDroppedFiles[$aDroppedFiles + 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 = $cLeft
$aArray = $cBottom
EndFunc ;==>_WindowGetPos
Func _Std($cmdline)
Local $res, $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 = 1
$Res = BinaryToString($serr)
Else
$res = 0
$Res = BinaryToString($sout)
EndIf
Return $res
EndFunc ;==>_Std
页:
1
[2]