Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Cheat Engine and C# - Notepad.exe

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
YeahNo
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 1

PostPosted: Sat Jul 04, 2015 3:30 pm    Post subject: Cheat Engine and C# - Notepad.exe Reply with quote

Hello,

I'm trying to learn a few things about reading and writing memory in C#. I'm currently stuck on a very basic step - reading and writing from/ to Notepad.exe.

I'm using Windows 10 and I can't seem to find the correct offset that controls input string. For example, if I type 'g' into notepad I'd like to read it through offset (and then later make it say something else).

When scanning for pointers to 'g' I'm left with 1309 results after few goes (it doesn't go lower):
imgur / rbT9egV.png

So my pointer should be 0x0001B3B8 (for example). Ok, so I take this pointer and input it into my C# code...

EDIT: The pointer is obviously wrong. Look like I'll first have to find notepad.exe base address by using
Code:
[DllImport("kernel32.dll")]
        public static extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme);


And I'm not quiet sure what to do next, but I'll try following "FAQ: How to use a pointer" and hopefully figure it out.

Obviously any of you can still help.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8517
Location: 127.0.0.1

PostPosted: Sat Jul 04, 2015 10:10 pm    Post subject: Reply with quote

You do not need to use Module32First in .NET, instead, you can make use of the Process class which has all of the similar features exposed already.

See here:
https://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.100).aspx

You can obtain a list of processes by their name using:
Code:
var procs = Process.GetProcessesByName("notepad");


You can obtain a list of the processes modules then afterward like this:
Code:
var procs = Process.GetProcessesByName("notepad");
if (procs.Length > 0)
{
    // Use the first found process..
    var proc = procs[0];
   
    // Obtain the main module information of the process..
    //
    // This will contain the notepad.exe 'module' information.
    var mainModule = proc.MainModule;
   
    //
    // TODO: Do the rest of your code here..
    //


To mimic what Cheat Engine shows with:
"notepad.exe" + 0001B3B8

You can do:
Code:
var procs = Process.GetProcessesByName("notepad");
if (procs.Length > 0)
{
    // Use the first found process..
    var proc = procs[0];
   
    // Obtain the main module information of the process..
    //
    // This will contain the notepad.exe 'module' information.
    var mainModule = proc.MainModule;
   
    // Calculate the address like Cheat Engine..
    var address = mainModule.BaseAddress.ToInt32() + 0x0001B3B8;
   
    //
    // TODO: Do the rest of your code here..
    //
}


Then you can use 'address' for whatever you need.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
YeahNo
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 1

PostPosted: Sun Jul 05, 2015 7:05 am    Post subject: Reply with quote

atom0s wrote:
snip

Glad to know I don't have to use Module32First, thanks!

EDIT:
Since I couldn't find the right offset for inputted text I decided to find offset indicating if text is selected or not.

Luckily I was able to find a static address right off the bat, replaced the offset in my code and voila - I can now read value indicating if text is selected or not.

It also works if I close and reopen notepad.

Now I need to find out how to find more complex pointers, which seems to be pain in the ass.
/EDIT

I've included your solution and found out that notepad.exe's base address is '140695836819456', add to that the found offset of '0x0001B3B8' and I get '140695836931000' which is my 'address'. As far as calculations go this is correct.

The problem is I don't have the right offset and I realize this because this code returns same 'memory[0]', even if I change character in notepad.exe. Here's the code:
Code:
static void Main(string[] args)
        {
            ProcessMemoryReader memoryReader = new ProcessMemoryReader();
            Process[] process = Process.GetProcessesByName("notepad");
            memoryReader.ReadProcess = process[0];
            if (process.Length > 0)
            {
                var mainModule = process[0].MainModule;
                Console.WriteLine(mainModule.BaseAddress);
                var address = mainModule.BaseAddress.ToInt64() + 0x0001B3B8;
                Console.WriteLine(address);
                memoryReader.OpenProcess();
                int bytesRead;
                byte[] memory;
                memory = memoryReader.ReadProcessMemory((IntPtr)address, 1, out bytesRead);
                Console.WriteLine(memory[0]);
                Console.WriteLine(Encoding.Unicode.GetString(memory));
            }

where ProcessMemoryReaderApi is
Code:
class ProcessMemoryReaderApi
    {
        public const uint PROCESS_VM_READ = (0x0010);
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
        [DllImport("kernel32.dll")]
        public static extern Int32 CloseHandle(IntPtr hObject);
        [DllImport("kernel32.dll")]
        public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
    }

and ProcessMemoryReader is
Code:
 public class ProcessMemoryReader
    {
        public ProcessMemoryReader()
        {
        }
        public Process ReadProcess
        {
            get
            {
                return m_ReadProcess;
            }
            set
            {
                m_ReadProcess = value;
            }
        }
        private Process m_ReadProcess = null;
        private IntPtr m_hProcess = IntPtr.Zero;
        public void OpenProcess()
        {
            m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_VM_READ, 1, (uint)m_ReadProcess.Id);
        }
        public void CloseHandle()
        {
            int iRetValue;
            iRetValue = ProcessMemoryReaderApi.CloseHandle(m_hProcess);
            if (iRetValue == 0)
                throw new Exception("CloseHandle failed");
        }
        public byte[] ReadProcessMemory(IntPtr MemoryAddress, uint bytesToRead, out int bytesReaded)
        {
            byte[] buffer = new byte[bytesToRead];
            IntPtr ptrBytesReaded;
            ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, MemoryAddress, buffer, bytesToRead, out ptrBytesReaded);
            bytesReaded = ptrBytesReaded.ToInt32();
            return buffer;
        }
    }

BTW notepad is 64-bit, so I had to use
Code:
var address = mainModule.BaseAddress.ToInt64() + 0x0001B3B8;

instead of
Code:
var address = mainModule.BaseAddress.ToInt32() + 0x0001B3B8;

I'll try finding new pointers, here's my last list:
imgur / rbT9egV.png

Thanks for the help!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites