Solved

Change memory address value

Posted on 2011-03-09
23
517 Views
Last Modified: 2012-05-11
If I have memory address, how can I change its value?
0
Comment
Question by:Mohamed Abowarda
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 8
  • 2
  • +2
23 Comments
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35088477
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
ID: 35088739
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 86

Expert Comment

by:Mike Tomlinson
ID: 35088789
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 9

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 35088838
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
ID: 35088903
@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 86

Expert Comment

by:Mike Tomlinson
ID: 35088917
...and this is .Net right?  Not pure C/C++?
0
 
LVL 86

Expert Comment

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

Author Comment

by:Mohamed Abowarda
ID: 35089036
.NET Framework 3.5
Visual Studio 2008
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35089653
*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
ID: 35089891
@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 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 450 total points
ID: 35089981
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
 
LVL 5

Assisted Solution

by:MedievalWarrior
MedievalWarrior earned 50 total points
ID: 35091109
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
ID: 35093413
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
ID: 35094521
@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 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 450 total points
ID: 35094727
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
ID: 35094909
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 86

Expert Comment

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

Expert Comment

by:MedievalWarrior
ID: 35094934
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
ID: 35094967
@Idle_Mind: Console1 will not spawns Console2.

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

Expert Comment

by:AndyAinscow
ID: 35095874
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 86

Accepted Solution

by:
Mike Tomlinson earned 450 total points
ID: 35096619
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
ID: 35098986
Great!

Thanks a lot,
0
 
LVL 86

Expert Comment

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

Featured Post

Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…

627 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