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# - Replace with Code/Script
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Sun Oct 17, 2010 1:01 pm    Post subject: C# - Replace with Code/Script Reply with quote

Ok, let me give a brief description of what my code does right now. Currently it uses a checkbox with a timer to freeze memory address to a specified value. It seems like there's more efficient way of doing this, similar to Cheat Engine's auto assembler scripts rather than writing to an address constantly.

So is there a way I can implement something similar to the auto assembler scripts using C#, for instance replacing the value with something that does nothing?

Here's my source right now. It scans for a four level pointer with a function and writes it using a timer function toggled with a checkbox.

Gets the health pointer.
Code:

private IntPtr getHealth1()
        {
            process = Process.GetProcessesByName("Arcania");
            mainModule = process[0].MainModule;
            preader.ReadProcess = process[0];
            preader.OpenProcess();

            int baseAddress = (int)mainModule.BaseAddress;
            int bytesRead;

            byte[] mem1 = preader.ReadProcessMemory((IntPtr)(baseAddress + 0x01003E1C), 4, out bytesRead);
            int num1 = BitConverter.ToInt32(mem1, 0);

            IntPtr base2 = new IntPtr(num1 + Convert.ToInt32(0x124));
            byte[] mem2 = preader.ReadProcessMemory(base2, 4, out bytesRead);
            int num2 = BitConverter.ToInt32(mem2, 0);

            IntPtr base3 = new IntPtr(num2 + Convert.ToInt32(0x4));
            byte[] mem3 = preader.ReadProcessMemory(base3, 4, out bytesRead);
            int num3 = BitConverter.ToInt32(mem3, 0);

            IntPtr base4 = new IntPtr(num3 + Convert.ToInt32(0x14));
            byte[] mem4 = preader.ReadProcessMemory(base4, 4, out bytesRead);
            int num4 = BitConverter.ToInt32(mem4, 0);

            IntPtr base5 = new IntPtr(num4 + Convert.ToInt32(0xFC));

            return base5;
        }


Writes the value 999 to memory on a 100ms interval. Enabled/disabled with a checkbox.
Code:

private void health_Tick(object sender, EventArgs e)
        {
            int bytesWrote;
            float value = 999;
            byte[] mem = BitConverter.GetBytes(value);
            preader.WriteProcessMemory(getHealth1(), mem, out bytesWrote);
            preader.WriteProcessMemory(getHealth2(), mem, out bytesWrote);
        }


Thanks,
Thunder
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Sun Oct 17, 2010 2:36 pm    Post subject: Reply with quote

That's pretty much the same way CE freezes values. To remove the code that alters the health, you use exactly the same method of injection (although you might have to allocate memory and toggle the execute bit on it if you require a code-cave). The matter of determining what to inject and where is the challenge, but it isn't really a programming challenge.

Cheers,
add
Back to top
View user's profile Send private message
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Sun Oct 17, 2010 6:58 pm    Post subject: Reply with quote

Isn't removing the code that alters health more efficient than constantly running timers though?

And how would I go about coding the script and injection into C#? I'm new to it and any links with more detail on this would help if you have any.

Thanks again.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Sun Oct 17, 2010 6:58 pm    Post subject: Reply with quote

A more efficient way would be to create a cave and alter the actual code of the game to write the value you want each time it's called. In some cases it might be a quick and simple thing to do, but in more common games, health functions are shared between all objects in the game so you may need to add more checks and such to ensure you are only setting your health and not enemies, etc.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Sun Oct 17, 2010 8:03 pm    Post subject: Reply with quote

Is there a good place where I can learn this? Maybe with some examples of code?

Another question, would creating a code cave and writing ASM involve using a .dll and injecting that using my trainer or can I do it all in C#?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Sun Oct 17, 2010 8:22 pm    Post subject: Reply with quote

Thunderstruck wrote:
Is there a good place where I can learn this? Maybe with some examples of code?

Another question, would creating a code cave and writing ASM involve using a .dll and injecting that using my trainer or can I do it all in C#?


Just check the tutorials section of the forums. There are plenty of tutorials showing how to do code caves. You can also use Cheat Engines tutorial.exe to learn some of the basics for caving.

And no you can write the raw bytes of your cave using C#. You will need to recalculate jumps and calls. But you can do it all via C#.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Sun Oct 17, 2010 8:58 pm    Post subject: Reply with quote

Ok, I've done the tutorial all the way through. I might do it again though just to get a better grasp on code caves. I'll check out the tutorial section in the meantime.

Thanks again for the help.

EDIT
I have another question. When I find the pointer using my code above, is there a way to get the actual value of what's at that address? I'd like to increment the value by one. It seems like it'd be pretty simple and I could probably figure it out after some Googling but I figured I'd ask anyway while I'm checking out code cave stuff and ASM.

_________________
"An act of God and nothing less will be accepted."
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Mon Oct 18, 2010 12:27 am    Post subject: Reply with quote

writeprocessmemory should do the trick.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Mon Oct 18, 2010 5:16 am    Post subject: Reply with quote

