2

Im writing a small memory scanner application to find pointers in the memory.
But i don't seem to be getting the expected results.

I have the following code:

[DllImport("kernel32.dll")]
private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] buffer, UInt32 size, IntPtr lpNumberOfBytesRead);

public int ReadInt(long Address)
{
    byte[] buffer = new byte[4];
    ReadProcessMemory(ProcessHandle, (IntPtr)Address, buffer, 4, IntPtr.Zero); // this always returns true
    return BitConverter.ToInt32(buffer, 0);
}

public List<long> SearchInt(long start, long end, int value)
{
    List<long> results = new List<long>();
    for (long i = start; i < end; i++)
    {
        try
        {
            if (ReadInt(i) == value)
                results.Add(i);
        }
        catch (Exception)
        {
            break; // no exceptions occur
        }
    }
    return results;
}

if i call the method like this:

SearchInt(baseAddress.ToInt64(), lastAddress.ToInt64(), 1234)

I know for a fact that the process im reading has an integer with the value of 1234 but i don't get any results. If i scan for other values i sometimes get results.

baseAddress is process.MainModule.BaseAddress
and
lastAddress is baseAddress + process.MainModule.ModuleMemorySize

Am i missing somthing here?

string.Empty
  • 10,393
  • 4
  • 39
  • 67
  • You are hiding exceptions. At least log them using Debug.WriteLine() so you can see if the loop is exiting early due to an exception. – Matthew Watson Sep 10 '13 at 09:19
  • there is no exceptions. – string.Empty Sep 10 '13 at 09:20
  • On a 64-bit processor, `i++` will 'jump' 8 bytes. – leppie Sep 10 '13 at 09:25
  • what should i do instead? – string.Empty Sep 10 '13 at 09:31
  • 2
    No it won't it will increment i by one, which is then used as an address up by one byte. – Ibasa Sep 10 '13 at 09:32
  • This is a 64-bit OS and app but it seems `i++` and `i = i + 1` both increment by 1, therefore increasing the pointer value by 1. This is what i thought would happen. – string.Empty Sep 10 '13 at 09:34
  • I created another app that has a global integer with the value `1234` and it never found it but it finds a few results for `1` and `0` and some others. – string.Empty Sep 10 '13 at 09:43
  • @NicolasTyler Finding `0` is no big feat. Any empty memory block can be read as an `int` with 0 value. How are you defining the ints? `const`? – Rotem Sep 10 '13 at 09:45
  • This is true and i know. I over get 27000 results for `0` and only 15 for `1`. And no im just making it public. But this should not make a difference the variable should be stored in the memory. – string.Empty Sep 10 '13 at 09:49
  • The `buffer` parameter to `ReadProcessMemory` should be `[Out]`, rather than `[In, Out]`, but I don't see where the way you have it would cause it to read wrong. – Jim Mischel Sep 10 '13 at 14:49

1 Answers1

2

This would not work if the value you are searching for is initialized at runtime and not a part of the static compiled code. It would then lie outside the memory area defined by BaseAddress + ModuleMemorySize

From ProcessModule.ModuleMemorySize:

ModuleMemorySize does not include any additional memory allocations that the module makes once it is running; it includes only the size of the static code and data in the module file.

Rotem
  • 21,452
  • 6
  • 62
  • 109
  • Ok im going to scan the entire memory and see if i get results. – string.Empty Sep 10 '13 at 09:54
  • 1
    @NicolasTyler If the value you are searching for is a class member, it may be stored on the heap, see a similar question: http://stackoverflow.com/questions/6242537/how-to-get-all-memory-address-space-used-by-a-process – Rotem Sep 10 '13 at 09:55
  • It seems that any address other than the addresses between baseAddress and lastAddress all have the value of zero. So its pointless scanning other addresses. – string.Empty Sep 10 '13 at 12:03