Jump to content

Recommended Posts

Posted (edited)

I do not know how to make it work:

;~ SearchAndReplace proc _targetadress : dword, _searchpattern : dword, _searchmask : dword, _replacepattern : dword,
;~ _replacemask : dword, _patternsize : dword, _searchsize : dword, _patchnumber : dword

;~ Local local_returnvalue : byte ;returns if something was patched
;~ Local local_match : dword ;counts how many matches


Dll ASM code: 
 

;**********************************************************************************************
;* Example (how to use)                                                                       *
;* ------------------------------------------------------------------------------------------ *
;* search : 2A 45 EB ?? C3 ?? EF                                                              *
;* replace: 2A ?? ?? 10 33 C0 ??                                                              *
;*                                                                                            *
;* .data                                                                                      *
;* SearchPattern   db 02Ah, 045h, 0EBh, 000h, 0C3h, 000h, 0EFh                                *
;* SearchMask      db    0,    0,    0,    1,    0,    1,    0   ;(1=Ignore Byte)             *
;*                                                                                            *
;* ReplacePattern  db 02Ah, 000h, 000h, 010h, 033h, 0C0h, 000h                                *
;* ReplaceMask     db    0,    1,    1,    0,    0,    0,    1   ;(1=Ignore Byte)             *
;*                                                                                            *
;* .const                                                                                     *
;* PatternSize     equ 7                                                                      *
;*                                                                                            *
;* .code                                                                                      *
;* push -1                      ;Replace Number (-1=ALL / 2=2nd match ...)                    *
;* push FileSize                ;how many bytes to search from beginning from TargetAdress    *
;* push PatternSize             ;lenght of Pattern                                            *
;* push offset ReplaceMask                                                                    *
;* push offset ReplacePattern                                                                 *
;* push offset SearchMask                                                                     *
;* push offset SearchPattern                                                                  *
;* push TargetAddress           ;the memory address where the search starts                   *
;* call SearchAndReplace                                                                      *
;*                                                                                            *
;* ReturnValue in eax (1=Success 0=Failed)                                                    *
;**********************************************************************************************

.586                    
.model flat, stdcall
option casemap :none

SearchAndReplace PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD

.code
;----this procedure is only for compiling a dll---
align 16
DllEntry proc _hinstance:DWORD, _reason:DWORD, _reserved1:DWORD
    mov eax,1 ;TRUE
    ret
DllEntry endp


