[零基礎][01] vb6寫楓之谷外掛 – Hack.cls 類模組篇

以往使用vb6編寫楓之谷的外掛時,往往會有程式碼雜亂難以整理的情況,許多的宣告、函數交錯複雜,在修改和維護上也會有相當的難度。以下的Hack.cls是大神Inndy原創經過另一位大神Onion修改過後的程式碼,小弟在本篇文章只負責編輯、少量修改,使用方法非常簡單,請參照以下步驟。


第一步 開啟新專案→新增→物件類別模組(Class)。

1 - [零基礎][01] vb6寫楓之谷外掛 - Hack.cls 類模組篇

第二步 貼入下方程式碼。或點我下載cls檔案並加入專案。

這裡面有什麼?

  • WriteMemory
  • ReadMemory
  • FindWindow
  • OpenProcess
  • ChangeImagePath
  • 各類型態轉換函數
第三步 在表單的程式碼中進行下列宣告:

Dim HACK As New clsHack

基本上是一帖新手上路外掛超級懶人包了,很多函數直接調用即可,方便、乾淨、無毒無害。

程式碼:

Option Explicit
'=====================Settings=====================
Private Const PreAllocSize As Long = &H10000 * 8
'=====================API=====================
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcessAPI Lib "kernel32" Alias "OpenProcess" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WriteProcessMemoryAPI Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
'Private Declare Function ReadProcessMemoryAPI Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function ZwReadVirtualMemory Lib "ntdll" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function CloseHandleAPI Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long Private Declare Function VirtualAlloc Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
'=====================Consts=====================
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
Private Const MEM_COMMIT = &H1000
Private Const PAGE_READWRITE = &H4
'=====================VarsForClass=====================
Private PreAllocAddress As Long
Private AllocedSize As Long
'=====================Vars=====================
Public Inited As Boolean
Public hWnd, Handle, Pid As Long

Public Function OpenProcess(Optional ByVal lpPID As Long = -1) As Long
If lpPID = 0 And Pid = 0 Then Exit Function
'If lpPID > 0 And Pid = 0 Then Pid = lpPID
If lpPID > 0 Then Pid = lpPID
Handle = OpenProcessAPI(PROCESS_ALL_ACCESS, False, Pid)
OpenProcess = Handle
If Handle > 0 Then Inited = True
End Function

Public Function OpenProcessByWindow(ByVal lpWindowName As String, Optional ByVal lpClassName As String = vbNullString) As Long
hWnd = FindWindow(lpClassName, lpWindowName)
GetWindowThreadProcessId hWnd, Pid
OpenProcessByWindow = OpenProcess
End Function

Public Function CloseHandle() As Long
If Not Inited Then Exit Function
CloseHandle = CloseHandleAPI(Handle)
Handle = 0
hWnd = 0
Pid = 0
Inited = False
End Function

Public Function CloseGame() As Long
If Not Inited Then Exit Function
CloseGame = TerminateProcess(Handle, 0&)
CloseHandle
Handle = 0
Pid = 0
hWnd = 0
End Function

Public Function ChangeImagePath(Optional ByVal lpImagePath As String = "C:WINDOWSsystem32taskmgr.exe") As Long
Static BeUsed As Boolean
If BeUsed = False Then
Dim hProcess As Long
hProcess = OpenProcessAPI(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId)
If hProcess = 0 Then Exit Function
Dim sLenth As Long
Dim BaseAddress As Long
sLenth = LenB(lpImagePath) + 1 + 26
BaseAddress = VirtualAllocEx(hProcess, ByVal 0&, ByVal sLenth, MEM_COMMIT, PAGE_READWRITE)
If BaseAddress = 0 Then Exit Function
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 0, ByVal VarPtr(&H30058B64), 4, False
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 4, ByVal VarPtr(&H8B000000), 4, False
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 8, ByVal VarPtr(&HC0831040), 4, False
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 12, ByVal VarPtr(&H245C8B3C), 4, False
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 16, ByVal VarPtr(&H89188904), 4, False
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 20, ByVal VarPtr(&HC2042444), 4, False
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 24, ByVal VarPtr(&H10), 2, False
WriteProcessMemoryAPI hProcess, ByVal BaseAddress + 26, ByVal StrPtr(lpImagePath), sLenth, False
CloseHandleAPI hProcess
CallWindowProc BaseAddress, BaseAddress + 26, 0, 0, 0
BeUsed = True
ChangeImagePath = BaseAddress
End If
End Function

