Solved

Change memory address value

Posted on 2011-03-09
23
512 Views
Last Modified: 2012-05-11
If I have memory address, how can I change its value?
0
Comment
Question by:Mohamed Abowarda
  • 10
  • 8
  • 2
  • +2
23 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Can you give some context to this question?  Why are you trying to change a value at a memory address?

As a general answer, in .Net you DON'T ever change a value at a specific memory address...unless we're talking about doing low level stuff in an "unsafe" block:
http://msdn.microsoft.com/en-us/library/chfa2zb8(VS.71).aspx
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
I have Console Application 1 that declare int variable, I used unsafe code to read the memory address for the int variable, I want to read or change this value on Console Application 2 using its memory address.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
That sounds like a job better solved with .Net Remoting or WCF.

Does console1 spawn console2?  How big is the int value?  How often does the value need to be changed?  Can you simply make console2 return the value to console1 using an exitcode?  Does it only need to be one way communication?...or two way?

Give more details...
0
 
LVL 8

Expert Comment

by:Subrat (C++ windows/Linux)
Comment Utility
In C/C++ you do as follows,

int a;
int* p = &a;
*p = 100;//Your desire value

Now a will hold value 100.
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@Idle_Mind, I want to be able to read or change some variables in Console Application 1 using Console Application 2 anytime while the both processes is running.

The variable could be any data type not just integer.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
...and this is .Net right?  Not pure C/C++?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
If .Net, what version you running?
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
.NET Framework 3.5
Visual Studio 2008
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
*I have no idea how to do this using unsafe code*

I can show you how to communicate from console2 to console1 using REMOTING, though, if you like.  It is not a straight forward process...but passing things between processes never is.
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@Idle_Mind: I tried to declare a pointer and set the pointer address to the other process variable memory address, I get the following exception:
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

I would prefer if it's possible to change other processes variables in memory, however, if it's not possible you can show how to communicate between two processes without using sockets.
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 450 total points
Comment Utility
This low level stuff is definitely not my forte...

I believe you need to be using the WriteProcessMemory() API if you want to put your int value into a specific address:
http://msdn.microsoft.com/en-us/library/ms681674(VS.85).aspx
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 5

Assisted Solution

by:MedievalWarrior
MedievalWarrior earned 50 total points
Comment Utility
You can't use the same memory pointer in one process  between different processes because the memory pointer doesn't exist in the other process. If you used .NET 4.0 then you could do this using managed code with the MemoryMappedFile Class.

MemoryMappedFile
http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile.aspx

You would need to use P/Invoke though for 3.5

Creating Named Shared Memory
http://msdn.microsoft.com/en-us/library/aa366551(v=vs.85).aspx

The above is the closest you would get to work with a pointer that both processes could share but as Idle_Mind suggest there are other alternatives like remoting and named pipes
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
I don't think you can do what you describe.  Each application has it's own memory space and the adress you get is the adress of the memory in the assigned block of memory for the application, not a global memory adress.
You need some sort of interprocess communication - which I assume you do have already else how does app2 'know' the address to modify in app1 ?
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@Idle_Mind: ReadProcessMemory() and WriteProcessMemory() works great! the only thing I need to know is how to get the process handle if I didn't started it by using System.Diagnostics.Process class?
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 450 total points
Comment Utility
You can use Process.GetProcessesByName()
// pass the app name with no path AND with no extension:
            Process[] ps = Process.GetProcessesByName("console");
            if (ps.Length > 0)
            {
                // do something with "ps[0].Handle"
            }

Open in new window


See:
http://msdn.microsoft.com/en-us/library/z3w4xdc9.aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.handle.aspx

How are you going to initially pass the address from console1 to console2 though?...
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
Idle_Mind: I can use the registry to save the addresses and read it using the other application, if you have any other suggestion, please let me know.

I have increased the points to 500.

Thank you,
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
If console1 spawns console2 then you could just pass it as a command line parameter.
0
 
LVL 5

Expert Comment