align 16
SearchAndReplace proc   _targetadress:dword,_searchpattern:dword,_searchmask:dword,_replacepattern:dword,
            _replacemask:dword,_patternsize:dword,_searchsize:dword,_patchnumber:dword
            
    LOCAL local_returnvalue :byte   ;returns if something was patched
    LOCAL local_match   :dword  ;counts how many matches
    
    pushad
    mov local_returnvalue,0
    mov local_match,0
    
    mov edi,_targetadress
    mov esi,_searchpattern
    mov edx,_searchmask
    mov ebx,_patternsize
    xor ecx,ecx
    
    .while ecx!=_searchsize
        @search_again:
        ;---check if pattern exceed memory---
        mov eax,ecx     ;ecx=raw offset
        add eax,ebx     ;raw offset + patternsize
        cmp eax,_searchsize
        ja @return      ;if (raw offset + patternsize) > searchsize then bad!
        
        push ecx        ;counter
        push esi        ;searchpattern
        push edi        ;targetaddress
        push edx        ;searchmask
        
        mov ecx,ebx     ;ebx=patternsize
        @cmp_mask:
        test ecx,ecx
        je @pattern_found
        cmp byte ptr[edx],1 ;searchmask
        je @ignore
        lodsb           ;load searchbyte to al & inc esi
        scasb           ;cmp al,targetadressbyte & inc edi
        jne @skip
        inc edx         ;searchmask
        dec ecx         ;patternsize
        jmp @cmp_mask
        @ignore:
        inc edi         ;targetadress
        inc esi         ;searchpattern
        inc edx         ;searchmask
        dec ecx         ;patternsize
        jmp @cmp_mask
        
        @skip:
        pop edx
        pop edi         ;targetadress
        pop esi         ;searchpattern
        pop ecx
        
        inc edi         ;targetadress
        inc ecx         ;counter
    .endw
    ;---scanned whole memory size---
    jmp @return 

    @pattern_found:
    inc local_match
    pop edx
    pop edi             ;targetadress
    pop esi
    mov eax,_patchnumber
    cmp eax,-1
    je @replace         
    cmp local_match,eax
    je @replace
    pop ecx             ;counter
    inc edi             ;targetadress
    jmp @search_again
    
    ;---replace pattern---
    @replace:
    mov esi,_replacepattern
    mov edx,_replacemask
    
    xor ecx,ecx
    .while ecx!=ebx         ;ebx=patternsize
        @cmp_mask_2:
        cmp byte ptr[edx],1
        je @ignore_2
        lodsb           ;load replacebyte to al from esi & inc esi
        stosb           ;mov byte ptr[edi],al & inc edi
        jmp @nextbyte
        @ignore_2:
        inc edi         ;targetadress
        inc esi         ;replacepattern
        @nextbyte:
        inc edx         ;replacemask
        inc ecx         ;counter
    .endw
    mov local_returnvalue,1     ;yes, something was patched
    
    ;---search again?---
    pop ecx             ;counter-->scanned size
    cmp _patchnumber,-1
    jne @return
    sub edi,ebx         ;edi=targetadress ; countinue where stopped
    inc edi             ;...
    inc ecx             ;ecx=counter(pointer to offset)  /bug fixed in v2.07
    mov esi,_searchpattern
    mov edx,_searchmask
    jmp @search_again

    ;---return---
    @return:
    popad
    movzx eax,local_returnvalue
    ret
SearchAndReplace endp



end DllEntry

[SOLVED]

snr.dup.search.and.replace.patchengine.sourcecode.src.zip

Edited by Trong

Regards,
 

Posted

The purpose of this work are: search and replace Hex.
I had failed to use the StringReplace() to search and replace short Hex in AutoIt .
I'm looking for other solutions!

Regards,
 

Posted