Public Function WriteMemory(ByVal lpAddress As Long, ByVal lpBuffer As Long, ByVal lpSize As Long) As Long
WriteMemory = WriteProcessMemoryAPI(Handle, ByVal lpAddress, ByVal lpBuffer, ByVal lpSize, False)
End Function

Public Function WriteByte(ByVal lpAddress As Long, ByVal lpValue As Byte) As Long
WriteByte = WriteProcessMemoryAPI(Handle, ByVal lpAddress, ByVal VarPtr(lpValue), ByVal LenB(lpValue), False)
End Function

Public Function WriteLong(ByVal lpAddress As Long, ByVal lpValue As Long) As Long
WriteLong = WriteProcessMemoryAPI(Handle, ByVal lpAddress, ByVal VarPtr(lpValue), ByVal LenB(lpValue), False)
End Function

Public Function WriteString(ByVal lpAddress As Long, ByVal lpValue As String) As Long
WriteString = WriteProcessMemoryAPI(Handle, ByVal lpAddress, ByVal VarPtr(lpValue), ByVal LenB(lpValue), False)
End Function

Public Function WriteAOBByString(ByVal lpAddress As Long, ByVal lpAobString As String) As Long
Dim WriteI As Integer
Dim WriteStr() As String
Dim WriteBuff() As Byte
lpAobString = Trim(lpAobString)
WriteStr() = Split(lpAobString, " ")
ReDim WriteBuff(UBound(WriteStr))
For WriteI = 0 To UBound(WriteStr)
WriteBuff(WriteI) = (Val("&H" + WriteStr(WriteI)))
Next WriteI
WriteAOBByString = WriteProcessMemoryAPI(Handle, ByVal lpAddress, ByVal VarPtr(WriteBuff(0)), UBound(WriteBuff) + 1, 0&)
End Function

Public Function WritePointer(ByVal lpAddress As Long, ByVal lpOffset As Long, ByVal lpValue As Long) As Long
WritePointer = WriteLong(ReadLong(lpAddress) + lpOffset, lpValue)
End Function

Public Function WriteMultiPointerByString(ByVal lpPointerList As String, ByVal lpBuffer As Long, ByVal lpSize As Long) As Long
'HACK.WriteMultiPointerByString "5A3B08=>460:A8:0", VarPtr(Gold), 4
Dim PointerList() As String
Dim tmp1, tmp2, i As Long
tmp1 = Val("&H" & Split(lpPointerList, "=>")(0))
PointerList = Split(Split(lpPointerList, "=>")(1), ":")
For i = 0 To UBound(PointerList)
tmp2 = ReadLong(tmp1) + Val("&H" & PointerList(i))
tmp1 = tmp2
Next
tmp2 = WriteMemory(tmp1, lpBuffer, lpSize)
WriteMultiPointerByString = tmp2
End Function

Public Function ReadMemory(ByVal lpAddress As Long, ByVal lpBuffer As Long, ByVal lpSize As Long) As Long
ReadMemory = ZwReadVirtualMemory(Handle, ByVal lpAddress, ByVal lpBuffer, ByVal lpSize, False)
End Function

Public Function ReadLong(ByVal lpAddress As Long) As Long
Dim value As Long
ZwReadVirtualMemory Handle, ByVal lpAddress, ByVal VarPtr(value), ByVal 4, False
ReadLong = value
End Function

Public Function ReadDouble(ByVal lpAddress As Long) As Double
Dim value As Double
ZwReadVirtualMemory Handle, ByVal lpAddress, ByVal VarPtr(value), ByVal 8, False
ReadDouble = value
End Function

Public Function ReadString(ByVal lpAddress As Long, ByVal lpSize As Long) As String
Dim value As String
value = Space(lpSize)
ZwReadVirtualMemory Handle, ByVal lpAddress, ByVal StrPtr(value), ByVal lpSize, False
ReadString = value
value = ""
End Function

Public Function ReadPointer(ByVal lpAddress As Long, ByVal lpOffset As Long) As Long
ReadPointer = ReadLong(ReadLong(lpAddress) + lpOffset)
End Function