by:MedievalWarrior
Comment Utility
It appears the OP has a static pointer to the variable in memory and doesn't actually *own the other process. If you do own the other console application it would be in your best interest to avoid using these methods since there are much safer alternatives.
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@Idle_Mind: Console1 will not spawns Console2.

@MedievalWarrior: I actually own the both applications.
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
You NEED some sort of interprocess communication for what you are doing.
Why not use that to just pass the value you want it changing to rather than attempting to modify the memory adress directly.
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 450 total points
Comment Utility
Just so you have it, here's an example of using .Net remoting to send an int from Console2 to Console1.

Here's the remoteable object that allows the value to be passed between the processes.  Compile this as its own Class Library.  Both Console1 and Console2 will add a Reference to this DLL:
using System;
using System.Collections.Generic;
using System.Text;

namespace RemoteableObject
{
    public class Communicator : MarshalByRefObject 
    {

        public delegate void MyDelegate(int value);
        public event MyDelegate ValueSent;

        public void Send(int value)
        {
            if (ValueSent != null)
            {
                ValueSent(value);
            }
        }

        public override object InitializeLifetimeService()
        {
            return null; // object stays alive forever 
            // (otherwise it literally "dies" after 10 minutes when its lease expires)
        }

    }
}

Open in new window


Here is Console1 that will host the remoteable object and will receive the int value:
// Project --> Add Reference --> Browse Tab --> RemoteableObject.dll
// Project --> Add Reference --> .Net Tab --> System.Runtime.Remoting
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace ConsoleApplication1
{
    class Program
    {
        private static bool Shutdown = false;
        private static TcpChannel Channel = new TcpChannel(50001);
        private static RemoteableObject.Communicator Comms = new RemoteableObject.Communicator();

        static void Main(string[] args)
        {
            RemotingServices.Marshal(Comms, "Comms"); // the string value is a unique channel name identifier (it can be different than the variable)
            ChannelServices.RegisterChannel(Channel, false); // the remoteable object will be available on tcpchannel 50001
            Comms.ValueSent += new RemoteableObject.Communicator.MyDelegate(Comms_ValueSent);

            while (!Shutdown)
            {
                System.Threading.Thread.Sleep(100);
            }

            Console.Write("Press enter to continue...");
            Console.ReadLine();
        }

        static void Comms_ValueSent(int value)
        {
            Console.WriteLine("Value received: " + value.ToString());
            if (value == -1)
            {
                Shutdown = true;
            }
        }

    }
}

Open in new window


Finally, here is Console2 that will obtain a reference to the actual remoteable object being housed in Console1.  Note that we are connecting to localhost (because both apps are on the same computer) we are acccessing it "by name" on channel 50001.  You could actually use this to communicate across a LAN by replacing "localhost" with a computer name:
// Project --> Add Reference --> Browse Tab --> RemoteableObject.dll
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {

        static void Main(string[] args)
        {
            int value = 0;
            string entry;
            RemoteableObject.Communicator Comms = 
                (RemoteableObject.Communicator)Activator.GetObject(typeof(RemoteableObject.Communicator), "tcp://localhost:50001/Comms");
           
            do
            {
                Console.Write("Enter an integer to send (-1 to kill both apps): ");
                entry = Console.ReadLine();
                if (int.TryParse(entry, out value))
                {
                    try
                    {
                        Comms.Send(value);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Send failed: " + ex.ToString());
                        
                    }
                }
                else
                {
                    Console.WriteLine("Invalid Integer Entered.");
                }
            }
            while (value != -1);

            Console.Write("Press enter to continue...");
            Console.ReadLine();
        }

    }
}

Open in new window


Run Console1 first then load up Console2.  Enter an integer into Console2 and it should appear in Console1.  Enter -1 to shut down both apps.
0
 
LVL 12

Author Closing Comment

by:Mohamed Abowarda
Comment Utility
Great!

Thanks a lot,
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
You got that integrated into your project already?  =)
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Wpf develop 5 29
c# regex: extract & replace text between braces 6 28
dynamic menu in asp.net c# 11 25
VB.NET HttpWebRequest 12 30
In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now