Thunderstruck wrote:
Ok, I've done the tutorial all the way through. I might do it again though just to get a better grasp on code caves. I'll check out the tutorial section in the meantime.

Thanks again for the help.

EDIT
I have another question. When I find the pointer using my code above, is there a way to get the actual value of what's at that address? I'd like to increment the value by one. It seems like it'd be pretty simple and I could probably figure it out after some Googling but I figured I'd ask anyway while I'm checking out code cave stuff and ASM.


ReadProcessMemory to read a value from another processes memory.
WriteProcessMemory to write a value to another processes memory.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Mon Oct 18, 2010 7:35 am    Post subject: Reply with quote

I figured it involved ReadProcessMemory. I'm guessing I have to read the memory and convert it using BitConverter just like writing it.

Thanks.

_________________
"An act of God and nothing less will be accepted."
Back to top
View user's profile Send private message
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Mon Oct 18, 2010 5:02 pm    Post subject: Reply with quote

I finished, though I didn't alter code or use code caves yet. This just freezes values and uses multi-level pointers with a function that has a rather nice for loop (the parameter is a array of ints in hex). I'll post the source here in case it helps anyone. Any suggestions are also welcome. And thanks again for the help guys.

Code:
namespace ArcaniaTrainer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            mainModule = process[0].MainModule;
            preader.ReadProcess = process[0];
            preader.OpenProcess();
        }

        ProcessMemoryReaderLib.ProcessMemoryReader preader = new ProcessMemoryReaderLib.ProcessMemoryReader();
        Process[] process = Process.GetProcessesByName("Arcania");
        ProcessModule mainModule;

        private void statusLabel_Click(object sender, EventArgs e)
        {

        }

        private void skillLabel_Click(object sender, EventArgs e)
        {

        }

        private void healthCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (healthTimer.Enabled == false)
                healthTimer.Enabled = true;
            else if (healthTimer.Enabled == true)
                healthTimer.Enabled = false;
        }

        private void manaCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (manaTimer.Enabled == false)
                manaTimer.Enabled = true;
            else if (manaTimer.Enabled == true)
                manaTimer.Enabled = false;
        }

        private void staminaCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (staminaTimer.Enabled == false)
                staminaTimer.Enabled = true;
            else if (staminaTimer.Enabled == true)
                staminaTimer.Enabled = false;
        }

        private void powerCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (powerTimer.Enabled == false)
                powerTimer.Enabled = true;
            else if (powerTimer.Enabled == true)
                powerTimer.Enabled = false;
        }

        private void infoButton_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Made by Vladimir Putin", "Credits", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void addButton_Click(object sender, EventArgs e)
        {
            int bytesRead;
            int bytesWrote;

            int[] offsets = { 0x010020D4, 0x5E0, 0x218, 0x0, 0x524 };

            byte[] mem1 = preader.ReadProcessMemory(getPointer(offsets), 4, out bytesRead);
            byte[] mem2 = BitConverter.GetBytes(BitConverter.ToSingle(mem1, 0) + 10);

            preader.WriteProcessMemory(getPointer(offsets), mem2, out bytesWrote);
        }

        private void clearButton_Click(object sender, EventArgs e)
        {
            int bytesRead;
            int bytesWrote;

            int[] offsets = { 0x010020D4, 0x5E0, 0x218, 0x0, 0x524 };

            byte[] value1 = preader.ReadProcessMemory(getPointer(offsets), 4, out bytesRead);
            byte[] value2 = BitConverter.GetBytes((float)0);

            preader.WriteProcessMemory(getPointer(offsets), value2, out bytesWrote);
        }

        private void found_Tick(object sender, EventArgs e)
        {
            Process[] pCheck = Process.GetProcessesByName("Arcania");

            if (pCheck.Length != 0)
            {
                statusLabel.Text = "Game found.\n\nLoad character\nbefore activating\noptions.";
                statusLabel.Enabled = true;
                skillLabel.Enabled = true;
                infoButton.Enabled = true;
                addButton.Enabled = true;
                clearButton.Enabled = true;
                healthCheckBox.Enabled = true;
                manaCheckBox.Enabled = true;
                staminaCheckBox.Enabled = true;
                powerCheckBox.Enabled = true;
            }

            else
            {
                statusLabel.Text = "Game not found.";
                statusLabel.Enabled = false;
                skillLabel.Enabled = false;
                infoButton.Enabled = false;
                addButton.Enabled = false;
                clearButton.Enabled = false;
                healthCheckBox.Enabled = false;
                manaCheckBox.Enabled = false;
                staminaCheckBox.Enabled = false;
                powerCheckBox.Enabled = false;
            }
        }

        private void health_Tick(object sender, EventArgs e)
        {
            int bytesWrote;
            byte[] value = BitConverter.GetBytes((float)999);

            int[] offsets1 = { 0x01003E1C, 0x124, 0x4, 0x14, 0xFC };
            int[] offsets2 = { 0x01002100, 0x3C, 0x164, 0x8, 0x80 };
           
            preader.WriteProcessMemory(getPointer(offsets1), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets2), value, out bytesWrote);
        }

        private void mana_Tick(object sender, EventArgs e)
        {
            int bytesWrote;
            byte[] value = BitConverter.GetBytes((float)999);

            int[] offsets1 = { 0x01003E1C, 0x128, 0x48, 0x4, 0x14, 0x114 };
            int[] offsets2 = { 0x01001C44, 0x438, 0x90, 0x14, 0xC, 0x80 };
           
            preader.WriteProcessMemory(getPointer(offsets1), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets2), value, out bytesWrote);
        }

        private void stamina_Tick(object sender, EventArgs e)
        {
            int bytesWrote;
            byte[] value = BitConverter.GetBytes((float)999);

            int[] offsets1 = { 0x01003E1C, 0x124, 0x4, 0x14, 0x108 };
            int[] offsets2 = { 0x01001C44, 0x438, 0x90, 0x14, 0x70 };
           
            preader.WriteProcessMemory(getPointer(offsets1), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets2), value, out bytesWrote);
        }

        private void power_Tick(object sender, EventArgs e)
        {
            int bytesWrote;
            byte[] value = BitConverter.GetBytes((float)999);

            int[] offsets1 = { 0x01003E1C, 0x124, 0x4, 0x14, 0x150 };
            int[] offsets2 = { 0x01003E1C, 0xE0, 0x34, 0x0, 0x148 };
            int[] offsets3 = { 0x01003E1C, 0xE0, 0x34, 0x0, 0x154 };
            int[] offsets4 = { 0x01003E1C, 0xE0, 0x34, 0x0, 0x14C };
            int[] offsets5 = { 0x01003E1C, 0xE0, 0x34, 0x0, 0x160 };
            int[] offsets6 = { 0x01003E1C, 0xE0, 0x34, 0x0, 0x158 };

            preader.WriteProcessMemory(getPointer(offsets1), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets2), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets3), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets4), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets5), value, out bytesWrote);
            preader.WriteProcessMemory(getPointer(offsets6), value, out bytesWrote);
        }

        private IntPtr getPointer(int[] offsets)
        {
            int bytesRead;

            byte[] mem1 = preader.ReadProcessMemory((IntPtr)((int)mainModule.BaseAddress + offsets[0]), 4, out bytesRead);
            int num1 = BitConverter.ToInt32(mem1, 0);

            IntPtr base1 = (IntPtr)0;

            for (int i = 1; i < offsets.Length; i++)
            {
                base1 = new IntPtr(num1 + Convert.ToInt32(offsets[i]));
                mem1 = preader.ReadProcessMemory(base1, 4, out bytesRead);
                num1 = BitConverter.ToInt32(mem1, 0);
            }

            return base1;
        }
    }
}

