+ Reply to Thread
Showing results 1 to 7 of 7

Thread: [VB6] modMemory.bas w/ Debug Privileges (for SC/BW v1.15+) + KEY Grabber Tutorial

  1. #1

    Disciple
    Logos is a jewel in the rough Logos's Avatar
    Join Date
    Aug 2006
    Location
    Viking Longship in the Frozen North
    Posts
    527
    Downloads
    3
    Uploads
    0

    [VB6] modMemory.bas w/ Debug Privileges (for SC/BW v1.15+) + KEY Grabber Tutorial

    The problem with original modMemory.bas was it simply wouldn't work with the latest SC/BW patch. My enhanced version does. Here's the code:
    Code:
    '//=======================================================
    '//                    Compiler Options
    '//=======================================================
    Option Explicit
    '//=======================================================
    '//                   Author Information
    '//=======================================================
    '//Author:      NAATYE
    '//Date:        3/13/2002
    '//Enhanced by: Logos
    '//Date:        10/24/2007
    '//Description: It should work with SC & BW v1.15+ now
    '//Thanks to:   hure (for his working DebugPrivilege module)
    '//=======================================================
    '//                        Notes
    '//=======================================================
    '//Undocumented Visual Basic Functions
    '//VarPtr() - Finds the address any type but string
    '//StrPtr() - Find the address of a string
    '//ObjPtr() - Find the address for a object
    '//Remember the &H in front of a number converts it from hex
    '//=======================================================
    '//                   Private Constants
    '//=======================================================
    Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
    Private Const TOKEN_ADJUST_PRIVILEGES = &H20
    Private Const TOKEN_QUERY = &H8
    Private Const ANYSIZE_ARRAY = 1
    Private Const SE_DEBUG_NAME = "SeDebugPrivilege"
    Private Const SE_PRIVILEGE_ENABLED = &H2
    '//=======================================================
    '//                 Public API Functions
    '//=======================================================
    Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal Classname As String, ByVal WindowName As String) As Long
    '//=======================================================
    '//                    Private Types
    '//=======================================================
    Private Type LUID
       lowpart As Long
       highpart As Long
    End Type
    Private Type LUID_AND_ATTRIBUTES
       pLuid As LUID
       Attributes As Long
    End Type
    Private Type TOKEN_PRIVILEGES
       PrivilegeCount As Long
       Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
    End Type
    '//=======================================================
    '//                 Private API Functions
    '//=======================================================
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
    Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
    Private Declare Function WriteString Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
    Private Declare Function WriteValue Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
    Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
    Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, BufferLength As Any, PreviousState As Any, ReturnLength As Any) As Long
    
    '//=======================================================
    '//                   Support Functions
    '//=======================================================
    Public Function getProcessHandle(pid As Long) As Long
       EnableDebugPrivilege (True)
       getProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
       EnableDebugPrivilege (False)
    End Function
    Public Function EnableDebugPrivilege(bOnOff As Boolean) As Boolean
       Dim tp As TOKEN_PRIVILEGES
       Dim tpPrev As TOKEN_PRIVILEGES
       Dim lid As LUID
       Dim tpSize As Long
       Dim lRet As Long
       Dim hCurProc As Long
       Dim hToken As Long
       
       
       tpSize = Len(tp)
       
       hCurProc = GetCurrentProcess()
       
       lRet = OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken)
       lRet = LookupPrivilegeValue("", SE_DEBUG_NAME, lid)
       
       tp.PrivilegeCount = 1
       tp.Privileges(0).pLuid = lid
       tp.Privileges(0).Attributes = 0
       
       '//Get Attributes
       lRet = AdjustTokenPrivileges(hToken, 0, tp, tpSize, tpPrev, tpSize)
    
       tpPrev.PrivilegeCount = 1
       tpPrev.Privileges(0).pLuid = lid
       
       If bOnOff = True Then
          tpPrev.Privileges(0).Attributes = tpPrev.Privileges(0).Attributes Or (SE_PRIVILEGE_ENABLED)
       Else
          tpPrev.Privileges(0).Attributes = tpPrev.Privileges(0).Attributes Xor _
                                             (SE_PRIVILEGE_ENABLED And tpPrev.Privileges(0).Attributes)
       End If
    
       '//Set Attributes
       lRet = AdjustTokenPrivileges(hToken, 0, tpPrev, tpSize, ByVal CLng(0), ByVal CLng(0))
       
       CloseHandle (hToken)
       EnableDebugPrivilege = CBool(lRet)
    End Function
    '//=======================================================
    '//                    Peek Functions
    '//=======================================================
    Public Function PeekString(hWnd As Long, Address As Long, Length As Long, Optional TrimString As Boolean = True) As String '//A string is usually terminated by a double null or &h0 therefore if trim string is enabled it will stop looping if a double null is found
    Dim pHandle As Long, ByteValue As Byte, I As Long
       
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
       
       If (pHandle <> 0) And (Address <> 0) Then
           For I = 0 To Length - 1 Step 1
               ReadProcessMemory pHandle, Address + I, ByteValue, 1&, 0&
               
               If (ByteValue = 0) And (TrimString = True) Then
                 Exit For
               End If
                   
               PeekString = PeekString & Chr$(ByteValue)
           Next
       End If
    
       CloseHandle pHandle
    
    End Function
    Public Function PeekLong(hWnd As Long, Address As Long) As Long
    Dim pHandle As Long
    
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
       
       If (pHandle <> 0) And (Address <> 0) Then
           ReadProcessMemory pHandle, Address, PeekLong, 4&, 0&
       End If
    
       CloseHandle pHandle
    
    End Function
    Public Function PeekInteger(hWnd As Long, Address As Long) As Integer
    Dim pHandle As Long
    
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
       
       If (pHandle <> 0) And (Address <> 0) Then
           ReadProcessMemory pHandle, Address, PeekInteger, 2&, 0&
       End If
    
       CloseHandle pHandle
    
    End Function
    Public Function PeekBytes(hWnd As Long, Address As Long, Length As Long) As Byte()
    Dim pHandle As Long, Bytes() As Byte, I As Long
       
       ReDim Bytes(Length - 1)
       
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
       
       If (pHandle <> 0) And (Address <> 0) Then
           For I = 0 To Length - 1 Step 1
               ReadProcessMemory pHandle, Address + I, Bytes(I), 1&, 0&
           Next
       End If
    
       CloseHandle pHandle
    
    End Function
    Public Function PeekByte(hWnd As Long, Address As Long) As Byte
    Dim pHandle As Long
    
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
       
       If (pHandle <> 0) And (Address <> 0) Then
           ReadProcessMemory pHandle, Address, PeekByte, 1&, 0&
       End If
       
       CloseHandle pHandle
    
    End Function
    '//=======================================================
    '//                    Poke Functions
    '//=======================================================
    Public Function PokeString(hWnd As Long, Address As Long, Value As String)
    Dim X() As Byte, Z As Long
       ReDim X(Len(Value) - 1)
       
       For Z = 0 To UBound(X)
           X(Z) = Asc(Mid(Value, Z + 1, 1))
       Next Z
       
       PokeString = PokeBytes(hWnd, Address, X())
    End Function
    Public Function PokeLong(hWnd As Long, Address As Long, Value As Long)
    Dim pHandle As Long
    
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
    
       If (pHandle <> 0) And (Address <> 0) Then
           PokeLong = WriteValue(pHandle, Address, Value, 4&, 0&)
       End If
       
       CloseHandle pHandle
    
    End Function
    Public Function PokeInteger(hWnd As Long, Address As Long, Value As Integer)
    Dim pHandle As Long
    
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
       
       If (pHandle <> 0) And (Address <> 0) Then
           PokeInteger = WriteValue(pHandle, Address, Value, 2&, 0&)
       End If
       
       CloseHandle pHandle
    
    End Function
    Public Function PokeBytes(ByVal hWnd As Long, ByVal Address As Long, ByRef Value() As Byte)
    Dim pHandle As Long
    
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
    
       If (pHandle <> 0) And (Address <> 0) Then
           PokeBytes = WriteProcessMemory(pHandle, Address, Value(0), CLng(UBound(Value) + 1), 0&)
       End If
    
       CloseHandle pHandle
       
    End Function
    Public Function PokeByte(ByVal hWnd As Long, ByVal Address As Long, ByRef Value As Byte)
    Dim pHandle As Long
    
       GetWindowThreadProcessId hWnd, pHandle
       pHandle = getProcessHandle(pHandle)
    
       If (pHandle <> 0) And (Address <> 0) Then
           PokeByte = WriteProcessMemory(pHandle, Address, Value, 1&, 0&)
       End If
    
       CloseHandle pHandle
       
    End Function
    Now for the CD KEY-NUMBER grabber tutorial for 1.15.1. This is for when you're at the battle.net login screen in StarCraft or Brood War. (Don't login, just alt+tab from there.)
    Code:
        Dim hWnd As Long
        Dim nAddress As Long
        Dim sKey As String
        
        'Get the window handle of Brood War
        hWnd = FindWindow("SWarClass", "Brood War")
        
        'If we didn't get any valid (>0) hWnd, try StarCraft's (original's) hwnd instead
        If hWnd = 0 Then hWnd = FindWindow("SWarClass", "Starcraft")
        
        'If we still don't have it, we're out of luck...
        If hWnd = 0 Then MsgBox "Error: StarCraft not found!", vbCritical: Exit Sub
        
        'The value at offset 12FD10 is a pointer to the first character of your CD KEY-NUMBER
        'PeekLong fetches the value at the specified offset for us
        nAddress = PeekLong(hWnd, &H12FD10)
        
        'The CD KEY-NUMBER is 13 characters long, so let's _
        fetch a 13 characters long string from wherever nAdress is pointing to
        sKey = PeekString(hWnd, nAddress, 13, True)
        
        'Done! Now sKey contains our key.
    
        'For looks turn XXXXXXXXXXXXX into XXXX-XXXXX-XXXX
        sKey = Mid(sKey, 1, 4) & "-" & Mid(sKey, 5, 5) & "-" & Mid(sKey, 10)
    It's really that easy. Good luck!

  2. #2
    Administrator

    Saint
    Perma has disabled reputation Perma's Avatar
    Join Date
    Jul 2004
    Location
    Canada
    Posts
    6,039
    Blog Entries
    2
    Downloads
    6
    Uploads
    2

    Cool beans. +rep

  3. #3
    The Sexy Penguin Senior Member
    Moderator

    Prophet
    LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX has a reputation beyond repute LCSBSSRHXXX's Avatar
    Join Date
    Feb 2005
    Location
    astrotravelin'
    Posts
    7,665
    Downloads
    21
    Uploads
    0

    The old modMemory.bas worked fine, you just needed to get debug privileges.

  4. #4

    Disciple
    Logos is a jewel in the rough Logos's Avatar
    Join Date
    Aug 2006
    Location
    Viking Longship in the Frozen North
    Posts
    527
    Downloads
    3
    Uploads
    0

    Thanks Perma!

    Quote Originally Posted by LCSBSSRHXXX View Post
    The old modMemory.bas worked fine, you just needed to get debug privileges.
    Um, that's sorta what it does. So you won't have to. (Better with one less module or the extra crap in this module instead of somewhere else.) Check thread titles.

    [VB6] modMemory.bas w/ Debug Privileges (for SC/BW v1.15+) + KEY Grabber Tutorial (w/ = with)

    As always, if you don't don't like it - don't use it. It may be of help to someone though. (I know I prefer the code of my new Key Grabber based on this module compared to my original version I compiled and posted in my sig linky.)

  5. #5
    Senior Member
    Retired Staff Member

    Zealot
    SubZero has disabled reputation SubZero's Avatar
    Join Date
    Apr 2004
    Location
    Singapore
    Posts
    826
    Downloads
    12
    Uploads
    0

    Nice contribution...

    Perhaps you should post up how you found the address to grab the cd key from, since it's a tutorial and stuff

  6. #6

    Disciple
    Logos is a jewel in the rough Logos's Avatar
    Join Date
    Aug 2006
    Location
    Viking Longship in the Frozen North
    Posts
    527
    Downloads
    3
    Uploads
    0

    Quote Originally Posted by SubZero View Post
    Nice contribution...

    Perhaps you should post up how you found the address to grab the cd key from, since it's a tutorial and stuff
    Well, actually it was available on the forums. But let's say there was a new patch, this is what we would do: Since it's needed for battle.net play anyway, battle.net login screen is a good place to start. (Of course I tried searching at the main menu first, but I could not find the key there. So let's just skip that step altogether.)

    At the Battle.net login screen, alt+tab and simply search for your cd-key as text using your favorite memory searcher (I use ArtMoney). xxxx-xxxxx-xxxx doesn't result in anything (it shouldn't anyways). So we try without the hyphens/dashes (as they're not unique to our key anyway). Now we come up with the offset of our key. Unfortunately, the next time we run StarCraft and go to the battle.net login screen, our key will be stored someplace else. So we need to find a pointer that points to the cd-key (and hope the pointer is static). We search for our key again.

    This time, upon finding it (in my case it was found starting at the offset 01D10088), we try to find a pointer pointing to the offset of the first character of our key. To do this, we either use ArtMoney's "Search the pointer to this address" feature or simply search for a 4-Byte Integer with the hex value 01D10088 (the offset of the first character of our key).

    This results in 0012FD10 and 0012FDF0. Upon running StarCraft and Brood War multiple times and testing both addresses as pointers they both seem to do the job (they seem to be static pointers pointing at the first offset of our cd-key). You would have to debug the game in order to learn the actual difference between these pointers, but as they both work just settle for either (I used 0012FD10 as I came across it on these very forums).

    StarCraft is really that simple. The tutorial was actually meant to be a tutorial on how to use the module to create a key grabber. Not on finding offsets. But if it's of interest, why not? ;)

  7. #7
    Banned

    Deviant
    bLueStar is an unknown quantity at this point bLueStar's Avatar
    Join Date
    Jun 2007
    Location
    Quebec, Canada
    Posts
    121
    Downloads
    0
    Uploads
    0

    awesome work Bro

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Similar Threads

  1. Titan's ModMemory.bas Tutorial
    By OverFlow636 in forum Hacking Tutorials
    Replies: 2
    Last Post: 07-09-2004, 09:46 AM

Posting Rules

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts