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 


C# Memory Library
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
KryziK
Expert Cheater
Reputation: 3

Joined: 16 Aug 2009
Posts: 186

PostPosted: Mon Jan 24, 2011 9:50 pm    Post subject: C# Memory Library Reply with quote

Hello everyone,

Today I present my .NET Memory Library/Class. (It has only been tested with C# thus far, and anybody willing to test and report will be appreciated!)
Please note that it IS a work in progress. If problems are reported or more features are suggested I will update it!

It's quite similar to this one, but, believe it or not, I didn't actually see this one until I was almost done with mine.
Some of the memory methods were also taken from here, and modified.

Date: January 28, 2011
Version: 1.0.0.4
Download: http://www.mediafire.com/?z2q790g03by1d

Note: You must add the DLL as a Reference to the Project, and then put
Code:
using MemoryEditor;
at the top of your Project.

Functions:
Code:
//Open Process
bool OpenProcess() //Opens Current Process
bool OpenProcess(string sProcessName) //Opens Process by Name
bool OpenProcess(int iProcessID) //Opens Process by PID

//Get Modules
ProcessModuleCollection GetModules() //Returns a list of Modules associated with the Process

//Get Process Info
string Name() //Returns the Process' Name
int PID() //Returns the Process' ID
int SID() //Returns the Session ID
string FileVersion() //Returns the Process' File Version
string StartTime() //Returns the Process' Start Time

//Get Module Info
int BaseAddress() //Returns the Main Module's Base Address
int BaseAddress(string sModuleName) //Returns the Module's Base Address
int EntryPoint() //Returns the Main Module's Entry Address
int EntryPoint(string sModuleName) //Returns the Module's Entry Address
int MemorySize() //Returns the Main Module's Size in Memory
int MemorySize(string sModuleName) //Returns the Module's Size in Memory

//Read from Address
byte ReadByte(int iMemoryAddress) //Reads a Byte from an Address
ushort ReadShort(int iMemoryAddress) //Reads a Short from an Address
uint ReadInt(int iMemoryAddress) //Reads an Integer from an Address
long ReadLong(int iMemoryAddress) //Reads a Long from an Address
float ReadFloat(int iMemoryAddress) //Reads a Float from an Address
double ReadDouble(int iMemoryAddress) //Reads a Double from an Address
string ReadString(int iMemoryAddress, uint iTextLength, int iMode = 0) //Reads a String from an Address. iMode explained below
byte[] ReadAOB(int iMemoryAddress, uint iBytesToRead) //Reads a Byte Array from an Address

//Write to Address
bool Write(int iMemoryAddress, byte bByteToWrite) //Writes a Byte to an Address
bool Write(int iMemoryAddress, short iShortToWrite) //Writes a Short to an Address
bool Write(int iMemoryAddress, int iIntToWrite) //Writes an Integer to an Address
bool Write(int iMemoryAddress, long iLongToWrite) //Writes a Long to an Address
bool Write(int iMemoryAddress, float iFloatToWrite) //Writes a Float to an Address
bool Write(int iMemoryAddress, double iDoubleToWrite) //Writes a Double to an Address
bool Write(int iMemoryAddress, string sTextToWrite, int iMode = 0) //Writes a String to an Address. iMode explained below
bool Write(int iMemoryAddress, byte[] bBytesToWrite) //Writes a Byte Array to an Address
bool NOP(int iMemoryAddress, int iLength) //NOPs X Bytes at an Address

//Read from Pointer
byte ReadByte(int iMemoryAddress, int[] iOffsets) //Reads a Byte from a Pointer
ushort ReadShort(int iMemoryAddress, int[] iOffsets) //Reads a Short from a Pointer
uint ReadInt(int iMemoryAddress, int[] iOffsets) //Reads an Integer from a Pointer
long ReadLong(int iMemoryAddress, int[] iOffsets) //Reads a Long from a Pointer
float ReadFloat(int iMemoryAddress, int[] iOffsets) //Reads a Float from a Pointer
double ReadDouble(int iMemoryAddress, int[] iOffsets) //Reads a Double from a Pointer
string ReadString(int iMemoryAddress, int[] iOffsets, uint iStringLength, int iMode = 0) //Reads a String from an Pointer. iMode explained below
byte[] ReadAOB(int iMemoryAddress, int[] iOffsets, uint iBytesToRead) //Reads a Byte Array from a Pointer

//Write to Pointer
bool Write(int iMemoryAddress, int[] iOffsets, byte bByteToWrite) //Writes a Byte to a Pointer
bool Write(int iMemoryAddress, int[] iOffsets, short iShortToWrite) //Writes a Short to a Pointer
bool Write(int iMemoryAddress, int[] iOffsets, int iIntToWrite) //Writes an Integer to a Pointer
bool Write(int iMemoryAddress, int[] iOffsets, long iLongToWrite) //Writes a Long to a Pointer
bool Write(int iMemoryAddress, int[] iOffsets, float iFloatToWrite) //Writes a Float to a Pointer
bool Write(int iMemoryAddress, int[] iOffsets, double iDoubleToWrite) //Writes a Double to a Pointer
bool Write(int iMemoryAddress, int[] iOffsets, string sTextToWrite, iMode = 0) //Writes a String to a Pointer. iMode explained below
bool Write(int iMemoryAddress, int[] iOffsets, byte[] bBytesToWrite) //Writes a Byte Array to a Pointer
bool NOP(int iMemoryAddress, int[] iOffsets, int iLength) //NOPs X Bytes (Pointer) //NOPs X Bytes at a Pointer

//Conversions
int Dec(int iHex) //Converts a Hexadecimal Value into Decimal
int Dec(string sHex) //Converts a Hexadecimal Value into Decimal
string Hex(int iDec) //Converts a Decimal Value into Hexadecimal
string Hex(string sDec) //Converts a Decimal Value into Hexadecimal

//Miscellaneous
bool BytesEqual(byte[] bBytes_1, byte[] bBytes_2) // Checks if two Byte Arrays are equivalent
bool IsNumeric(string sNumber) //Checks if Input String contains only Digits
byte[] ReverseBytes(byte[] bOriginalBytes) //Flips the Bytes in an Array. "AABBCCDD" becomes "DDCCBBAA"

//Creates a Static Address based on an Offset
int CalculateStaticAddress(string sStaticOffset) //Returns BaseAddress+StaticOffset
int CalculateStaticAddress(int iStaticOffset) //Returns BaseAddress+StaticOffset
int CalculateStaticAddress(string sStaticOffset, string sModuleName) //Returns ModuleBaseAddress+StaticOffset
int CalculateStaticAddress(int iStaticOffset, string sModuleName) //Returns ModuleBaseAddress+StaticOffset


Writing Types (ONLY IF NOT PRE-DECLARED):
    Byte: Prefix "(byte)"
    Short: Prefix "(short)"
    Int: Any non-float number will default to this type
    Long: Prefix "(long)" OR any number longer than an integer
    Float: Suffix "f"
    Double: Suffix "d" OR any number with a decimal
    Examples:
      Byte - "Write(iAddress, (byte)137);"
      Short - "Write(iAddress, (short)5000);"
      Integer - "Write(iAddress, 512591);"
      Long - "Write(iAddress, (long)125012);" or "Write(iAddress, 12357129572591);"
      Float - "Write(iAddress, 50.5f);"
      Double - "Write(iAddress, 920.512485d);" or "Write(iAddress, 125.125);"



The difference between iMode = 0 and iMode = 1:

Here's a picture, for reference:


Alright, so say you read from the Address 52BD87. With iMode = 0, you get
Code:
Tuto

and with iMode = 1, you get
Code:
5475746F


So, basically, one Reads/Writes ASCII, and the other Reads/Writes literal Hex Bytes.

Here's a basic example for the Cheat Engine Tutorial (v3.1):
Note: This demonstrates Pointers. If the Static Address is not a pointer you would just ignore the Offsets Parameter.
A full trainer is provided on the Downloads Page. This is just for quick reference.
Code:
using MemoryEditor;

static void Main(string[] args)
{
   Console.WriteLine("Please open Tutorial-i386.exe and press ENTER...");

   Memory oMemory = new Memory(); //Create Memory Class
   if (oMemory.OpenProcess("Tutorial-i386")) //Open Handle to Tutorial-i386.exe
   {
      Console.WriteLine("\tPID: " + oMemory.PID());
      Console.WriteLine("\tSID: " + oMemory.SID());
      //Console.WriteLine("\tFILE VERSION: " + oMemory.FileVersion());
      Console.WriteLine("\tSTART TIME: " + oMemory.StartTime());
      Console.WriteLine("\tBASE ADDRESS: 0x" + oMemory.Hex(oMemory.BaseAddress()) + "\n");

      oMemory.Write(0x57C310, new int[] { 0x458 }, (short)1000); //Completes Step 2

      //oMemory.Write(0x57C320, new int[] { 0x45C }, (short)5000); //Completes Step 3

      //oMemory.Write(0x57C340, new int[] { 0x46C }, 5000f); //Completes Step 4.1
      //oMemory.Write(0x57C340, new int[] { 0x470 }, 5000d); //Completes Step 4.2

      //oMemory.NOP(oMemory.CalculateStaticAddress(0x21DAA), 2); //Completes Step 5
         
      //oMemory.Write(0x57C370, new int[] { 0 }, (short)5000); //Completes Step 6

      //oMemory.Write(0x57C3A0, new int[] { 0xC, 0x14, 0, 0x18 }, (short)5000); //Completes Step 8
   }
}


Update Log:
Code:
January 28, 2011: Added more overloads for simplicity.

January 26, 2011:
Some functions changed back to using overloads, as suggested by slovach
OpenProcess Import removed thanks to Wiccaan

January 24, 2011: Initial Release


Finally, if there are any questions, comments, concerns, suggestions, helpful hints for others, bugs, or anything else, please either PM me or post it here.
Your name will be included along with your contribution on this post!


Last edited by KryziK on Fri Jan 28, 2011 2:32 pm; edited 9 times in total
Back to top
View user's profile Send private message
AhMunRa
Grandmaster Cheater Supreme
Reputation: 27

Joined: 06 Aug 2010
Posts: 1117

PostPosted: Mon Jan 24, 2011 10:06 pm    Post subject: Reply with quote

What will be the impact of using this class?

I mean will it affect overall size of finished exe, or will the executable have to be packaged with the Memory.dll in order to run since it isn't part of the stock C# lib.

I broke up the memoryapi from your last tut and created a seperate memory class and when built it produced a dll that I would have to distribute with my app.

One of the things I loved about your other post was the fact that as long as the user has the .NET framework they have all they need to run the app.

_________________
<Wiccaan> Bah that was supposed to say 'not saying its dead' lol. Fixing >.>
Back to top
View user's profile Send private message
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5813

PostPosted: Mon Jan 24, 2011 10:16 pm    Post subject: Reply with quote

there exists these cool things called operator overloading and generics, you should look into them.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 96

Joined: 25 Jan 2006
Posts: 5528
Location: 127.0.0.1

PostPosted: Tue Jan 25, 2011 12:32 pm    Post subject: Reply with quote

There's kind of no reason for you to import OpenProcess and use it in C# when you can obtain a handle to a process using the Process class already.
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx

GetLastError returns a DWORD which you just convert to string, you should use FormatMessage and convert it to a proper error string if you plan to return it to the user.
http://msdn.microsoft.com/en-us/library/ms679351%28VS.85%29.aspx

Also keep in mind that calling API outside of managed code can get skewed results, so GetLastError may not be reliable:
http://blogs.msdn.com/b/adam_nathan/archive/2003/04/25/56643.aspx

_________________
- Retired.
Back to top
View user's profile Send private message
KryziK
Expert Cheater
Reputation: 3

Joined: 16 Aug 2009
Posts: 186

PostPosted: Tue Jan 25, 2011 1:52 pm    Post subject: Reply with quote

slovach wrote:
there exists these cool things called operator overloading and generics, you should look into them.


I've taken a look at Generics, and I'm not quite sure they're what I want or not. Then again I'm not really sure what the best method is so could you elaborate? I know how to overload so that part isn't a problem. The part that IS a problem however is putting (type) in front of the value, such as (short)5000. I'd like to not have to use this, but if there's no other way it will have to do.

Quote:
There's kind of no reason for you to import OpenProcess and use it in C# when you can obtain a handle to a process using the Process class already.


So instead of OpenProcess I would just use Process.Handle? It seems to work, but does the handle need to be closed after the memory functions have been called, or can it be left alone?

Quote:

One of the things I loved about your other post was the fact that as long as the user has the .NET framework they have all they need to run the app.


Well, you could just download the source and copy the code from the class straight into your namespace. That way it would be the same thing. Otherwise I'm pretty sure you would have to have a copy of the DLL present. Seeing as I'm about to rewrite the code a bit, you may want to wait a little or else you might need to rename some of your functions.
Back to top
View user's profile Send private message
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5813

PostPosted: Tue Jan 25, 2011 5:45 pm    Post subject: Reply with quote

If you don't want to use generics, you can just use an IntPtr (and pretend it's a void pointer) I guess.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 96