Public Function ReadMultiPointerByString(ByVal lpPointerList As String, ByVal lpBuffer As Long, ByVal lpSize As Long) As Long
'HACK.ReadMultiPointerByString "5A3B08=>460:A8:C", VarPtr(Gold), 4
Dim PointerList() As String
Dim tmp1, tmp2, i As Long
tmp1 = Val("&H" & Split(lpPointerList, "=>")(0))
PointerList = Split(Split(lpPointerList, "=>")(1), ":")
For i = 0 To UBound(PointerList)
tmp2 = ReadLong(tmp1) + Val("&H" & PointerList(i))
tmp1 = tmp2
Next
tmp2 = ReadMemory(tmp1, lpBuffer, lpSize)
ReadMultiPointerByString = tmp2
End Function

Public Function Alloc(ByVal lpSize As Long, Optional ByVal lpAddress As Long = 0) As Long
If Not Inited Then Exit Function
If PreAllocAddress = 0 Then
PreAllocAddress = VirtualAllocEx(Handle, ByVal lpAddress, ByVal PreAllocSize, MEM_COMMIT, PAGE_READWRITE)
End If
If lpSize > (PreAllocSize / 4) Then '大於1/4的預先申請空間,就另外申請
Alloc = VirtualAllocEx(Handle, ByVal lpAddress, ByVal lpSize, MEM_COMMIT, PAGE_READWRITE)
Exit Function
End If
If lpSize + AllocedSize > PreAllocSize Then '申請空間會超出預先申請空間時,多申請一些空間
PreAllocAddress = VirtualAllocEx(Handle, ByVal lpAddress, ByVal PreAllocSize, MEM_COMMIT, PAGE_READWRITE)
AllocedSize = 0
End If
Alloc = PreAllocAddress + AllocedSize
AllocedSize = AllocedSize + lpSize
End Function

Public Function MakeJmp(ByVal lpAddress As Long, ByVal lpJmpAddress As Long, Optional ByVal lpNops As Long = 0) As Long
MakeJmp = CBool(WriteByte(lpAddress, &HE9)) And CBool(WriteLong(lpAddress + 1, lpJmpAddress - lpAddress - 5))
If lpNops = 0 Then Exit Function
MakeJmp = MakeJmp And CBool(MakeNops(lpAddress + 5, lpNops))
End Function

Public Function MakeCall(ByVal lpAddress As Long, ByVal lpCallAddress As Long, Optional ByVal lpNops As Long = 0) As Long
MakeCall = CBool(WriteByte(lpAddress, &HE8)) And CBool(WriteLong(lpAddress + 1, lpCallAddress - lpAddress - 5))
If lpNops = 0 Then Exit Function
MakeCall = MakeCall And CBool(MakeNops(lpAddress + 5, lpNops))
End Function

Public Function MakeNops(ByVal lpAddress As Long, ByVal lpSize As Long) As Long
If lpSize = 0 Then
MakeNops = True
Exit Function
End If
Dim NOP() As Byte
ReDim NOP(lpSize)
Dim i As Long
For i = 0 To lpSize - 1
NOP(i) = &H90
Next
MakeNops = WriteMemory(lpAddress, VarPtr(NOP(0)), lpSize)
End Function

Public Function Address2Aob(ByVal Address As Long) As String
Dim tmpAOB As String, reAOB As String, i As Integer
tmpAOB = Hex(Address)
For i = 1 To 7
If (i Mod 2) = 1 Then reAOB = Mid(tmpAOB, i, 2) & " " & reAOB
Next
Address2Aob = Chr(32) & Trim(reAOB) & Chr(32)
End Function

Public Function asm_Je(ByVal FromAdd As Long, ByVal TargetAdd As Long) As String
Dim jneAdd As String, reAOB As String, i As Integer
jneAdd = Hex(TargetAdd - (FromAdd + 6))
For i = 1 To 7
If (i Mod 2) = 1 Then reAOB = Mid(jneAdd, i, 2) & " " & reAOB
Next
asm_Je = Chr(32) & Trim(reAOB) & Chr(32)
End Function

Public Function asm_Jne(ByVal FromAdd As Long, ByVal TargetAdd As Long) As String
Dim jneAdd As String, reAOB As String, i As Integer
jneAdd = Hex(TargetAdd - (FromAdd + 6))
For i = 1 To 7
If (i Mod 2) = 1 Then reAOB = Mid(jneAdd, i, 2) & " " & reAOB
Next
asm_Jne = Chr(32) & Trim(reAOB) & Chr(32)
End Function

Code過於繁複,為避免錯誤,建議用直接下載Hack.cls的方式。→點我下載