There are better way to format the code (chage parameter types, etc... but I'm lazy) I hope you got/rewrite the example.

 

Local $sStringSource = "abcde"
Local $tString = DllStructCreate("char Data[" & StringLen($sStringSource) & "]")
$tString.Data = $sStringSource

Local $tSearchPattern = DllStructCreate("byte[1]")
DllStructSetData($tSearchPattern, 1, "c")

Local $tSearchMask = DllStructCreate("byte[1]")
DllStructSetData($tSearchMask, 1, 0, 1)

Local $treplacepattern = DllStructCreate("byte[1]")
DllStructSetData($treplacepattern, 1, Asc("F"), 1)


Local $treplacemask = DllStructCreate("byte[1]")
DllStructSetData($treplacemask, 1, 0, 1)


Local $_targetadress = DllStructGetPtr($tString)
Local $_searchpattern = DllStructGetPtr($tSearchPattern)
Local $_searchmask = DllStructGetPtr($tSearchMask)
Local $_replacepattern = DllStructGetPtr($treplacepattern)
Local $_replacemask = DllStructGetPtr($treplacemask)
Local $_patternsize = 1
Local $_searchsize = DllStructGetSize($tString)
Local $_patchnumber = -1



Local $aRep = DllCall('snr_patchengine.dll', 'BYTE', 'SearchAndReplace', 'DWORD', $_targetadress, 'DWORD', $_searchpattern, 'DWORD', $_searchmask, 'DWORD', $_replacepattern, 'DWORD', $_replacemask, 'DWORD', $_patternsize, 'DWORD', $_searchsize, 'DWORD', $_patchnumber)
ConsoleWrite($aRep[0] & @CRLF)
ConsoleWrite($aRep & @CRLF)
ConsoleWrite($tString.Data & @CRLF)

Saludos

Posted

work perfectly for me.

A better example.

Local $sStringSource = "abcde"
Local $tString = DllStructCreate("char Data[" & StringLen($sStringSource) & "]")
$tString.Data = $sStringSource

Local $tSearchPattern = DllStructCreate("byte[" & StringLen($sStringSource) & "]")
DllStructSetData($tSearchPattern, 1, "abcde")

Local $tSearchMask = DllStructCreate("byte[" & StringLen($sStringSource) & "]")
DllStructSetData($tSearchMask, 1, 0, 1)
DllStructSetData($tSearchMask, 1, 0, 2)
DllStructSetData($tSearchMask, 1, 0, 3)
DllStructSetData($tSearchMask, 1, 0, 4)
DllStructSetData($tSearchMask, 1, 0, 5)

Local $treplacepattern = DllStructCreate("byte[" & StringLen($sStringSource) & "]")
DllStructSetData($treplacepattern, 1, Asc("F"), 1)
DllStructSetData($treplacepattern, 1, Asc("G"), 2)
DllStructSetData($treplacepattern, 1, Asc("D"), 3)
DllStructSetData($treplacepattern, 1, Asc("H"), 4)
DllStructSetData($treplacepattern, 1, Asc("B"), 5)

Local $treplacemask = DllStructCreate("byte[" & StringLen($sStringSource) & "]")
DllStructSetData($treplacemask, 1, 1, 1);avoid a
DllStructSetData($treplacemask, 1, 0, 2)
DllStructSetData($treplacemask, 1, 0, 3)
DllStructSetData($treplacemask, 1, 1, 4) ;avoid d
DllStructSetData($treplacemask, 1, 0, 5)

Local $_targetadress = DllStructGetPtr($tString)
Local $_searchpattern = DllStructGetPtr($tSearchPattern)
Local $_searchmask = DllStructGetPtr($tSearchMask)
Local $_replacepattern = DllStructGetPtr($treplacepattern)
Local $_replacemask = DllStructGetPtr($treplacemask)
Local $_patternsize = DllStructGetSize($treplacepattern)
Local $_searchsize = DllStructGetSize($tString)
Local $_patchnumber = -1



Local $aRep = DllCall('snr_patchengine.dll', 'BYTE', 'SearchAndReplace', 'DWORD', $_targetadress, 'DWORD', $_searchpattern, 'DWORD', $_searchmask, 'DWORD', $_replacepattern, 'DWORD', $_replacemask, 'DWORD', $_patternsize, 'DWORD', $_searchsize, 'DWORD', $_patchnumber)
ConsoleWrite($aRep[0] & @CRLF)
ConsoleWrite($aRep & @CRLF)
ConsoleWrite($tString.Data & @CRLF)

Do it more dynamically.

Saludos

Posted

Completing the function:

Code 1 (include dll on script):

ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "00", "99") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)


ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "00??", "0066") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)


ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "33??33", "55??77") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)


ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "0033??11", "77332?66") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)

