views:

79

answers:

2

I'm writing a .SO that gets called by another program and I want to be able to flip a value in memory through a function in the .SO

What I have so far is :

int 
axptrace( int numArguments, char* pMessageBuffer, int* pMessageBufferSize,
  char* pData[], int* pDataLength[] )  
{  
printf("Beginning dump attempt..\n");  
unsigned int* wkptr =(int*)0x7f793db70040;  
printf("At %llx, the value was %d\n\n",(long long)wkptr,*wkptr);  
if(*wkptr == 1){  
 printf("Switching the value.\n");  
 *wkptr = 0;  
 printf("At %llx, the value is now %d\n\n",(long long)wkptr,*wkptr);  
 printf("Switched!\n\n");   
}  
    printf("Ending dump attempt..\n");  
}

As the program runs, I get the messages I expected:

Beginning dump attempt..
At 7f793db70040, the value was 1

Switching the value.
At 7f793db70040, the value is now 0

Switched!

Ending dump attempt..

Beginning dump attempt..

At 7f793db70040, the value was 0

Ending dump attempt..

If I run the same function again though, instead of seeing the value 0 in the first part, I see the value 1 again. I thought it had changed the value at 0x7f793db70040, but apparently it went back to the old value.

Also, the 0xf793db70040 was gotten through a debugger. Is there a way to see if a 'symbol' or something like that points to that address, and a way to use that in my code?

+4  A: 

You're setting a completely arbitrary memory address, and you expect meaningful things to happen? Memory changes all the time. It's no surprise your poking values in gets overwritten, unless you really know what that memory's for.

Now, given the high value there, it's probably a value on the stack, which means it's going to be:

  1. Changing often
  2. Used for multiple purposes
  3. Used for the same purposes at different addresses

If there was a symbol for a memory address (there won't be for addresses on the stack or heap), and it was exported (unlikely for executables), you could obtain it using dlsym - if not exported, and the executable isn't stripped, you might be able to parse ELF headers to find it (this is very difficult. You would essentially be implementing a debugger).

In general, poking values in like this is almost never the right way to be doing things. In fact, often editing the code in the executable is slightly easier than trying to pin down values in memory like this. What are you really trying to achieve?

Edit: If you want to set a debug variable, two better options are:

  1. Put the global debug variable into the .so. Access it as normal (that is, the main app only has extern int foo;, the .so has the real int foo;)
  2. Do the reverse; put the global debug variable into the exe, use extern int foo; in the .so, and (important!) pass -Wl,-E to gcc or g++ to link the executable (this will allow the executable to export symbols in reverse).
  3. Have the executable call a function in the .so, passing the address of the variable. The .so can then store the address somewhere it can find it later. This option does not require the variable to be a global.

Don't use a debugger-derived address. It might be the wrong address, and even if it's the right address, it will change if you recompile anything. It might even change between two runs of the same binaries on the same system, thanks to ASLR. You simply cannot rely on this working.

bdonlan
The address isn't arbitrary, I found it to be the pointer into my structure.. But I had to "sweep" the memory manually with a debugger. I don't believe that value gets reset anywhere, but then again, I don't know the code so that could very well be the problem. There's nothing outside of the application pushing the old value in that address though, IE glibc enforcing some type of "protection" from changing stuff on the stack with a dlopen or something like that then? What I'm trying to do is flip a boolean that gets read to determine if internal debugging info for the app should be displayed.
Antonio Pires
I've added some more specific suggestions for your case.
bdonlan
+3  A: 

This is so wrong it makes my kidneys hurt.

Do not modify hard-coded values in memory. Don't dereference 0xf793db70040. You have no idea what that points to, and by far the likeliest outcome of modifying a hard-coded pointer like that will be a fiery crash. If you're lucky. If you're unlucky, you'll corrupt your program in a subtle way that causes a crash or data data loss some seconds, minutes, or hours later.

Figure out what value you want to change, and change that directly though a data pointer. Your last sentence is tending towards the right way: find the 'symbol' that this value corresponds to, and check that value.

The real question is: what are you trying to do, and why were you poking through the debugger to find the value you want to change?

JSBangs
It's not an arbitrary pointer, I know what struct that value maps into. I don't know how to read where that value is off the symbol table, i guess that's my second question. I have a struct that begins at that address, and I want to change the first byte to 1 during runtime. I was using the debugger because I do not know of a way to find where that variable is during runtime.. I know a function that has that parameter in the signature, so I got that value by peeking into the activation record of that function and writing the address down. Too bad it changes every time.
Antonio Pires
@Antonio, in that case you might want to try calling dlsym(). or simply declaring the variable extern and accessing it by name just like you would any other variable.
asveikau