I have a 64 bit reference to an object where the low order 32 bits of the reference are getting overwritten with 0xFFFFFFFF. I can't figure out how to set a data breakpoint on the bytes for the reference itself because the watch window gives me no way to acquire the address of the reference.
I see two solutions (if I correctly understood the problem):
change the reference to a pointer;
add a dummy variable in front of your reference - see the code below - and set the break-point to its address.
class object_t
{
public:
int i;
};
class test_t
{
public:
int64_t dummy {};
object_t& ro;
test_t( object_t& aro ) : ro { aro } {}
};
int main()
{
object_t obj;
test_t c { obj };
// without dummy
int64_t* p = (int64_t*)&c;
*(int32_t*)p = 0xffffffff; // simulates memory corruption
c.ro.i = 0; // exception
// with dummy
int64_t* p = (int64_t*)&c;
*(int32_t*)p = 0xffffffff; // will break
return 0;
}
I don't know any direct way to do this. But, here's a possible solution:
first, find where the variable is approximately: if you have a variable next to it, then get its address. If no variable nearby, then if the reference on the stack, then get the stack pointer (esp/rsp on x86). If the reference is in an object which is not on stack, then use the this pointer.
second, use the memory window, go to this approximate address, and search for the value of the reference, it will be somewhere nearby.
Related
I have a specific problem I'm trying to solve, I need to find the location (in memory) of a class's method. I think I've hit a syntax constraint because a pointer to a method is handled as a member pointer Example:
class Foo {
public:
int targetFunction(int value) { return value + 5; }
};
DWORD findLocation() { // ignore the fact that DWORD might not equal pointer size.
int (Foo::*address)(int) = &(Foo::targetFunction); // member function pointer
void* typeHide = (void*)&address; // Remove type
DWORD targetAddress = *(DWORD*)typeHide; // Convert type from void* to DWORD* and dereference to DWORD
return targetAddress;
}
int (Foo::*address)(int) = can also be written as auto address =
Now, in VS2008, it says Foo::targetFunction's address is "0x000F B890" but &Foo::targetFunction is "0x000F 1762"
First, the member pointer works correctly using the member pointer operators .* and ->*. If I cast targetAddress back to a member pointer, it still works!
Second, the location can be a thunk function!
Finally, if I use VS2008's debugger to change the value of targetFunction from the member pointer's address 1762 to the VS debugger reported value B890, my code works correctly!
Is there a C++ specific way of getting the address value (B890) instead of the member pointer value (1762)?
Upon request, here is code I'm trying to make work:
BYTE overwriteStorage[300][2];
void NOP(void)
{
// hackish, but works for now.
}
void disableOlderVersions(DWORD _address, int index)
{
//...
_address = findLocation();
DWORD protectionStorage = 0;
VirtualProtect((void *)_address, 1+4, PAGE_WRITECOPY, &protectionStorage); // windows.h: Make Read/Write the location in code
{
BYTE *edit = (BYTE*)_address;
overwriteStorage[index][0] = *(edit+0); // store previous value to revert if needed
*(edit+0) = 0XE9; // JUMP (32-bit)
overwriteStorage[index][1] = *(edit+1); // store second value
signed int correctOffset = (signed int)NOP - (signed int)_address - 5; // calculate 0xE9 relative jump
*(signed int*)(edit+1) = correctOffset; // set jump target
}
VirtualProtect((void *)_address, 1+4, PAGE_EXECUTE, &protectionStorage);
}
if I replace the first line of findLocation from a member pointer to an actual function pointer it works perfectly. However, I need to read&write to several class methods as well, this method is broken by the odd member pointers.
Also, I've had some local functions not report the correct address either (recently). Is there possibly another way to find function addresses without being constrained by the compiler behaviors?
It sounds like you're trying to compress a member-function call into a single function pointer. It's not possible.
Remember:
Object x;
x.a(1);
is actually short for
a(&x /*this*/, 1 /*arg1, ... */); //approximation, leprechauns may be involved in actual implementations.
That first argument is crucial, it's going to become "this".
So you can't do something like this:
class Object {
public:
void f(int);
}
typedef void (*FNPTR)(int);
Object a;
void (Object::* memberFuncPtr)(int);
void* nerfedPtr = (void*)memberFuncPtrl
FNPTR funcPtr = static_cast<FNPTR>(nerfedPtr);
funcPtr(1);
Because you've robbed the member function of it's object context.
There is no way to call an object member function without having both the address of the function and the address of the instance.
Alright, so I have looked around online and clearly my problem is that I'm using a variable "val" here that stops existing when the function closes. Unfortunately, I haven't really found any actual solutions to my problem here. I'm sure this is an easy enough problem to solve once you know how, but I just don't have the knowledge.
In this code, just notice I'm trying to return an unsigned int val. I can't do that because the code wants a reference, not just a variable. I can't simply return val but I don't know what to do.
http://i.imgur.com/E8sf2aS.png
Thanks for the help.
Edit: sorry, I had some problems with the image, apparently I need to work on my rep.
I'm going to take a wild guess.
Foo& doStuff()
{
// blah blah
Foo val;
// ...
return val;
// val is no longer valid end of scope. Returning invalid reference.
}
Either pass in the result Foo instance to doStuff, or create a new Foo on the heap and return as pointer.
So,
void doStuff(Foo& val)
{
// blah blah
// ...
val = x;
}
or
Foo* doStuff()
{
// blah blah
Foo* val = new Foo; // dont forget to delete
// ...
return val;
}
Of course, you can return by value:
Foo doStuff()
{
// blah blah
Foo val;
// ...
return val;
}
Depending on how heavy a Foo is. Of course, since in this case a Foo is just an small int, you should simply return by value. For some cases of return by value for large/non-trivial types, a temporary copy is created (In those instances where there is no copy elision via RVO or NRVO); in these cases you might want to avoid returning large object types by value.
This code has a lot of problems, apart from being given in an image (!!!)
I guess you're trying to find the element at position pos-1 in a list, or something. The main problem referring to your question seems to be that you're first assigning val by value, then you have no reference to return. You should return n2->value directly, which should be a reference to unsigned int, like that:
const unsigned int &list::operator[](unsigned int pos) const
{
node *n1 = ???, *n2 = ???;
for (unsigned int k = 0; k < _size; k++)
{
if (k == pos)
return n2->value;
n1 = n2->next;
n2 = n1;
}
return ???;
}
Other problems remain, e.g.
why you need two node* and not just one (looking for position pos-1 directly)
how to initialize n1, n2 (somehow pointing to the head of your list; obviously new node() should not work)
what to return if input argument pos is out of range (possibly return a reference to some static variable that you can detect, or throw an exception)
For these problems, more context would be needed from your side.
Reference variables, are only valid if the object to which "refer" to, exists in memory. Passing around references to an out of scope variable, is considered undefined behavior.
This is the mistake in your code.Please correct it.
const unsigned int& list::operator[] (unsigned int pos)const
{
const unsigned int val = 0;
return val; //this is a local variable, whose scope ends here, a reference to this should not be returned
}
This is the compiler's warning, to your code.
warning: reference to local variable ‘val’ returned [enabled by default]
Please listen to compiler warnings (especially c/c++ !!), in your case simply using pass by value, would have been sufficient.
Edit:
In case the return variable, is enforced to be a reference type, and cannot be avoided, you can then extend the life of you local variable, to throughout the existence of the program by making it static.
const unsigned int& list::operator[] (unsigned int pos)const
{
static const unsigned int val = 0;
return val;
}
Th variable val is now a static local variable, whose life is throughout the program,
so pasing around references to this variable should be OK, but not recommended programming,
since a pass by value will suffice for the needs of your application.
I have the following structure, class and function snippet:
structure:
struct myData
{
short index;
char name[32];
}
class:
class myFoo
{
...
public:
short count;
myData** data;
...
}
function:
int Do_Bar(myFoo vFoo)
{
...
myData* data = *vFoo.data;
for (short i=0; i<vFoo.count; ++i)
{
Printf("%3d %s", data.index, data.name);
}
...
}
function call:
...
myFoo foo;
SomeAPI_GetCompleteObjectList(&foo);
Do_Bar(foo);
...
But my code crashes with these code. But if I removed the parameter and create a myFoo class in Do_Bar() function instead, the code works fine:
int Do_Bar(myFoo vFoo)
{
myFoo foo;
SomeAPI_GetCompleteObjectList(&foo);
...
myData* data = *vFoo.data;
for (short i=0; i<vFoo.count; ++i)
{
Printf("%3d %s", data.index, data.name);
}
...
}
Why is it? And how to resolve this?
EDIT1:
I forgot to mention that the initializations of foo is done before the function call. This was initialized using an API.
I modified the code for this.
You have not given memory to pointer data in line myData* data and trying to assign something to it.Alternative method are either
define myData data then use &data as pointer
or allocate memory using dynamic memory allocation.
You have a couple of undefined behaviors in that little piece of code...
You have a double-pointer, but never "point" either of them to anything. This mean they will point to random memory locations.
You print an uninitialized character array, which means it contains random data.
And since you don't do any initialization at all, foo.count will also contain a random value, which may be negative or very large.
And last bot not least, like I said in my comment, that code should not even compile as you use the wrong syntax for the access of the members in the structure.
I am getting access violation error in the below code..i have pointed it out in the program.
void *pBuff = 0;
void set_data(void *pBuff)
{
int value = 70, i;
int *phy_bn = new int[8];
for(i=0; i<8; i++)phy_bn[i] = value;
pBuff =phy_bn;
cout<<((int*)pBuff)[0];//..accessing 0th element value..no error here..gives 70 as result..
}
int main()
{
set_data(pBuff);
cout<<((int*)pBuff)[0];//acces violation error
return 0;
}
Why that access violation even when i am not assigning it the address of a local variable...
Yes i can use vector or pass by reference.
But i want to know why pBuff is not getting assigned
Because it is a copy of the pointer being modified within set_data(). Pass the pointer by reference so the change is visible to the caller:
void set_data(void*& pBuff)
Note that the function variable pBuff hides the global variable pBuff in the function set_data().
That said, I am unsure of the reason for void* and why vector<int> is not being used which handles all dynamic memory allocation for you.
When you say
pBuff = phy_bn;
You're just changing the local value of pBuff, not the global value of pBuff. Either pass pBuff as a double pointer, or simply remove the argument to the function, as pBuff is global already.
void *pBuff = 0; /* This is the global pBuff, which isn't being changed */
void set_data(void *pBuff /* This is the local pBuff, which is being changed */)
{
...
pBuff = phy_bn;
...
}
'plz i want to avoid double pointers..its not required i guess...'
Guessed wrong, it is required! You'll need a pointer reference for the pBuff parameter then:
void set_data(void*& pBuff)
{
// ...
}
This is effectively the same as using a double pointer.
The only thing you're doing with
pBuff =phy_bn;
is manipulating the function parameter representation on the local stack.
The pBuff inside set_data is not the global pBuff. The value of the global pBuff never gets changed from 0. Since this is C++ code, set_data can take its pointer argument by reference, and assigning to it will change the value at the point of the function call.
In C++, pointers are passed by value, the same as other value types. It may be instructional to think of a pointer as literally an integer type; then it’s easy to see why pBuff = phy_bn; doesn’t accomplish anything, for the same reason that this code doesn’t:
#include <iostream>
void set(int x) {
x = 5;
}
int main(int argc, char** argv) {
int y = 0;
set(y);
std::cout << y << '\n';
return 0;
}
Here, x is a local variable. It is a copy of y, not y itself. You can change its value by assigning to it, sure, but you’re merely changing the value of a variable which will not exist outside the scope of set(). If you change the definition of set() to use a reference:
void set(int& x) {
x = 5;
}
Then y will indeed be updated, because you have explicitly requested that x be an alias for the name you pass to set(), instead of a copy. You were misled by the names: the pBuf in set_data() is not the same variable pBuf in main(), even though they happen to have the same value; they’re like two different people with the same name and the same amount of money.
I have a thread-class Buffer (own made class), and many derived classes such as BufferTypeA, BufferTypeB...
Since I have to synchronize them in a certain order, I'm giving any of them an integer which represents the order to run certain task. I also have to know inside each thread Buffer which one is next to run the task, so I'm passing every BufferType a reference to an integer which all of them must share and I didn't want to make it Global.
I got lost at any point and I don't see where.
First I create all the BufferTypes from a class where I also define that shared integer as:
int currentThreadOrder;
And when creating the BufferTypes:
int position = 0;
if (NULL == bufferA) {
bufferA = new BufferTypeA(¤tThreadOrder, ++position,
waitCondition);
}
if (NULL == bufferB) {
bufferB = new BufferPos(¤tThreadOrder, ++position,
waitCondition);
}
if (NULL == bufferC) {
bufferC = new BufferRtk(¤tThreadOrder, ++position,
waitCondition);
}
Then, in BufferTypeA header:
class BufferTypeA: public Buffer {
public:
BufferTypeA(int currentThreadOrder,
int threadConnectionOrder = 0,
QWaitCondition *waitCondition = NULL);
//..
}
And in cpp file:
BufferTypeA::BufferTypeA(int currentThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition):
Buffer(currentThreadOrder, threadConnectionOrder, waitCondition) { }
Now I'll show Buffer header:
class Buffer: public QThread {
public:
Buffer(int ¤tThreadOrder,
int threadConnectionOrder = 0,
QWaitCondition *waitCondition = NULL);
//...
protected:
QWaitCondition *waitCondition;
int threadConnectionOrder;
int ¤tThreadOrder; // Shared address
}
And finally the cpp:
Buffer::Buffer(int ¤tThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition) {
this->threadConnectionOrder = threadConnectionOrder;
this->waitCondition = waitCondition;
this->currentThreadOrder = currentThreadOrder;
}
And the error I'm getting is error: uninitialized reference member Buffer::currentThreadOrder.
I'm embarrased to ask, because it's going to be a simple problem with pointers and addresses, but I can't see where the problem is, so please help.
When you create a class with a data-member that is a reference, the reference needs to be assigned a value in the constructor initializer list.
References have to be given a value when they are created, they are not pointers. They have to start with a value and that value cannot be changed (while the contents that is pointed to by that value can be changed).
Essentially you can think of a reference as an alias for an existing variable. You can't give a friend a nickname if you don't have a friend :)
RESPONSE TO COMMENT:
You don't "share a reference" between objects. Each object will have its own reference to the same variable. When you "pass by reference" you are telling the compiler that you want the variable in your function to actually be the variable in your outer scope, rather than creating a new variable by value. This means that you only have one variable at one memory location. The reference is just memory in some other place that forwards you to that same memory location.
Think of this as call forwarding... I can have 15 phone numbers in 15 different countries. I can set them all up to forward calls to my cell in the US. So, people are calling me no matter which number they call.
Each of your classes just has another reference to forward the "phone calls" or variable reads/writes to that same memory location. So, you're not sharing a reference between classes, you're making sure that each class HAS a reference to the same underlying memory location.
Back to the metaphore, each class won't have the same phone, but each class' phone will forward to the same number (variable) none-the-less which lets them all set/get the same value in the end.
RESPONSE II:
Here's a simple example to get your head going, it's pretty easy to apply to your classes. I didn't compile it but it should work minus a typo or two possibly.
class A
{
public:
A(int& shared) : m_shared(shared)
{
//No actions needed, initializer list initializes
//reference above. We'll just increment the variable
//so you can see it's shared in main.
m_shared += 7;
}
void DoSomethingWithIt()
{
//Will always reflect value in main no matter which object
//we are talking about.
std::cout << m_shared << std::endl;
}
private:
//Reference variable, must be initialized in
//initializer list of constructor or you'll get the same
//compiler error again.
int& m_shared;
};
int main()
{
int my_shared_integer = 0;
//Create two A instances that share my_shared_integer.
//Both A's will initialize their internal reference to
//my_shared_integer as they will take it into their
//constructors "by reference" (see & in constructor
//signature) and save it in their initializer list.
A myFirstA(my_shared_integer);
A mySecondA(my_shared_integer);
//Prints 14 as both A's incremented it by 7 in constructors.
std::cout << my_shared_integer << std::endl;
}
you pass a pointer int* as 1st argument to BufferTypeA, which expects and int, while you said in your question you meant to use a int&. To do this, the ctor of BufferTypeA should take a int& and initialise it in an initialisation list (i.e. not within the { } part of the ctor) like
class BufferType {
int &Ref;
public:
BufferTypeA(int& ref) : Ref(ref) { /* ... */ }
};
and in your construction of BufferA you must not pass an address, but the reference, i.e.
int counter;
Buffer = new BufferType(counter);
You want code like this:
Buffer::Buffer(
int ¤tThreadOrder0,
const int threadConnectionOrder0,
QWaitCondition *const waitCondition0
) :
threadConnectionOrder(threadConnectionOrder0),
waitCondition(waitCondition0),
currentThreadOrder(currentThreadOrder0)
{}
The reason is related to the reason you cannot write
const double pi;
pi = 3.14;
but can write
const double pi = 3.14;
A reference is typically implemented as a constant pointer, to which one cannot assign an address after one has initialized the pointer. Your version of the code assigns, as in the first pi example. My version of the code initializes, as in the second pi example.