Jump to content

[SOLVED] Using dUP2's search 'n' replace patch engine in AutoIt3


Recommended Posts

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,
 

Link to post
Share on other sites

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

Link to post
Share on other sites

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

Link to post
Share on other sites

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,
 

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By rmckay
      I'm trying to understand the use of TreeWalker and DllCall()s.  My ultimate goal is to use TreeWalker to list all children of webpages.  I've been working through the files for UIASpy to understand the logic.  After a weeks worth of searching for examples I'm still stuck on the reason for the repeated use of DllCalls in most of the functions.  Here is an example - the function 'UIASpy_CheckWindows()' (located in UIASpy_Elements.au3) is called from file UIASpy_Gui.au3.  In the function the following DllCall is used:
      DllCall( "user32.dll", "lresult", "SendMessageW", "hwnd", $hTV, "uint", $TVM_GETITEMW, "wparam", 0, "struct*", $tItem ) I understand that the function 'SendMessageW' in 'user32.dll' sends a message to the window $hTV.  The message is '$TVM_GETNEXTITEM' and '$tItem' is a struct with additional information - Microsoft Doc -https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagew.  The window $hTV is created in UIASpy_Gui.au3 and that's where I get lost.  Is there code in UIASpy_Gui.au3 that handles this message?  I don't know what to look for.  This procedure - Function called that contains DllCall (SendMessage) is repeatedly used.  Thanks in advance.
×
×
  • Create New...