[HOW TO] Vb.Net Memory Reading menu

User Tag List

Results 1 to 8 of 8
  1. #1
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [HOW TO] Vb.Net Memory Reading

    The goal
    To be able to read any memory address inside another process, like such.<br>
    Code:
      Dim ourValue as Int32 = 0
      ourValue = MemoryReader.ReadInt32(0x12345678)
      Dim ourValue2 as Int64 = 0
      ourValue2 = MemoryReader.ReadInt64(0x11223344)
      Dim ourBytes() as Byte
      ourBytes = MemoryReader.ReadBytes(0x1F00FF00,100) '100 = length to read
    Basic Assumptions
    I assume you can already program in .Net! That means variables,functions,classes. You feel comfortable with the OOP concepts of vb.net. If you don't know where to declare a variable so your program has access to it, I can't help you. I'm not going to specifically say when to create a class, what to name the files, etc. This guide is for those people who are really comfortable in .Net and have a basic conceptual understanding of what they are trying to do. I had quite hard time myself getting all of this to work (the ins-and-outs of OpenProcess, the mbi.Protect etc), and now that it does work, maybe the final results will help you avoid some frustration.
    Before we get started
    I AM NOT an expert. Some of my information may be incorrect or misleading. Trust content at own risk.

    Some Background Information
    Windows(R) Memory Management
    Basically windows keeps track of a lot of complicated stuff for us, and as far as we care
    each process (on Windows XP! 32bit) gets it's own memory range of 0-&FFFFFFF (32bit--2 gigs). This isn't possible. If the
    machine only has 2 gigs of ram, how can each process get 2 gigs? In reality it can't, and if each process actually used
    that much, your system would stop. But as far as each process is concerned, in theory, it can access 0-0xFFFFFFFF.

    Windows API (I won't explain what they are, only declare them)
    ReadProcessMemory() is the wonderful API which actually lets us read into another processes ram.But, before we can just go reading away, there is a bit of security first. Basically, not just any program can/should/has any reason to, read the ram of another process. So before we can do that, we have to use another windows API, OpenProcess, which gives us special access rights.(kind of) You probably have to be an administrator on the computer for this to work? (todo: experiment, if you care)
    OpenProcess(). You pass in a reference to the desired process, and it returns a handle to that process which you can use for ReadProcessMemory
    (and WriteProcessMemory!) Be sure to call CloseHandle() when you're done with the handle, because it's an OS resource and might lead to mem leak.
    Da Code
    Code:
        Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAcess As UInt32, ByVal bInheritHandle As Boolean, ByVal dwProcessId As Int32) As IntPtr
        Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer() As Byte, ByVal iSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean
        Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As IntPtr) As Boolean
    So now that we have our APIs declared. Let's start using them! But first thing first. Which process do we want to 'read from' and how do we define it in vb.net? Thank goodness there is already a 'Process' class in .Net! The way I find the process is by using .Net functions to find it's main Window based on Title. There are some more complicated scenerios, such as, what if the process doesn't have a window being displayed?! I'm not going into that here.
    There are several options are far as how we select(find) our target process. Two convenient .Net functions.
    Process.GetProcesses() Returns an array of every process currently running.
    Process.GetProcessByName() Tries to find process by name. Funny thing is, since you can run a program multiple times, this returns an array!
    I chose .GetProcesses because of convenience (discovering process name vs window title - which seems easier)
    It returns an array of all processes currently running. We loop over the array,comparing the Process's .MainWindowTitle until we find our process.
    A note about OpenProcess(). You can actually ask for different access rights. The two we care about: READ and WRITE. In my code
    I use PROCESS_ALL_ACCESS (which is Read,Write + some) but this value changes depending on what version of Windows you're on. If all you
    plan to do is read, VM_READ should work. This code is made specifically to run on Windows Xp 32 bit. Any other OS might fail.


    I actually overload my function so there are 2 ways to call it. I only explicitly use the 'window caption' version atm.
    Code:
    Public Class MemoryManager
    Private _targetProcess as Process = Nothing 'to keep track of it. not used yet.
    Private _targetProcessHandle as IntPtr = Intptr.Zero 'Used for ReadProcessMemory
    Private PROCESS_ALL_ACCESS as UInt32 = &H1F0FFF
    Private PROCESS_VM_READ as Uint32 = &H10
        Public Function TryAttachToProcess(ByVal windowCaption As String) As Boolean
            Dim _allProcesses() As Process = Process.GetProcesses
            For Each pp As Process In _allProcesses
                If pp.MainWindowTitle.ToLower.Contains(windowCaption.ToLower) Then
                    'found it! proceed.
                    Return TryAttachToProcess(pp)
                End If
            Next
            MessageBox.Show("Unable to find process '" & windowCaption & ".' Is running?")
            Return False
        End Function
    
        Public Function TryAttachToProcess(ByVal proc As Process) As Boolean
            If _targetProcessHandle = IntPtr.Zero Then 'not already attached
                _targetProcess = proc
                _targetProcessHandle = OpenProcess(ReadProcessMemoryRights.PROCESS_ALL_ACCESS, False, _targetProcess.Id)
                If _targetProcessHandle = 0 Then
                    TryAttachToProcess = False
                    MessageBox.Show("OpenProcess() FAIL! Are you Administrator??")
                Else
                    'if we get here, all connected and ready to use ReadProcessMemory()
                    TryAttachToProcess = True
                    MessageBox.Show("OpenProcess() OK")
                End If
            Else
                MessageBox.Show("Already attached! (Please Detach first?)")
                TryAttachToProcess = False
            End If
        End Function
    
        Public Sub DetachFromProcess()
            If Not (_targetProcessHandle = IntPtr.Zero) Then
                _targetProcess = Nothing
                Try
                    CloseHandle(_targetProcessHandle)
                    _targetProcessHandle = IntPtr.Zero
                    MessageBox.Show("MemReader::Detach() OK")
                Catch ex As Exception
                    MessageBox.Show("MemoryManager::DetachFromProcess::CloseHandle error " & Environment.NewLine & ex.Message)
                End Try
            End If
        End Sub
    
    End Class
    I guess I should explain something before I continue too much further. We have a choice. Call OpenProcess() every time we want to ReadProcessMemory (which, if we're planning on reading dozens of values every second, might not be efficient) or call it once and store the value returned, the handle, in our class. This seems ideal, but means we must verify we have attached to the process before trying to read, which can sometimes be a pain. The other option is to add an extra parameter to your Read() functions, and make each function attach before it reads. Since I'm planning on doing a lot of ReadProcessMemory calls, I took the route of 'attaching' once, and storing the handle. Maybe later we can add shared methods so MemoryManager.ReadInt32(aProcess,0x1234) is possible.

    ReadProcessMemory()
    ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer(), iSize,ByRef lpNumberOfBytesRead) As Boolean

    hProcess The process you want to read from. Duh. -- handle returned by OpenProcess()
    lpBaseAddress The address you want to read (or start reading at) -- you can read as many bytes as you want. not just 1 address at a time!
    lpBuffer The byte array where ReadProcessMemory stores the data it reads
    iSize How many bytes to read
    lpNumberOfBytesRead Actual number of bytes read (if this isn't == iSize, there was a partial error!)

    As Boolean The function tells you if it succeeded or not.

    demo. (no error checking)
    Code:
    Dim _myBytes(3) as Byte
    _myBytes = ReadProcessMemory(_targetHandle,&H112233,_myBytes,4,vbNull) 'fills _myBytes with data stored at 0x112233, 0x112234, 0x112235, 0x112236
    note. lpBuffer needs to be declared the correct size! ReadProcessMemory won't resize it for you.
    If it's too small, it will return as normal and not throw any errors!
    Last edited by abuckau907; 11-04-2012 at 05:18 AM.

    [HOW TO] Vb.Net Memory Reading
  2. #2
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The Goal
    To verify that our MemoryManager code can, in fact, read another process's memory.
    We will be using Cheat Engine (a memory scanner) to find addresses and to verify the data returned from our functions is correct.

    Basically Cheat Engine scans all memory being used by a program. and can search it for a value. So using CE we can actually learn
    the address where pinball stores our score! (note: this address can change each time you run pinball, we'll worry about that later if need be)
    (crude demo on how to find memory address with Cheat Engine)

    -Open pinball. Play some. Make youre score go above 0
    -Pause the game (F3) -- your score value needs to not change while CE scans
    -Open Cheat Engine
    -Attach CE to pinball
    -Leave all options to default (4 bytes,range, etc)
    -Do a first scan for your score

    On my system, CE only finds the score stored at 1 location. If your score was, for example, 100, it probably would have found that value at a LOT more locations. Try changing your score and scanning again (new scan). If that doesn't work, read a tutorial on 'how to find addresses with Cheat Engine' ( 1) find all possible locs, 2)change your score, 3)see if those possible locs still == your score. CE will help you do this.) For pinball, there should only be 1 address. Either way, we're just trying to make sure our MemoryManager can actually read data. Any address could do: I chose reading pinball's score because it gives some "oh, I see it" satisfaction.



    So, now we have an address to read! In my case 0x00AC4E4C (yours may/should be different, that's ok)

    Back to the code. We haven't actually made a function in the MemoryManager class which can read data yet. We have a decision to make. There are actually two major design strategies we can use here: we can have lots of functions, one named for each data type we will read from ram. So our class will have ReadInt32(), ReadUint32(), ReadInt64(), ReadUint64 etc. Or, the other approach is create one function (or, prototype??) which lets you pass in what data type you want to read. For example, MemManager.ReadValue(0x123456,Int32) (This can only work with POD(?) types, which have a constant size in memory) You would want to do this, maybe, to read a custom structure from ram instead of just a plain old built-in type. It's part of
    some new language features(function prototyping?) put into VB.Net. To be honest, I'm not really sure, and it's not something I've read about yet. I chose to instead, explicitly create a bunch of functions, each one made to read a specific data type. This means a LOT or duplicate code. Which isn't good. Keep that in mind.


    MemoryManager class. The first Read() function. ReadInt32()
    Code:
        Public Function ReadInt32(Byval addr as IntPtr) As Int32
    	'Int32 data type-- is 32 bits long, 4 bytes.
            Dim _dataBytes(3) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _dataBytes, 4, vbNull)
            Return BitConverter.ToInt32(_bytes, 0)
        End Function

    A couple things to note about the function
    No error checking
    lpBytesRead = vbNull ? This is used to know if RPM was actually able to read all data. If RPM only
    read some of the memory locations, _bytesRead will be < iSize (in previous example, iSize=4)
    If we pass in vbNull,because the parameter is ByRef, basically it's saying, I don't care, I won't use this value in my code.\
    BitConverter A handy .Net class which converts an array of bytes to many core data types

    error checking
    Code:
    Public Function ReadInt32(Byval addr as IntPtr) As Int32
    	Dim _dataBytes(3) As Byte
    	Dim _actualReadLength as Int32 = 0
            If ReadProcessMemory(_targetProcessHandle, addr, _dataBytes, 4, _actualReadLength) Then
    	   'success
    	If _actualReadLength = 4 Then
    	   'all bytes read
    	   Return BitConverter.ToInt32(_bytes, 0)
    	Else
    	'ReadProcessMemory only able to read *some* of the memory location. 
    	Return 0 'or handle byte array at own risk? [should have been zero filled on creation?] + [some valid data?]
    	Else
    	'ReadProcessMemory returned FAIL. Possibly ram is inaccessable.
    	Return 0
        End Function
    The second Read() function. ReadInt64()
    Code:
        Public Function ReadInt32(Byval addr as IntPtr) As Int32
            Dim _dataBytes(3) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _dataBytes, 4, vbNull)
            Return BitConverter.ToInt32(_bytes, 0)
        End Function
        Public Function ReadInt64(Byval addr as IntPtr) As Int64
            Dim _dataBytes(7) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _dataBytes, 8, vbNull)
            Return BitConverter.ToInt64(_bytes, 0)
        End Function
    Side Note
    Int32 and Uint32 are both 32 bits, 4 bytes, in length. You need to understand how signed and unsigned works! That's too much to explain inside another tutorial. I HIGHLY recomend physically writing on paper numbers in binary,decimal,hex..lining them up in different ways, and try to feel comfortable looking at numbers in different formats. This helps especially when debugging. For example, I kept reading a pointer and outputting it using .ToString(). Well I was getting a number like 110347892 instead of the hex address Cheat Engine was showing me. It was because .ToString() was displaying it in base 10, which is the default, we all use grew up using base 10. Fortunately, .ToString() can take a formatting parameter where it will convert it to hex for us! (and there are other .Net functions for converting bases). The point is that you need to understand numbers.
    Tip. In vb.net hex numbers start with &H <-- get it..H, pretty obvious. In other languages the prefix is 0x. Sometimes you'll see me refer to a memory loc as 0x123456. In vb it would be &H123456 and in decimal it would be..you tell me.

    Another Read() Function. This time UnSigned (if that should really matter..) Hooray BitCoverter class.
    Code:
        Public Function ReadInt32(Byval addr as IntPtr) As Int32
            Dim _dataBytes(3) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _dataBytes, 4, vbNull)
            Return BitConverter.ToInt32(_bytes, 0)
        End Function
        Public Function ReadInt64(Byval addr as IntPtr) As Int64
            Dim _dataBytes(7) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _dataBytes, 8, vbNull)
            Return BitConverter.ToInt64(_bytes, 0)
        End Function
        Public Function ReadUInt32(Byval addr as IntPtr) As UInt32
            Dim _dataBytes(3) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _dataBytes, 4, vbNull)
            Return BitConverter.ToUInt32(_bytes, 0)
        End Function
    Until you have one for each data type you might read
    Code:
    Public Function ReadInt16(ByVal addr As IntPtr) As Int16
            Dim _rtnBytes(1) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 2, vbNull)
            Return BitConverter.ToInt16(_rtnBytes, 0)
        End Function
        Public Function ReadInt32(ByVal addr As IntPtr) As Int32
            Dim _rtnBytes(3) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 4, vbNull)
    
            Return BitConverter.ToInt32(_rtnBytes, 0)
        End Function
        Public Function ReadInt64(ByVal addr As IntPtr) As Int64
            Dim _rtnBytes(7) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 8, vbNull)
            Return BitConverter.ToInt64(_rtnBytes, 0)
        End Function
        Public Function ReadUInt16(ByVal addr As IntPtr) As UInt16
            Dim _rtnBytes(1) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 2, vbNull)
            Return BitConverter.ToUInt16(_rtnBytes, 0)
        End Function
        Public Function ReadUInt32(ByVal addr As IntPtr) As UInt32
            Dim _rtnBytes(3) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 4, vbNull)
            Return BitConverter.ToUInt32(_rtnBytes, 0)
        End Function
        Public Function ReadUInt64(ByVal addr As IntPtr) As UInt64
            Dim _rtnBytes(7) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 8, vbNull)
            Return BitConverter.ToUInt64(_rtnBytes, 0)
        End Function
        Public Function ReadFloat(ByVal addr As IntPtr) As Single
            Dim _rtnBytes(3) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 4, vbNull)
            Return BitConverter.ToSingle(_rtnBytes, 0)
        End Function
        Public Function ReadDouble(ByVal addr As IntPtr) As Double
            Dim _rtnBytes(7) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, 8, vbNull)
            Return BitConverter.ToDouble(_rtnBytes, 0)
        End Function
        Public Function ReadIntPtr(ByVal addr As IntPtr) As IntPtr
            Dim _rtnBytes(IntPtr.Size - 1) As Byte
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, IntPtr.Size, Nothing)
                If IntPtr.Size = 4 Then
                    Return New IntPtr(BitConverter.ToUInt32(_rtnBytes, 0))
                Else
                    Return New IntPtr(BitConverter.ToInt64(_rtnBytes, 0))
                End If
        End Function
        Public Function ReadBytes(ByVal addr As IntPtr, ByVal size As Int32) As Byte()
            Dim _rtnBytes(size - 1) As Byte 
            ReadProcessMemory(_targetProcessHandle, addr, _rtnBytes, size, vbNull)
            Return _rtnBytes
        End Function
    I also added one for IntPtr (which uses IntPtr.Size -- 32/64 problems ahead..) and one for ReadBytes. And forgot Boolean I hope they make sense. We'll be using ReadBytes() much later to scan the entire memory range because it's more efficient to read a large chunk of ram vs. 4 bytes at a time. It's the difference between calling ReadProcessMemory 10,000 times and 10,000,000 times...
    I guess I forgot ReadByte(), singular. I don't see myself using it. If so desired, you should* be able to create it your self.

    Back to actually testing if any of this works. I assume you've created a new project, and the MemoryManager class. And added all our new read functions.
    Create a variable of the MemoryManager class. (Top of your form class? For demo purposes. I won't go into variable scoping) and use it!
    Code:
    Public Class Form1
    Private _memManager as New MemoryManager 'New word is important! -I'm not explaining this.
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If _memManager.TryAttachToProcess("3D Pinball") Then
      Dim _myScore as Int32 = _memManager.ReadInt32(&HAC4E4C)
       ' Done using MemoryManager for reading. Close it.
         _memManager.DetachFromProcess()
      MessageBox.Show("Your current 3D Pinball score is: " & _myScore.ToString())
    Else
      MessageBox.Show("MemoryManager unable to attach to 3D Pinball for ram reading")
    End If
    End Sub
    
    End Class

    That's it. You can now go poking around, trying to read the memory of different programs. But please don't.

    -Andrew
    Last edited by abuckau907; 11-04-2012 at 06:19 AM.

  3. #3
    Naws's Avatar Private
    Reputation
    1
    Join Date
    Jul 2014
    Posts
    1
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It works =), but I need to read the following address: client.dll+9DEFD4 ;c

  4. #4
    Jadd's Avatar 🐸 Premium Seller
    Reputation
    1515
    Join Date
    May 2008
    Posts
    2,433
    Thanks G/R
    81/336
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Naws View Post
    It works =), but I need to read the following address: client.dll+9DEFD4 ;c
    Process.Modules Property (System.Diagnostics)
    ProcessModule.BaseAddress Property (System.Diagnostics)

  5. #5
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    yep.

    @Naws So, "client.dll+9DEFD4"

    client.dll is a .dll file loaded into ram -- which means it has a START address, and is some length in bytes. Usually when programs show you " some.dll + offset" they mean the start address of the dll.

    So your task is to figure out where that .dll starts in ram.
    As mentioned by Jadd, process.Modules() returns an array of the process's modules
    aModule.BaseAddress is the start address in ram of a specific module.

    (use a for loop..something like..

    For Each zzModule in targetProcess.Modules

    If zzModule.Name = "targetModule" Then
    '' this is our module
    moduleBaseAddr = zzModule.BaseAddress
    End If

    Next zzModule

    then add your offset. Now you have a "plain ol' address" (a 32 bit number...) like shown in the tutorial.

    Maybe try to ask people for help instead of telling them what you need...usually that doesn't get you very far.
    Last edited by abuckau907; 07-25-2014 at 01:26 AM. Reason: typing with a hammer
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  6. #6
    kneeki's Avatar Private
    Reputation
    1
    Join Date
    Mar 2014
    Posts
    2
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey abuckau907! Thanks for this thread, you did a fairly good job of explaining what's going on during the whole process. I am however, running into a bit of an issue as I'm getting errors after attempting to run your code. I'm including a pastebin of what I've created after reading your posts, you can find that here.
    Code:
    Error	1	'ReadProcessMemoryRights' is not declared. It may be inaccessible due to its protection level.	C:\Users\David\Downloads\MemoryReaderConcept\MemoryReaderConcept\Form1.vb	44	52	MemoryReaderConcept
    Error	2	'_bytes' is not declared. It may be inaccessible due to its protection level.	C:\Users\David\Downloads\MemoryReaderConcept\MemoryReaderConcept\Form1.vb	76	41	MemoryReaderConcept
    Error	3	'_bytes' is not declared. It may be inaccessible due to its protection level.	C:\Users\David\Downloads\MemoryReaderConcept\MemoryReaderConcept\Form1.vb	82	41	MemoryReaderConcept
    Error	4	'_bytes' is not declared. It may be inaccessible due to its protection level.	C:\Users\David\Downloads\MemoryReaderConcept\MemoryReaderConcept\Form1.vb	88	42	MemoryReaderConcept
    p.s.
    I'm trying to read the output screen of the Calculator app instead of Pinball because I don't have Pinball installed (running Windows 8.1 Pro x64). Any idea where it is I've gone wrong following your tutorial?

  7. #7
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    you copy-pasted the code? _bytes vs. _dataBytes. hmm.

    And the first error...I guess I didn't include all the rights...
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    Last edited by abuckau907; 08-11-2014 at 03:20 PM.
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  8. #8
    tongclub18's Avatar Member
    Reputation
    1
    Join Date
    Sep 2014
    Posts
    12
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    client.dll is a .dll file loaded into ram which means it has a START address, and is some length in bytes. Usually when programs show you " some.dll + offset" they mean the start address of the dll.

    คาสิโนออนไลน์
    Last edited by tongclub18; 12-15-2014 at 04:04 AM.

Similar Threads

  1. [guide] how to create a wow bot using autoit (memory reading)
    By zamba1587 in forum WoW Memory Editing
    Replies: 17
    Last Post: 01-23-2017, 03:27 PM
  2. [HOW TO] Vb.Net Memory Reading Part 2
    By abuckau907 in forum Programming
    Replies: 5
    Last Post: 12-03-2012, 08:48 PM
  3. How do i know if a Bot is using memory reading / writing?
    By sturmtiger in forum WoW Bots Questions & Requests
    Replies: 1
    Last Post: 01-06-2011, 06:31 AM
  4. VB .Net Memory Reading Project
    By Glitchy in forum WoW Memory Editing
    Replies: 4
    Last Post: 01-22-2008, 12:37 PM
  5. How do you find memory offsets in the game?
    By koalaz2004 in forum World of Warcraft General
    Replies: 0
    Last Post: 08-18-2006, 09:40 PM
All times are GMT -5. The time now is 02:39 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search