Joined: 25 Jan 2006
Posts: 5528
Location: 127.0.0.1

PostPosted: Wed Jan 26, 2011 4:54 pm    Post subject: Reply with quote

No the handles obtained from the Process class are maintained internally, you do not need to close them.
_________________
- Retired.
Back to top
View user's profile Send private message
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5813

PostPosted: Thu Jan 27, 2011 11:21 pm    Post subject: This post has 1 review(s) Reply with quote

Don't know why this got locked, unlocking
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 96

Joined: 25 Jan 2006
Posts: 5528
Location: 127.0.0.1

PostPosted: Fri Jan 28, 2011 1:29 am    Post subject: Reply with quote

slovach wrote:
Don't know why this got locked, unlocking


May have been me by mistake due to another thread, if so sorry about that. Surprised

_________________
- Retired.
Back to top
View user's profile Send private message
ej52
Cheater
Reputation: 0

Joined: 29 Mar 2011
Posts: 39
Location: Mother City

PostPosted: Wed Mar 30, 2011 4:42 pm    Post subject: Code Injection Reply with quote

Hey Darkjohn

I jst dwnloaded this and i noticed @ step7 you said the following ...

Quote:
"I cannot complete Step 7 yet because I can't assemble and inject code. Please manually do this step or press SKIP"