Func _BinarySearchAndReplace($sStringHex, $sSearch, $sReplace)
    If (StringLeft($sStringHex, 2) = "0x") Then $sStringHex = StringTrimLeft($sStringHex, 2)
    If (StringLen($sStringHex) = 0) Or (StringLen($sSearch) = 0) Then Return SetError(-1, 0, $sStringHex);Not think to replace
    If @AutoItX64 Then Return SetError(1, 0, $sStringHex);Dll only for 32-bit
    ;--------------------------------------------------------- Begin create temp dll
    Local $sBinaryDll = '4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000C00000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A240000000000000071D4F7DB35B5998835B5998835B59988C9958B8834B59988BBAA8A8834B599885269636835B59988000000000000000000000000000000000000000000000000504500004C010300E8B694560000000000000000E0000E210B01050C00020000000400000000000000100000001000000020000000000010001000000002000004000000000000000400000000000000004000000004000000000000020000000000100000100000000010000010000000000000100000000020000057000000000000000000000000000000000000000000000000000000000000000000000000300000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    $sBinaryDll &= '2E74657874000000B7000000001000000002000000040000000000000000000000000000200000602E7264617461000057000000002000000002000000060000000000000000000000000000400000402E72656C6F6300000C00000000300000000200000008000000000000000000000000000040000042000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    $sBinaryDll &= '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000558BECB801000000C9C20C008D642400558BEC83C4F860C645FF00C745F8000000008B7D088B750C8B55108B5D1C33C9EB2C8BC103C33B45207773515657528BCB85C97420803A017408ACAE750A4249EBEF47464249EBE95A5F5E5947413B4D2075CFEB49FF45F85A5F5E8B452483F8FF74093945F874045947EBB68B75148B551833C9EB0D803A017404ACAAEB02474642413BCB75EFC645FF0159837D24FF750C2BFB47418B750C8B5510EB84610FB645FFC9C2200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    $sBinaryDll &= '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8B694560000000032200000010000000100000001000000282000002C20000030200000101000004620000000004456545F5061746368456E67696E652E646C6C00536561726368416E645265706C616365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    $sBinaryDll &= '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    $sBinaryDll &= '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    Local $sDllFilePath = @TempDir & "\~PE32.dll"
    FileDelete($sDllFilePath)
    Local $hOpenDll = FileOpen($sDllFilePath, 2 + 8 + 16)
    FileWrite($sDllFilePath, Binary('0x' & $sBinaryDll))
    FileClose($hOpenDll)
    If Not FileExists($sDllFilePath) Then Return SetError(-1, 0, $sStringHex);Can not write temp Dll
    ;----------------------------------------------------------- End Cceate temp dll
    ConsoleWrite("+   -IN: " & $sStringHex & @CRLF)
    Local $taStrPtr = DllStructCreate("char Data[" & StringLen($sStringHex) & "]")
    $taStrPtr.Data = $sStringHex
    Local $spStrPtr = DllStructCreate("byte[" & StringLen($sSearch) & "]")
    Local $smStrPtr = DllStructCreate("byte[" & StringLen($sSearch) & "]")
    Local $aStr = StringSplit($sSearch, "")
    For $i = 1 To $aStr[0]
        DllStructSetData($spStrPtr, 1, Asc($aStr[$i]), $i)
        DllStructSetData($smStrPtr, 1, $aStr[$i] = "?" ? 1 : 0, $i);avoid a
    Next
    Local $rpStrPtr = DllStructCreate("byte[" & StringLen($sReplace) & "]")
    Local $tmStrPtr = DllStructCreate("byte[" & StringLen($sReplace) & "]")
    Local $aStr = StringSplit($sReplace, "")
    For $i = 1 To $aStr[0]
        DllStructSetData($rpStrPtr, 1, Asc($aStr[$i]), $i)
        DllStructSetData($tmStrPtr, 1, $aStr[$i] = "?" ? 1 : 0, $i);avoid a
    Next
    Local $_TargetAdress = DllStructGetPtr($taStrPtr)
    Local $_SearchPattern = DllStructGetPtr($spStrPtr)
    Local $_SearchMask = DllStructGetPtr($smStrPtr)
    Local $_ReplacePattern = DllStructGetPtr($rpStrPtr)
    Local $_ReplaceMask = DllStructGetPtr($tmStrPtr)
    Local $_PatternSize = DllStructGetSize($rpStrPtr)
    Local $_SearchSize = DllStructGetSize($taStrPtr)
    Local $aRep = DllCall($sDllFilePath, 'BYTE', 'SearchAndReplace', 'DWORD', $_TargetAdress, 'DWORD', $_SearchPattern, 'DWORD', $_SearchMask, 'DWORD', $_ReplacePattern, 'DWORD', $_ReplaceMask, 'DWORD', $_PatternSize, 'DWORD', $_SearchSize, 'DWORD', -1)
    If @error Or (Not IsArray($aRep)) Then Return SetError(@error, 0, 0)
    $sReplace = "0x" & $taStrPtr.Data
    FileDelete($sDllFilePath)
    Return SetError(@error, 0, $sReplace)
EndFunc   ;==>_BinarySearchAndReplace

 

Code 2: 

 

ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "00", "99") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)


ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "00??", "0066") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)


ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "33??33", "55??77") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)


ConsoleWrite("-   OUT: " & _BinarySearchAndReplace("001122330033221100", "0033??11", "77332?66") & @CRLF)
ConsoleWrite("! Error: " & @error & @CRLF)

Func _BinarySearchAndReplace($sStringHex, $sSearch, $sReplace)
    If (StringLeft($sStringHex, 2) = "0x") Then $sStringHex = StringTrimLeft($sStringHex, 2)
    If (StringLen($sStringHex) = 0) Or (StringLen($sSearch) = 0) Then Return SetError(-1, 0, $sStringHex);Not think to replace
    If @AutoItX64 Then Return SetError(1, 0, $sStringHex);Dll only for 32-bit
    ConsoleWrite("+   -IN: " & $sStringHex & @CRLF)
    Local $taStrPtr = DllStructCreate("char Data[" & StringLen($sStringHex) & "]")
    $taStrPtr.Data = $sStringHex
    Local $spStrPtr = DllStructCreate("byte[" & StringLen($sSearch) & "]")
    Local $smStrPtr = DllStructCreate("byte[" & StringLen($sSearch) & "]")
    Local $aStr = StringSplit($sSearch, "")
    For $i = 1 To $aStr[0]
        DllStructSetData($spStrPtr, 1, Asc($aStr[$i]), $i)
        DllStructSetData($smStrPtr, 1, $aStr[$i] = "?" ? 1 : 0, $i);avoid a
    Next
    Local $rpStrPtr = DllStructCreate("byte[" & StringLen($sReplace) & "]")
    Local $tmStrPtr = DllStructCreate("byte[" & StringLen($sReplace) & "]")
    Local $aStr = StringSplit($sReplace, "")
    For $i = 1 To $aStr[0]
        DllStructSetData($rpStrPtr, 1, Asc($aStr[$i]), $i)
        DllStructSetData($tmStrPtr, 1, $aStr[$i] = "?" ? 1 : 0, $i);avoid a
    Next
    Local $_TargetAdress = DllStructGetPtr($taStrPtr)
    Local $_SearchPattern = DllStructGetPtr($spStrPtr)
    Local $_SearchMask = DllStructGetPtr($smStrPtr)
    Local $_ReplacePattern = DllStructGetPtr($rpStrPtr)
    Local $_ReplaceMask = DllStructGetPtr($tmStrPtr)
    Local $_PatternSize = DllStructGetSize($rpStrPtr)
    Local $_SearchSize = DllStructGetSize($taStrPtr)
    Local $aRep = DllCall('DVT_PatchEngine.dll', 'BYTE', 'SearchAndReplace', 'DWORD', $_TargetAdress, 'DWORD', $_SearchPattern, 'DWORD', $_SearchMask, 'DWORD', $_ReplacePattern, 'DWORD', $_ReplaceMask, 'DWORD', $_PatternSize, 'DWORD', $_SearchSize, 'DWORD', -1)
    If @error Or (Not IsArray($aRep)) Then Return SetError(@error, 0, 0)
    $sReplace = "0x" & $taStrPtr.Data
    Return SetError(@error, 0, $sReplace)
EndFunc   ;==>_BinarySearchAndReplace

 

Regards,
 

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
×
×
  • Create New...