Hi, I've already posted a thread about this on stackoverflow, but nobody has said anything useful, and it's been a day since it has been posted. I'm trying to scan for a memory address in a targeted process, but it goes really really slow. Either that, or there's something wrong with my function, because it has never returned. This is my memory editing class,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace Black_Downloader
{
    class MemoryEditor
    {
        public const uint DELETE = 0x00010000;
        public const uint READ_CONTROL = 0x00020000;
        public const uint WRITE_DAC = 0x00040000;
        public const uint WRITE_OWNER = 0x00080000;
        public const uint SYNCHRONIZE = 0x00100000;
        public const uint END = 0xFFF;
        public const uint PROCESS_ALL_ACCESS = (DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | SYNCHRONIZE | END);

        public Process targetedProcess;

        [DllImport("kernel32.dll")]
        public static extern int OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll")]
        public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesRead);

        [DllImport("kernel32.dll")]
        public static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesWritten);

        public Process targetProcess(string name, int index = 0)
        {
            return (targetedProcess = Process.GetProcessesByName(name)[index]);
        }

        public int getHandle(Process proc, uint access = PROCESS_ALL_ACCESS)
        {
            return OpenProcess(access, false, proc.Id);
        }

        public byte[] getBytesFromString(string str)
        {
            return Encoding.Unicode.GetBytes(str);
        }

        public string getStringFromBytes(byte[] byteArr)
        {
            return Encoding.Unicode.GetString(byteArr);
        }

        public int makeHex(string str)
        {
            return (int.Parse(str, System.Globalization.NumberStyles.HexNumber));
        }

        public byte[] ReadMemory(int address, int processSize)
        {
            byte[] buffer = new byte[processSize];
            ReadProcessMemory(getHandle(targetedProcess), address, buffer, processSize, 0);
            return buffer;
        }

        public int GetAddress(byte[] memory, int index = 0)
        {
            int bufi = 0;

            for (int i = 0; i < int.MaxValue; i++)
                if (ReadMemory(makeHex(i.ToString()), GetObjectSize(memory)) == memory && bufi++ -1 == index)
                    return i;

            return -1;
        }

        public void WriteMemory(int address, byte[] processBytes)
        {
            WriteProcessMemory(getHandle(targetedProcess), address, processBytes, processBytes.Length, 0);
        }

        public int GetObjectSize(object TestObject)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            byte[] Array;
            bf.Serialize(ms, TestObject);
            Array = ms.ToArray();
            return Array.Length;
        }
    }
}

The class works without any problems except for the address scanner. Here is the address scanner function.

        public int GetAddress(byte[] memory, int index = 0)
        {
            int bufi = 0;

            for (int i = 0; i < int.MaxValue; i++)
                if (ReadMemory(makeHex(i.ToString()), GetObjectSize(memory)) == memory && bufi++ -1 == index)
                    return i;

            return -1;
        }

I really don't know why this thing is so slow, when I do the exact same thing in Cheat Engine, it does it immediantly, since I'm targeting notepad, and it scans addresses from 0 to the max value of a long, but mine only goes from 0 to the max size of an int.

Recommended Answers

All 2 Replies

I really don't know why this thing is so slow, when I do the exact same thing in Cheat Engine, it does it immediantly, since I'm targeting notepad, and it scans addresses from 0 to the max value of a long, but mine only goes from 0 to the max size of an int.

It does not go to the size of a long, you don't have that much memory or time. Even if you had a processor that was running at 1000 Ghz it will still take over 200 days to just count to the size of a long, much less do anything else.

Now, as to why it is slow. Lets break it down as most of your problem is in the if statement

makeHex(i.ToString()) - You take an integer, convert it to a string, then convert it back to an integer. And you act as if the string were a hex string, which causes you to miss memory locations. Just use i here and you'd be fine.

GetObjectSize(memory) - This is a method call that you make every time you iterate the loop, but it never changes value. Move this outside the loop, call it once and be done with it.

ReadMemory(makeHex(i.ToString()), GetObjectSize(memory)) == memory - This is asking if the memory read is the same as the reference to 'memory'. It is not comparing the contents of memory if that's what you think it is doing.

bufi++ -1 == index - Even if by some chance the previous was true, this can only ever be true on iteration index+1 through the loop. So you might as well skip the loop and just check the one memory location that this condition holds true.

What is it that you want this method to actually do?

What is it that you want this method to actually do?

I'm trying to find the memory address of specific memory in a program. And as for the stuff you mentioned, I'm going to change the class.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.