Is this still the case? or do you knw how 2 do code injection with C# now?

Ej52
Back to top
View user's profile Send private message
KryziK
Expert Cheater
Reputation: 3

Joined: 16 Aug 2009
Posts: 186

PostPosted: Wed Mar 30, 2011 4:44 pm    Post subject: Reply with quote

Still the case. I haven't really looked into it much.
Back to top
View user's profile Send private message
AhMunRa
Grandmaster Cheater Supreme
Reputation: 27

Joined: 06 Aug 2010
Posts: 1117

PostPosted: Wed Mar 30, 2011 4:58 pm    Post subject: Reply with quote

I have, you will need to write code to create a code cave in the app. I was working on it, but got side tracked.
_________________
<Wiccaan> Bah that was supposed to say 'not saying its dead' lol. Fixing >.>
Back to top
View user's profile Send private message
KryziK
Expert Cheater
Reputation: 3

Joined: 16 Aug 2009
Posts: 186

PostPosted: Wed Mar 30, 2011 5:00 pm    Post subject: Reply with quote

AhMunRa wrote:
I have, you will need to write code to create a code cave in the app. I was working on it, but got side tracked.


Yeah, that's about as far as I got.
Back to top
View user's profile Send private message
ej52
Cheater
Reputation: 0

Joined: 29 Mar 2011
Posts: 39
Location: Mother City

PostPosted: Wed Mar 30, 2011 5:01 pm    Post subject: Reply with quote

Ok i've managed 2 get it workin with simple injections ...

I added VirtualAllocEx and VirtualFreeEx to the memory class from your other post
and wrote a simple function that calculates the bytes for a JMP to a newly
allocated memory region (using VirtualAllocEx), which allows me to inject code. Smile

If you'd like i'll post a tutorial/sample code 2moro Smile

Ej52
Back to top
View user's profile Send private message
KryziK
Expert Cheater
Reputation: 3

Joined: 16 Aug 2009
Posts: 186

PostPosted: Wed Mar 30, 2011 5:02 pm    Post subject: Reply with quote

Sure.
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
Goto page 1, 2, 3  Next
Page 1 of 3

 
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)