_________________
"An act of God and nothing less will be accepted."
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Mon Oct 18, 2010 5:11 pm    Post subject: Reply with quote

You don't need if/else checks for your checkbox code, you can just use the sender argument's Checked property like this:

Code:
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            timer1.Enabled = ((CheckBox)sender).Checked;
        }


Just reduces the need for extra code.

As for your pointer method, overall it's up to you how to get the final objective of your trainer/hack. If it works, it works.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Mon Oct 18, 2010 8:27 pm    Post subject: Reply with quote

Thanks, I'll make that change. The pointer method works perfectly so far, at least better copy/pasting the same lines of code for each pointer. For my first C# program, I think it went pretty well. It's pretty close to Java which is was my first language and it certainly beats C which is what I'm studying at the moment along with ASM. Hopefully I'll understand code caves and scripts much better after this semester if I can learn before then.

EDIT
I was just looking more into using a assembly script in C# and I read ASM can't be written directly in the source like C++. It also said something about a dll call, where the assembly script is written in a .dll the called into C#. Is this what I need to do or is there a way to do the same thing with C# without using assembly at all?

_________________
"An act of God and nothing less will be accepted."
Back to top
View user's profile Send private message
AhMunRa
Grandmaster Cheater Supreme
Reputation: 27

Joined: 06 Aug 2010
Posts: 1117

PostPosted: Mon Oct 18, 2010 10:03 pm    Post subject: Reply with quote

You can use ASM with C# but as far as I know C# will not handle it directly. You can call it from a dll though.

Some examples.

http://www.codeproject.com/KB/msil/reflexil.aspx

http://www.codingthewheel.com/archives/how-to-inject-a-managed-assembly-dll

http://blogs.msdn.com/b/jmstall/archive/2006/09/28/managed-create-remote-thread.aspx

_________________
<Wiccaan> Bah that was supposed to say 'not saying its dead' lol. Fixing >.>
Back to top
View user's profile Send private message
Thunderstruck
Newbie cheater
Reputation: 0

Joined: 29 Apr 2007
Posts: 16
Location: 39.531, -76.438

PostPosted: Tue Oct 19, 2010 9:02 am    Post subject: Reply with quote

Thanks, those look very helpful. I'll definitely read through them.
_________________
"An act of God and nothing less will be accepted."
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  Next
Page 1 of 2

 
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