0

Assuming addr is address of a local variable on stack, are the following correct ways for retrieving the values of variables (ChildPid is tracee's id)?

double data = (double) ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);

float data = (float) ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);

Thanks.

curveball
  • 4,320
  • 15
  • 39
  • 49

2 Answers2

2

The documentation says that PTRACE_PEEKDATA returns a word. It also says

The size of a "word" is determined by the operating-system variant (e.g., for 32-bit Linux it is 32 bits).

So you can't reliably use a single ptrace() call to get at a double on a 32-bit system, just half of it. The other half's address probably depends on if the stack grows up or down. On a 64 bit system you'd have to figure out which half of the returned word has the float.

So... it's all very system dependent on what you have to do.

Shawn
  • 47,241
  • 3
  • 26
  • 60
  • It is 64-bit, and the following print 8: cout << sizeof(ptrace(PTRACE_PEEKDATA, pid, addr, 0)) << endl; So, if 8 bytes are returned, why does it return wrong value. I actually poked a double at addr and peek it right back, and got wrong answer. – Sohrab Honargohar Aug 25 '18 at 06:50
  • @SohrabHonargohar Are you just casting from the long returned by ptrace to a double like in your post? That's obviously not going to give you anything useful. – Shawn Aug 25 '18 at 07:54
0

Casting long to double won't get you the desired result. Casting numbers converts the numeric value, it doesn't copy bits. What you need is something like:

long pt = ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);
double result;
assert (sizeof(pt) == sizeof(result), "Oops, wrong word size!");
memcpy (&result, &pt, sizeof(result));

To get a float, you need to know which half of the word it occupies (normally you shouldn't use addr which is not aligned to a word boundary). Thus you need something like the following:

long pt = ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);
float result;
assert (sizeof(pt) == 2*sizeof(result), "Oops, wrong word size!");
// either this (for the lower half of the word)
memcpy (&result, &pt, sizeof(result));
// or this (for the upper half of the word)
memcpy (&result, ((char*)&pt)+sizeof(result), sizeof(result));
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243