Get the value of a variable using the hexadecimal memory address - c++

I just want to get the value using the hex address:
#include<stdio.h>
int main()
{
int *hold, value=10;
hold = &value;
printf("%p",hold);
}
It gives me the address 0x7fffd7c24334. I just want to know that if there is a way in C or C++ so that I can get directly the value of "value" using hex number 0x7fffd7c24334 for the time being. I suppose the address of the variable hold is the same for sometime so that 0x7fffd7c24334 still point to value, but I am not sure.

Assuming that this address is consistent upon every execution of your program, you can use this:
int value2 = *(int*)0x7fffd7c24334;
But please note that this assumption is generally wrong!
The address of a local variable in a function depends on the state of the stack (the value of the SP register) at the point in execution when the function is called.
It might possibly work in main, since this function is called only once, and the SP register should have the same value upon every execution of your program. But even if it does work, that address will change as soon as you add variables before value. To put it in simple words, don't use this method.

printf("%d",*hold);
De-reference and use %d.
You cannot rely on the hex address.
See here: http://ideone.com/RdY4Ni

I think you can use this:
printf("%x", hold);

Related

Passing &variable to an function

I have question about line #2 and #9 of this code.
I have ran this code on codeblocks and it turns out that trip(&y) runs and make y=21 at the end of line 9. This is not what I expected.
I thought &y would return the address (like hexadecimal number) and pass it to trip. Then trip will triple the weird (hexadecimal) number of the address and perhaps change the address of int y, or produce error.
Which part of my logic has fault?
My logics are:
&y returns the address of the variable (hexadecimal).
trip (int* x) takes in the number (address in this case) and triples it.
Therefore, nothing has been done to the actual value of y, which is 7.
Edit: The answer is 105.
You are right about the address of y that is given to the function trip(int*).
Your mistake is that the function trip(int*) dereferences the address to access the value it points to.
Assume y has the value 7 and is stored at address 0x0014 (simplified for your convenience).
The function trip(int*) gets the address 0x0014 and uses it to get to the value 7 of y.
Now it triples this value and stores the result where the address is pointing to. Thus overwriting the value 7 of y with the new value of 21.
This dereferencing of the address is done by the star (*) right in front of the x in the body of the function trip(int*).
To clarify. Addresses aren't necessarily a hexadecimal value. Hexadecimal is just a way to display a number. Addresses are just the number to a certain place in memory. In this case 0x0014 is the same as 20 in decimal. Meaning y is stored at address 20 (as decimal).
Please keep in mind that pointers are rarely the right way to do something. Like in this case with the function quin(int&). The problem that is solved with a pointer in trip(int*), is solved much cleaner in quin(int&). References are cleaner and safer.
The function trip(int*) does not check for the case that the address given is invalid (the address given is NULL/nullptr). quin(int&) doesn't even have to check for this since references cannot be NULL in C++.
If you have to use pointers, consider using smart pointers like std::unique_ptr<T> and std::shared_ptr<T>.

Accessing memory mapped register

