HelpMemory Editing FindPattern() in Visual Basic?

Posts 1–3 of 3 · Page 1 of 1
Memory Editing FindPattern() in Visual Basic?
Hey,
I googled alot now and didn't really find something that is useful. I need a function to read out memory values through patterns. Is there any possibility in visual basic?

Something like FindPattern() or ScanPattern()?

Does anyone have an example for me maybe?

Kind regards,
xChucky109
http://www.mpgh.net/forum/33-visual-...ory-part1.html
http://www.mpgh.net/forum/33-visual-...ory-part2.html

part one explains a little background info.
part two has 'FindPattern. Code is UGLY, but maybe you can improve it : )

 
code from link 2


Code:
    ''' <summary>
    ''' Scans a process's entire memory range for the specified hex string.
    ''' <param name="hexString">Standard search/mask technique. (** denotes a masked byte.)</param>
    ''' <param name="returnOnFirstOccurance">End scan early if value found?</param>
    ''' </summary>
    Public Function FindPattern(ByVal hexString As String, Optional ByVal returnOnFirstOccurance As Boolean = True) As IntPtr()
        ''format example: 64 8b 15 ** ** ** ** 8b 34 ** 8b 0d ** ** ** ** 89 81
        Dim _hexStringChunks() As String = hexString.Split(" ")
        Dim _hexStringAsBytes(_hexStringChunks.Length - 1) As Byte
        Dim _mask(_hexStringChunks.Length - 1) As Byte

        For xx As Int32 = 0 To _hexStringChunks.Length - 1
            If _hexStringChunks(xx) = "**" Then
                _hexStringAsBytes(xx) = &H0
                _mask(xx) = &H0 'unimportant
            Else
                _hexStringAsBytes(xx) = Byte.Parse(_hexStringChunks(xx), Globalization.NumberStyles.HexNumber)
                _mask(xx) = &H1 'important
            End If
        Next
        Dim _results() As IntPtr = ScanForByteMask(_hexStringAsBytes, _mask, returnOnFirstOccurance)
        Return _results
    End Function
    ''' <summary>
    ''' Scan a process's entire memory range for the specified array of bytes. Function always return an array(). (may specify to return when first occurance is found. If returnOnFirstOccurance=true, array.length will be 1)
    ''' </summary>
    Private Function ScanForBytes(ByVal byteBuff() As Byte, Optional ByVal returnOnFirstOccurance As Boolean = False) As IntPtr()
        If IsAttachedToProcess() = False Then
            Return New IntPtr() {IntPtr.Zero} 'user fail
        End If
        Dim _rtns As New List(Of IntPtr) 'locations (memory addresses) where the buff() was found at
        If Not returnOnFirstOccurance Then _rtns.Capacity = 1000 'could be larger. depends how many results you expect..
        Dim _mbi As MEMORY_BASIC_INFORMATION, _sysInfo As SYSTEM_INFO
        Dim _mbiSize As Int32 = Marshal.SizeOf(_mbi) ' size of mbi struct, in bytes.
        GetSystemInfo(_sysInfo)
        Dim _addr As IntPtr = IntPtr.Zero 'counter/loop control.
        Dim _readBuff(_sysInfo.dwPageSize - 1) As Byte 'small buffer to read small mem regions
        Dim _bigBuff(0) As Byte 'large buffer to read large mem regions
        Dim _actualBytesRead As Int32 = 0 ''actual length of bytes copied during ReadProcessMemory()
        Dim _origPageProtection As UInt32 = 0 ''To preserve/restore original protection values
        Dim _hasAlreadyFoundOnce As Boolean = False 'possibly end the scan early when first result found
        Dim _oldProtects As String = "" 'displayed after errorrs. as string of '0' padded bits.

        Do
            VirtualQueryEx(_targetProcessHandle, _addr, _mbi, _mbiSize)
            _oldProtects = ConvertMBIProtectToBinaryString(_mbi.Protect)
            If _mbi.State = MemoryAllocationState.Commit Then
                If _mbi.Protect And MemoryAllocationProtectionType.PAGE_CANREAD Then 'bitmask check for any readable type
                    ''EASY READ
                    If _mbi.Protect And MemoryAllocationProtectionType.PAGE_GUARD Then
                        DoOutput("avoided the guard at 0x" & _addr.ToString("X"))
                        GoTo badLabelSkipThisMemRegion 'BUT ITS GUARDED
                    End If
                Else
                    ''CANT READ YET
                    If _mbi.Protect And MemoryAllocationProtectionType.PAGE_COPYFORWARD Then
                        ''CANT READ AT ALL (ignore non-readable copyforward unless you really* know what you're doing. usually fails anyway)
                        DoOutput("avoided OS managed file (dll?) at 0x" & _addr.ToString("X"))
                        GoTo badLabelSkipThisMemRegion
                    Else
                        ''Enable Read
                        If _mbi.Protect And MemoryAllocationProtectionType.PAGE_CANEXECUTE Then
                            'it should remain executable! 
                            If VirtualProtectEx(_targetProcessHandle, _mbi.BaseAddress, _mbi.RegionSize, MemoryAllocationProtectionType.PAGE_EXECUTE_READWRITE, _origPageProtection) Then
                                'DoOutput("execPatching OK 0x" & _addr.ToString("X"))
                            Else
                                DoOutput("SFB() execPatching FAIL 0x" & _addr.ToString("X"))
                                DoOutput("protect: " & _oldProtects)
                                Threading.Thread.Sleep(2500)
                                GoTo badLabelSkipThisMemRegion
                            End If
                        Else
                            If VirtualProtectEx(_targetProcessHandle, _mbi.BaseAddress, _mbi.RegionSize, MemoryAllocationProtectionType.PAGE_READWRITE, _origPageProtection) Then
                                'DoOutput("readPatching OK 0x" & _mbi.BaseAddress.ToString("X"))
                            Else
                                DoOutput("SFB() readPatching FAIL 0x" & _mbi.BaseAddress.ToString("X"))
                                DoOutput("protect: " & _oldProtects)
                                Threading.Thread.Sleep(2500)
                                GoTo badLabelSkipThisMemRegion
                            End If
                        End If
                    End If
                End If
                ''READ THE DATA
                If _mbi.RegionSize.ToInt32 <= _sysInfo.dwPageSize Then '4096 bytes. 4kb. see windows memory management for info.
                    ''READ THE DATA. small region
                    If ReadProcessMemory(_targetProcessHandle, _mbi.BaseAddress, _readBuff, _mbi.RegionSize, _actualBytesRead) Then
                        If (_actualBytesRead <> _mbi.RegionSize) Then
                            'not able to read all data, handle gracefully. do nothing :)
                            modPublic.DoOutput("SFB() RPM->ActualBytesRead too low! 0x" & _mbi.BaseAddress.ToString("X"))
                        Else
                            ''COMPARE VALUE                                      
                            For xx As Int32 = 0 To _mbi.RegionSize.ToInt32 - byteBuff.Length 'todo:  align4?
                                For yy As Int32 = 0 To byteBuff.Length - 1
                                    If byteBuff(yy) <> _readBuff(xx + yy) Then
                                        GoTo badLabelNoSuccess
                                    End If
                                Next
                                _rtns.Add(_addr.ToInt32 + xx)  'found it
                                If returnOnFirstOccurance Then
                                    _hasAlreadyFoundOnce = True
                                    Exit For
                                End If
badLabelNoSuccess:
                            Next
                        End If
                    Else
                        modPublic.DoOutput("SFB() RPM FAIL 0x" & _mbi.BaseAddress.ToString("X"))
                    End If
                Else
                    ' large region                                     
                    _bigBuff = ReadLargeRamPage(_addr, _addr.ToInt32 + _mbi.RegionSize.ToInt32)
                    For xx As Int32 = 0 To _bigBuff.Length - byteBuff.Length 'todo:  align4?
                        ''COMPARE VALUE 
                        For yy As Int32 = 0 To byteBuff.Length - 1
                            If byteBuff(yy) <> _bigBuff(xx + yy) Then
                                GoTo badLabelNoMoreSuccess
                            End If
                        Next
                        _rtns.Add(_addr.ToInt32 + xx) 'found it
                        If returnOnFirstOccurance Then
                            _hasAlreadyFoundOnce = True
                            Exit For
                        End If
badLabelNoMoreSuccess:
                    Next
                End If ''end region size
                '' RESTORE PROTECTION
                If _origPageProtection Then
                    VirtualProtectEx(_targetProcessHandle, _mbi.BaseAddress, _mbi.RegionSize, _origPageProtection, _origPageProtection)
                    _origPageProtection = 0
                End If
                If _hasAlreadyFoundOnce AndAlso returnOnFirstOccurance Then Exit Do
            End If ''//state=committed
badLabelSkipThisMemRegion:
            _addr = _mbi.BaseAddress.ToInt32 + _mbi.RegionSize.ToInt32 ''increment _addr to next region
        Loop While _addr.ToInt32 < _sysInfo.lpMaximumApplicationAddress

        If _rtns.Count = 0 Then _rtns.Add(IntPtr.Zero) 'pattern not found!
        Return _rtns.ToArray
    End Function
    Private Function ScanForByteMask(ByVal buff() As Byte, ByVal mask() As Byte, Optional ByVal returnOnFirstOccurance As Boolean = False) As IntPtr()
        If IsAttachedToProcess() = False Or mask.Length <> buff.Length Then
            Return New IntPtr() {IntPtr.Zero} 'user fail
        End If
        Dim _rtns As New List(Of IntPtr) 'locations (memory addresses) where the buff() was found at
        If Not returnOnFirstOccurance Then _rtns.Capacity = 1000 'could be larger. depends how many results you expect..
        Dim _mbi As MEMORY_BASIC_INFORMATION, _sysInfo As SYSTEM_INFO
        Dim _mbiSize As Int32 = Marshal.SizeOf(_mbi) ''size of memory_basic_region struct in bytes.
        GetSystemInfo(_sysInfo)
        Dim _addr As IntPtr = IntPtr.Zero 'counter/loop control.
        Dim _readBuff(_sysInfo.dwPageSize - 1) As Byte 'small buffer to read small mem regions
        Dim _bigBuff(0) As Byte 'large buffer to read large mem regions
        Dim _actualBytesRead As Int32 = 0 ''actual length of bytes copied during ReadProcessMemory()
        Dim _origPageProtection As UInt32 = 0 ''To preserve/restore original protection values
        Dim _hasAlreadyFoundOnce As Boolean = False
        Dim _oldProtects As String = "" 'displayed after errorrs. as string of bits.
        Do
            VirtualQueryEx(_targetProcessHandle, _addr, _mbi, _mbiSize)
            _oldProtects = ConvertMBIProtectToBinaryString(_mbi.Protect)
            If _mbi.State = MemoryAllocationState.Commit Then
                If _mbi.Protect And MemoryAllocationProtectionType.PAGE_CANREAD Then 'bitmask check for any readable type
                    ''EASY READ
                    If _mbi.Protect And MemoryAllocationProtectionType.PAGE_GUARD Then
                        'DoOutput("avoided the guard at 0x" & _addr.ToString("X"))
                        GoTo badLabelSkipThisMemRegion 'BUT ITS GUARDED
                    End If
                Else
                    ''CANT READ YET
                    If _mbi.Protect And MemoryAllocationProtectionType.PAGE_COPYFORWARD Then
                        ''CANT READ AT ALL (ignore non-readable copyforward unless you really* know what you're doing. usually fails anyway)
                        DoOutput("avoided OS managed file (dll?) at 0x" & _addr.ToString("X"))
                        GoTo badLabelSkipThisMemRegion
                    Else
                        ''Enable Read
                        If _mbi.Protect And MemoryAllocationProtectionType.PAGE_CANEXECUTE Then
                            'it should remain executable! 
                            If VirtualProtectEx(_targetProcessHandle, _mbi.BaseAddress, _mbi.RegionSize, MemoryAllocationProtectionType.PAGE_EXECUTE_READWRITE, _origPageProtection) Then
                                'DoOutput("execPatching OK 0x" & _addr.ToString("X"))
                            Else
                                DoOutput("SFBM() execPatching FAIL 0x" & _addr.ToString("X"))
                                DoOutput("protect: " & _oldProtects)
                                Threading.Thread.Sleep(2500)
                                GoTo badLabelSkipThisMemRegion
                            End If
                        Else
                            If VirtualProtectEx(_targetProcessHandle, _mbi.BaseAddress, _mbi.RegionSize, MemoryAllocationProtectionType.PAGE_READWRITE, _origPageProtection) Then
                                'DoOutput("readPatching OK 0x" & _mbi.BaseAddress.ToString("X"))
                            Else
                                DoOutput("SFBM() readPatching FAIL 0x" & _mbi.BaseAddress.ToString("X"))
                                DoOutput("protect: " & _oldProtects)
                                Threading.Thread.Sleep(2500)
                                GoTo badLabelSkipThisMemRegion
                            End If
                        End If
                    End If
                End If
                ''READ THE DATA
                If _mbi.RegionSize.ToInt32 <= _sysInfo.dwPageSize Then '4096 bytes. 4kb. see windows memory management for info.
                    ''READ THE DATA. small region
                    If ReadProcessMemory(_targetProcessHandle, _mbi.BaseAddress, _readBuff, _mbi.RegionSize, _actualBytesRead) Then
                        If (_actualBytesRead <> _mbi.RegionSize) Then
                            'not able to read all data, handle gracefully. do nothing :)
                            modPublic.DoOutput("SFBM() RPM->ActualBytesRead too low! 0x" & _mbi.BaseAddress.ToString("X"))
                        Else
                            ''COMPARE VALUE                                      
                            For xx As Int32 = 0 To _mbi.RegionSize.ToInt32 - buff.Length 'todo:  align4?
                                For yy As Int32 = 0 To buff.Length - 1
                                    If mask(yy) <> 0 Then
                                        If buff(yy) <> _readBuff(xx + yy) Then
                                            GoTo badLabelNoSuccess
                                        End If
                                    End If
                                Next
                                _rtns.Add(_addr.ToInt32 + xx)  'found it
                                If returnOnFirstOccurance Then
                                    _hasAlreadyFoundOnce = True
                                    Exit For
                                End If
badLabelNoSuccess:
                            Next
                        End If
                    Else
                        modPublic.DoOutput("SFBM() RPM FAIL 0x" & _mbi.BaseAddress.ToString("X"))
                    End If
                Else
                    ' large region                                     
                    _bigBuff = ReadLargeRamPage(_addr, _addr.ToInt32 + _mbi.RegionSize.ToInt32)
                    For xx As Int32 = 0 To _bigBuff.Length - buff.Length 'todo:  align4?
                        ''COMPARE VALUE 
                        For yy As Int32 = 0 To buff.Length - 1
                            If mask(yy) <> 0 Then
                                If buff(yy) <> _bigBuff(xx + yy) Then
                                    GoTo badLabelNoMoreSuccess
                                End If
                            End If
                        Next
                        _rtns.Add(_addr.ToInt32 + xx) 'found it
                        If returnOnFirstOccurance Then
                            _hasAlreadyFoundOnce = True
                            Exit For
                        End If
badLabelNoMoreSuccess:
                    Next
                End If ''end region size
                '' RESTORE PROTECTION
                If _origPageProtection Then
                    VirtualProtectEx(_targetProcessHandle, _mbi.BaseAddress, _mbi.RegionSize, _origPageProtection, _origPageProtection)
                    _origPageProtection = 0
                End If
                If _hasAlreadyFoundOnce AndAlso returnOnFirstOccurance Then Exit Do
            End If ''//state=committed
badLabelSkipThisMemRegion:
            _addr = _mbi.BaseAddress.ToInt32 + _mbi.RegionSize.ToInt32 ''increment _addr to next region
        Loop While _addr.ToInt32 < _sysInfo.lpMaximumApplicationAddress

        If _rtns.Count = 0 Then _rtns.Add(IntPtr.Zero) 'pattern not found!
        Return _rtns.ToArray
    End Function
    ''' <summary>
    ''' Reads a region of ram (startAddress to stopAddress). CALLING code is responsible for checking memory_allocation_protection_type before calling this function.
    ''' </summary>
    ''' <param name="aStart">Beginning of scan range. (usually a memory_basic_information.BaseAddress, doesn't have to be).</param>
    ''' <param name="aStop">End of scan range. (usually memory_basic_information.BaseAddress + iSize, doesn't have to be) </param>
    ''' <returns></returns>
    ''' <remarks>Can span multiple regions, but caller should verity access rights first!</remarks>
    Private Function ReadLargeRamPage(ByVal aStart As IntPtr, ByVal aStop As IntPtr) As Byte()
        Dim _rtnBuffSize As Int32 = aStop.ToInt32 - aStart.ToInt32 'theoretical max size: may be smaller due to read failure
        Dim _returnByteBuff(_rtnBuffSize - 1) As Byte ' return results
        Dim _byteBuffCurrIndex As Int32 = 0 'counter
        Dim _readBuff(_systemInfo.dwPageSize - 1) As Byte 'temporary storage for ReadProcessMemory()
        Dim _actualBytesRead As Int32 = 0 '' actual length of bytes returned by ReadProcessMemory()
        Dim _curAddr As IntPtr = aStart
        Dim _sizeRemaining As Int32 = _rtnBuffSize '
        'start reading
        Do
            If _sizeRemaining >= _systemInfo.dwPageSize Then
                If ReadProcessMemory(_targetProcessHandle, _curAddr, _readBuff, _systemInfo.dwPageSize, _actualBytesRead) Then
                    If (_actualBytesRead <> _systemInfo.dwPageSize) Then
                        ''not able to read entire area
                        If _actualBytesRead > 0 Then 'append what little data we did read
                            Array.Copy(_readBuff, 0, _returnByteBuff, _byteBuffCurrIndex, _actualBytesRead)
                            _byteBuffCurrIndex += _actualBytesRead
                        End If
                        modPublic.DoOutput("ReadLargeRamChunk() RPM->ActualBytesRead too low! 0x" & _curAddr.ToString("X"))
                    Else
                        Array.Copy(_readBuff, 0, _returnByteBuff, _byteBuffCurrIndex, _systemInfo.dwPageSize)
                        _byteBuffCurrIndex += _systemInfo.dwPageSize
                    End If
                Else
                    modPublic.DoOutput("ReadLargeRamChunk() RPM->FAIL! 0x" & _curAddr.ToString("X"))
                End If
                _sizeRemaining -= _systemInfo.dwPageSize ' 
            Else
                'almost at end of mem scan. 1 small piece left
                If ReadProcessMemory(_targetProcessHandle, _curAddr, _readBuff, _sizeRemaining, _actualBytesRead) Then
                    If (_actualBytesRead <> _sizeRemaining) Then
                        'not able to read entire area
                        If _actualBytesRead > 0 Then 'append what little data we did read
                            Array.Copy(_readBuff, 0, _returnByteBuff, _byteBuffCurrIndex, _actualBytesRead)
                            _byteBuffCurrIndex += _actualBytesRead
                        End If
                        modPublic.DoOutput("ReadLargeRamChunk() RPM->ActualBytesRead too low! (final chunk) 0x" & _curAddr.ToString("X"))
                    Else
                        Array.Copy(_readBuff, 0, _returnByteBuff, _byteBuffCurrIndex, _sizeRemaining)
                        _byteBuffCurrIndex += _sizeRemaining
                    End If
                Else
                    modPublic.DoOutput("ReadLargeRamChunk() RPM->FAIL! (final chunk!) 0x" & _curAddr.ToString("X"))
                End If
                _sizeRemaining = 0
            End If
            If _sizeRemaining = 0 Then Exit Do
            _curAddr = _curAddr.ToInt32 + _systemInfo.dwPageSize
        Loop
        If _byteBuffCurrIndex < _rtnBuffSize Then ' ie. actual_read_length < expected_read_length
            '_returnBuff was declared too large. Shrink it.
            ReDim Preserve _returnByteBuff(_byteBuffCurrIndex - 1) ' only occurs on read failures
        End If
        Return _returnByteBuff
    End Function
Pretty ugly, and could be more efficient, but hopefully gives you ideas.
FindPattern is shit-slow from an external process, period. RPM/WPM are crazy slow normally, let alone when you don't even know the exact address you want to read from. The only way to slightly speed up the process is to buffer as much data as you can each read so that the number of reads you actually need to do are reduced. This of course involves consuming more memory to do a simple FindPattern so you'll need to tradeoff between speed and memory.

Anyway here's an implementation I just whipped up (I forgot how shit VB.NET is to write )

Code:
Imports System.Runtime.InteropServices

Public Class PatternScanner
    '16kb buffer size, anything above ~20kb won't be read correctly with a single call to ReadProcessMemory
    'increase/decrease this value as necessary (decreasing will slow down the scanning, but reduce the amount of memory consumed)
    Private Const BUFFER_SIZE As Integer = 16384

    <DllImport("kernel32.dll", SetLastError:=True, CallingConvention:=CallingConvention.Winapi)> _
    Private Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), ByVal nSize As UIntPtr, <Out()> ByRef lpNumberOfBytesRead As UIntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    Public Shared Function Scan(ByVal processHandle As IntPtr, ByVal pattern As Byte(), ByVal mask As String, ByVal startAddress As IntPtr, ByVal length As Integer) As IntPtr
        If processHandle = IntPtr.Zero Then Throw New ArgumentNullException("processHandle")
        If pattern Is Nothing Then Throw New ArgumentNullException("pattern")
        If length <= 0 Then Throw New ArgumentOutOfRangeException("length")
        If pattern.Length <> mask.Length Then Throw New ArgumentException("Both 'pattern' and 'mask' must be of equal length.")

        Dim results = Scan_impl(processHandle, pattern, mask, startAddress, length, True)
        Return If(results.Count = 1, results(0), IntPtr.Zero)
    End Function

    Public Shared Function ScanAll(ByVal processHandle As IntPtr, ByVal pattern As Byte(), ByVal mask As String, ByVal startAddress As IntPtr, ByVal length As Integer) As List(Of IntPtr)
        If processHandle = IntPtr.Zero Then Throw New ArgumentNullException("processHandle")
        If pattern Is Nothing Then Throw New ArgumentNullException("pattern")
        If length <= 0 Then Throw New ArgumentOutOfRangeException("length")
        If pattern.Length <> mask.Length Then Throw New ArgumentException("Both 'pattern' and 'mask' must be of equal length.")

        Dim results = Scan_impl(processHandle, pattern, mask, startAddress, length, False)
        Return results
    End Function

    Private Shared Function Scan_impl(ByVal processHandle As IntPtr, ByVal pattern As Byte(), ByVal mask As String, ByVal startAddress As IntPtr, ByVal length As Integer, Optional ByVal shortCircuit As Boolean = True) As List(Of IntPtr)
        Dim blockSize As Integer = Math.Min(length, BUFFER_SIZE)
        Dim iterator As Integer = 0
        Dim read As UIntPtr = UIntPtr.Zero
        Dim buffer(blockSize - 1) As Byte
        Dim cmask = mask.ToCharArray()
        Dim results As New List(Of IntPtr)

        While iterator < length
            If Not ReadProcessMemory(processHandle, New IntPtr(startAddress.ToInt64() + iterator), buffer, CType(Math.Min(blockSize, length - iterator), UIntPtr), read) Then
                Throw New InvalidOperationException("Unable to read memory from the target process. Please ensure the process handle is valid and has correct read permissions.")
            End If

            Dim location = Scan_search(buffer, pattern, cmask, read.ToUInt32(), shortCircuit)
            If location.Count > 0 Then
                results.AddRange(location.Select(Function(i) New IntPtr(iterator + startAddress.ToInt32() + i)))
                If shortCircuit Then Return results
            End If

            iterator += read.ToUInt32()
        End While

        Return results
    End Function

    Private Shared Function Scan_search(ByVal haystack As Byte(), ByVal pattern As Byte(), ByVal mask As Char(), ByVal length As Integer, Optional ByVal shortCircuit As Boolean = True) As List(Of Integer)
        Dim results As New List(Of Integer)

        For i As Integer = 0 To (length - pattern.Length - 1)
            For j As Integer = 0 To (pattern.Length - 1)
                If mask(j) = "?"c OrElse (haystack(i + j) = pattern(j)) Then
                    If j = (pattern.Length - 1) Then
                        results.Add(i)
                        If shortCircuit Then Return results
                    End If
                Else
                    Exit For ' no point iterating i * j times, can exit this loop as soon as a mismatch is identified
                End If
            Next j
        Next i

        Return results
    End Function
End Class
Of course you can improve the Scan_search search algorithm so that it uses a more efficient searching algorithm (they are around) but I couldn't be arsed looking one up and implementing it with wildcards.

I tried following the most standard form of FindPattern signature (that all the kids are using in C++ these days) so that it'd be as intuitive as possible. To call it you'd do something like:

Code:
' I had notepad++ open with some text in the editor which contained 'ScopedHandle' in it
Module Module1
    Sub Main()
        Dim pattern As Byte() = Array.ConvertAll("Scope??andle".ToCharArray(), Function(c) CType(Asc(c), Byte))
        Dim target As Process = Process.GetProcessesByName("notepad++")(0)
        Dim location As IntPtr = PatternScanner.Scan(target.Handle, pattern, "xxxxx??xxxxx", New IntPtr(&H115900), &HFF)

        Console.WriteLine(location.ToString("X8"))
        Console.Read()
    End Sub
End Module
Posts 1–3 of 3 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us