Attribute VB_Name = "PatchProc"
Option Explicit

Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As String, ByVal nSize As Long, ByRef lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Public Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadID As Long
End Type
Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Pointer As String * 4
Private lBuff As Long
Private StartInfo As STARTUPINFO
Private ProcInfo As PROCESS_INFORMATION
Public ActiveProcess As PROCESS_INFORMATION

Public Function RunProcess(CmdLine As String) As Boolean
    StartInfo.cb = Len(StartInfo)

    If CreateProcess(vbNullString, CmdLine, ByVal 0&, ByVal 0&, False, 0, vbNull&, vbNullString, StartInfo, ProcInfo) Then
        ActiveProcess = ProcInfo: Pointer = Space(4): RunProcess = True
    Else
        RunProcess = False
    End If
End Function

Public Sub UnloadHandles()
    Call CloseHandle(ActiveProcess.hProcess)
    Call CloseHandle(ActiveProcess.hThread)
End Sub

Public Function Peek4(BaseAddress As Long) As Long
    Call ReadProcessMemory(ActiveProcess.hProcess, BaseAddress, Pointer, 4, 0)
    Call CopyMemory(lBuff, ByVal Pointer, 4)
    Peek4 = lBuff
End Function

Public Sub Poke4(BaseAddress As Long, StuffToWrite As Long)
    Call WriteProcessMemory(ActiveProcess.hProcess, ByVal BaseAddress&, StuffToWrite, 4, 0)
End Sub

Public Sub Poke2(BaseAddress As Long, StuffToWrite As Integer)
    Call WriteProcessMemory(ActiveProcess.hProcess, ByVal BaseAddress&, StuffToWrite, 2, 0)
End Sub