Assume there is a memory mapped device at address 0x1ffff670. The device register has only 8-bits. I need to get the value in that register and increment by one and write back.
Following is my approach to do that,
In the memory I think this is how the scenario looks like.
void increment_reg(){
int c;//to save the address read from memory
char *control_register_ptr= (char*) 0x1ffff670;//memory mapped address. using char because it is 8 bits
c=(int) *control_register_ptr;// reading the register and save that to c as an integer
c++;//increment by one
*control_register_ptr=c;//write the new bit pattern to the control register
}
Is this approach correct? Many thanks.
Your approach is almost correct. The only missing part - as pointed out in the comments on the question - is adding a volatile to the pointer type like so:
volatile unsigned char * control_register_ptr = ...
I would also make it unsigned char, since that is usually a better fit, but that's basically not that much different (the only meaningful difference would be when shifting the value down.)
The volatile keyword signals to the compiler the fact that the value at that address might change from outside the program (i.e. by code that the compiler doesn't see and know about.) This will make the compiler more conservative in optimizing loads and stores away, for example.

How to change returned value of function

There is a function in this program, that currently returns a 1. I would prefer for it to return a 0.
uregs[R_PC] is the program counter.
arg0 is the program counter offset from where we left the function (assembly, "ret").
From this I deduce: we can add the offset to the program counter, uregs[R_PC]+arg0, to find the address of the return value.
I have allocated a 32-bit "0", and I try to write 2 bytes of it into the address where the return value lives (our function expects to return a BOOL16, so we only need 2 bytes of 0):
sudo dtrace -p "$(getpid)" -w -n '
int *zero;
BEGIN { zero=alloca(4); *zero=0; }
pid$target::TextOutA:return {
copyout(zero, uregs[R_PC]+arg0, 2);
}'
Of course I get:
dtrace: error on enabled probe ID 2 (ID 320426: pid60498:gdi32.dll.so:TextOutA:return): invalid address (0x41f21c) in action #1 at DIF offset 60
uregs[R_PC] is presumably a userspace address. Probably copyout() wants a kernel address.
How do I translate the userspace address uregs[R_PC] to kernel-space? I know that with copyin() we can read data stored at user-space address, into kernel-space. But that doesn't give us the kernel address of that memory.
Alternatively: is there some other way to change the return value using DTrace?
DTrace is not the right tool for this. You should instead use a debugger like dbx, mdb or gdb.
In the meantime, I'll try to clarify some of the concepts that you've mentioned.
To begin, you may well see in the source code for a simple function that there is a single return. It is quite possible that the compiled result, i.e. the function's machine-specific implementation, also contains only a single point of exit. Typically, however, the implementation is likely to contain more than one exit point and it may be useful for a developer to know from which specific one a function returned. It is this information, described as an offset from the start of the function, that is given by a return probe's arg0. Your D script, then, is attempting to update part of the program or library itself; although the addition of arg0 makes the destination address somewhat random, the result is most likely still within the text section, which is read-only.
Secondly, in the common case, a function's implementation returns a value by storing it in a specific register; e.g. %rax on amd64. Thus overriding a return value would neccessitate overriding a register value. This is impossible because DTrace's access to the user-land registers is read-only.
It is possible that a function is implemented in such a way that, as it returns, it recovers the return value from a specific memory location before writing it into the appropriate register. If this were the case then one could, indeed, modify the value in memory (given its location) just before it is accessed. However, this is going to work for only a subset of cases: the return value might equally be contained in another register or else simply expressed as a constant in the program text itself. In any case, it would be far more trouble than it's worth given the existence of more appropriate debugging tools.

c++ strings and pointers confusion

string * sptemp = (string *) 0x000353E0;
What does this code exactly want to say ?
I know that in the left side we define a string pointer but I couldn't understand the right part.
It means take a numeric value, convert it to a pointer with that value as the address it points to, and then use that value to initialise the variable sptemp.
If the memory at that address contains a valid string object, then you can use the pointer to access it. If not, trying to do so will give undefined behaviour.
string * sptemp = (string *) 0x000353E0;
What does this code exactly want to say ?
It says, treat the data located at address 0x000353E0 as though it holds a string and assign the address to the variable sptemp. The data can be accessed through the pointer variable sptemp after that.
These comments are mostly right, but not completely. We don't actually know that string is std::string here. It could be that string is a bit of memory-mapped hardware whose address on the OP's embedded SBC is defined by the hardware 0x000353E0. In that case, this is completely sensible, and what people do all the time. The pointer "string *sptemp" is set to point to the hardware interface.
But it's probably nonsense.

LLVM: Replacing all instances of an address with a constant

I'm trying to replace all instances of an address with a constant.
I'm getting & testing the address of store with the following (i is an instruction)
//already know it's a store instruction at this point
llvm::Value *addy = i->getOperand(0);
if(llvm::ConstantInt* c = dyn_cast<llvm:::ConstantInt>(addy)){
//replace all uses of the address with the constant
//operand(1) will be the address the const would be stored at
i->getOperand(1)->replaceAllUsesWith(c);
}
I'd think this would work, but I'm getting the error that
"Assertion: New->getType()== getType() && replaceAllUses of value with new value of different type!" failed
and I'm not sure why...my understanding of replaceAllUses is that it would replace usage of address (i->getOperand(1) with the constant?
The error message is pretty straightforward: the type of the new value is not identical to the type of the old value that you are replacing.
LLVM IR is strongly typed, and as you can see in the language reference, every instruction has a specific type it expects as each operand. For example, store requires that the address's type will always be a pointer to the type of the value being stored.
As a result, whenever you replace the usage of a value, you must ensure first that they both have the same type - replaceAllUsesWith actually has an assert to verify it, as you can see, and you failed it. It's also simple to see why: operand 1 of a store instruction is always of some pointer type, and a ConstantInt always represents something of some integer type, so surely they can never match.
What exactly are you trying to achieve? Perhaps you are thinking about replacing each load of that store's address with a usage of the constant? In that case, you'll have to find yourself all the loads that use that address, and for each of them (for each of the loads, I mean, not of the addresses) perform replaceAllUsesWith with the constant. There are standard LLVM passes that can do those things for you, by the way - check out the pass list. I'm guessing mem2reg followed by some constant propagation pass will take care of this.