Can gdb print 64-bit address? - gdb

I entered the following command in gdb:
(gdb) p PyObject_GetAttrString($2, "_other_obj_m")
and got the following output which should be a variable address type (PyObject*).
$4 = -246881136
Then I used printf to convert it to hex format and got a wrong address "0xf148e490", the real address is "0x4f78f148e490".
Any one know how to solve this problem?

If your target program doesn't have any debugging info for a function, gdb will assume that the function has return type int. On x86_64 Linux, that's likely to be 4 bytes.
$ gdb -q python2.7
(gdb) ptype PyObject_GetAttrString
type = int ()
(gdb) p sizeof(int)
$1 = 4
If your target has debugging info, you'll get the correct result.
$ gdb -q python2.7-dbg
Reading symbols from python2.7-dbg...done.
(gdb) ptype PyObject_GetAttrString
type = struct _object {
struct _object *_ob_next;
struct _object *_ob_prev;
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} *(PyObject *, const char *)
If you don't have any debugging info, you can cast the function symbol to the correct type signature, or to one that's close enough, such as pointer to function returning void *. Try this:
(gdb) p ((void * (*)(void *, char *))PyObject_GetAttrString)($2, "_other_obj_m")

Related

address returned is not what's stored in the value

I'm trying to debug a small C++ program using gdb, but may be getting hung up on some pointer arithmetic:
A* get(int) returns a pointer to an instance of a class A I've defined. Internally, get(int) references an array of A, returning:
class A_list {
private:
A* A_array;
int count;
public:
A_list(int c): count(c) { A = new A[c]; }
void insertAt(A a, int idx) {
A_array[idx] = a;
}
A* get(int);
};
A* A_list::get(int idx) {
...
A* result = A_array + idx;
return result;
}
presumably, when dealing with an array of A, I can simply add the index (times the size of a single A) to get the address of the idx'th.
This seems to work as expected. However, when calling get(int) from within another member function of A_list, I watch the value assignment in gdb and see two different values:
void A_list::foo() {
A* a = nullptr; // I declare my pointer, and initialize to 0x0
...
a = get(0); // I store the address of `A_array[0]`
The gdb watchpoint outputs:
Old value = (Number *) 0x0
New value = (Number *) 0x55555556b2c0
However, when I print the address stored in a, I get a completely different value, with an unrecognized message attached.
(gdb) p a
(Number *) 0x7ffff7b4e5c0 <_IO_file_overflow+256>
attempting to dereference any of the member values gives unexpected results
I can't find <_IO_file_overflow+256> defined anywhere in the gdb sources. What does it mean?
Why might the value stored in a appear to be different from the value returned when get() is called from inside a member function of A_list? From outside (eg - in main()) I get the expected value.
Edit 9-08:
Changed assignment in get() based on feedback. Still getting the same arbitrary address when I return from the get() function.
When doing pointer arithmetic, it's done in elements and not in units of bytes.
Therefore the multiplication with sizeof(A) is invalid and wrong: The expression A_array + (idx * sizeof(A)) should be plain A_array + idx.
Or you could be explicit and return &A_array[idx].
All this means that for any pointer or array a and (valid) index i, the expression *(a + i) is exactly the same as a[i]. And from that follows that &a[i] will be exactly the same as a + i.
To answer your last question -- <_IO_file_overflow+256> is telling you gdb's best guess as to what that address (0x7ffff7b4e5c0) refers to -- in this case, the address is pointing into some shared libaray, and the symbol _IO_file_overflow is the closest symbol defined in that library (and specifically, this address is 256 bytes past that symbol). This looks to be part of libc.
You can get more detail about what addresses correspond to what in your program by examining the file /proc/<pid>/maps -- you just need to know the pid of the process you are debugging and you can look at that file in another window.
As to why you're getting this odd value when it looks like you've just assigned a different value, it may be that gdb is getting confused and you have another a defined somewhere and gdb is printing that. Or you may have incomplete/incorrect debugging info in your program -- make sure that you compile with -O0 -g if you want accurate debug info.

what does (void(*)() sc) () mean?

unsigned char sc[] =
(some long binary string)
int main()
{
((void(*)())sc)();
return 0;
}
what does what does (void(*)() sc) () mean in here?
I saw " *void(*)() means a void function that takes no argument" in StackoverFlow.
`
I have three question
First,
As this comment above, I think above code has to "*" ahead of void(*).
However, without pointer "*" , it is working well.
Second, "void(*)() sc is wrapped by ()(), such like (void(*)() sc)().
there is twice use of "()"
Third, why is it working?? Common,When we call a function, we usually write only name of function, such as funtion1(a , b);
"(void(*)() sc )()" is just initialize!!
So i think sc is not used yet. However it is working well.
This is a trick to execute any shellcode inside your main.
Let's analyze it together shall we ? (The function declaration, not your shellcode):
(void(*)() sc ) ();
First lets talk about sc. sc is a byte array being assigned a shellcode, meaning that anything can happen (hence why it was rightfully edited).
Then it is converted into a function, a function ptr to be exact:
void(*)() sc
With void(*)() you simply cast your shellcode as a function pointer, meaning that if we call this function ptr, taking no argument as you noticed, it will point to the first byte of your unsigned char array. The compiler will interpret your char array as raw bytes to be converted into machine code.
NB: an unsigned char is a byte.
Finally the trailing (); ask the function, wrapped by parenthesis, to be executed, as soon as you start your program.
In short it is a convenient way to tell eip, the register that hold the address of program's next execution, to point at your byte array and easily test different shellcodes.
Note that, as mentioned by dxiv, this will not work in environment that prevent code execution from data area as your function ptr points to a data segment.
If you want to make it work you will need to compile with the following flags in order to enable exacstack -z execstack, and potentially -fno-stack-protector as well as -m32 if it is a shellcode for 32 bits:
gcc -m32 -fno-stack-protector -z execstack shellcode.c && ./a.out
Example to read /etc/passwd (linux):
unsigned char sc[] =
"\x31\xc9"
"\xf7"
"\xe1\xb0"
"\x05"
"\x51\x68"
"\x73\x73\x77"
"\x64"
"\x68"
"\x63"
"\x2f\x70\x61"
"\x68" "\x2f"
"\x2f\x65\x74"
"\x89" "\xe3"
"\xcd\x80\x93"
"\x91"
"\xb0"
"\x03\x31\xd2"
"\x66" "\xba"
"\xff\x0f\x42"
"\xcd""\x80"
"\x92" "\x31"
"\xc0\xb0\x04"
"\xb3" "\x01"
"\xcd" "\x80"
"\x93\xcd\x80";
int main()
{
((void(*)())sc)();
return 0;
}
Another example to open a shell:
#include <unistd.h>
unsigned char sc[] =
"\x31\xc0\x50\x68\x2f\x2f"
"\x73\x68\x68\x2f\x62\x69"
"\x6e\x89\xe3\x50\x53\x89"
"\xe1\xb0\x0b\xcd\x80";
int main()
{
((void(*)())sc)();
return 0;
}

gdb "Attempt to take address of value not located in memory." when calling functions, even const

I get errors even though there is no modification on the objects, very simple expression, calling a method:
(gdb) p my_unordered_map.count(edge.target_node_id)
$6 = 1
(gdb) p my_unordered_map[edge.target_node_id]
Attempt to take address of value not located in memory.
also I have the same error while calling a const function:
class A {
Sub s;
X get_x () const {
return s.x;
}
};
(gdb) p a.get_x()
Attempt to take address of value not located in memory.
(gdb) p a.s.x
--works
I don't understand. So far, when evaluating an expression, I can rely on it not working.
The code is in a lambda. A is an argument, my_unordered_map is captured by reference.
(gdb 8.3)

Debugging C++ code

While running some code through gdb , I cam across this structure definition :
ptype spawnStmt
type = struct stmt {
stmt *next;
const char *stmtname;
int lineNo;
const char *filename;
stmtType type;
stmt::<anonymous union> s;
} *(var *, stmtlist *)
(gdb) p spawnStmt
$3 = {stmt *(var *, stmtlist *)} 0x80514f8 <spawnStmt>
Can someone please explain to me what this means - {stmt *(var *, stmtlist *)} 0x80514f8 .
My intention is to print the values of the elements in this structure.
What would be the correct syntax for that ?
Thanks
Can someone please explain to me what this means
spawnStmt is a function at address 0x80514f8, taking var* and stmtlist* as parameters, and returning struct stmt.
My intention is to print the values of the elements in this structure.
There is no "this structure" yet. You have to set a break point on spawnStmt(), finish from it, and only then can you print values of the elements (finish will actually print them for you).

Cannot call function with reference parameter in gdb

For this function:
void foo_ref(const int& i)
{
cout << i << endl;
}
It's failed when I call it in gdb:
(gdb) call foo_ref(5)
Attempt to take address of value not located in memory.
Of course, in this simple example there's no need to use reference as parameter. If I use a normal "int", no problem then.
Actually the real example is a template function, like this:
template<class T>
void t_foo_ref(const T& i)
{
cout << i << endl;
}
When "T" is "int", I have the problem mentioned above.
Is it a bug in gdb? Or is it possible I could call such function in gdb?
It is possible, though not in an intuitive fashion (I would still classify this as a bug).
You need an actual memory region (a variable, or something heap-allocated).
(gdb) p (int *) malloc(sizeof(int))
$8 = (int *) 0x804b018
(gdb) p * (int *) 0x804b018 = 17
$9 = 17
(gdb) p t_foo_ref<int>((const int&) * (const int *) 0x804b018 )
17
$10 = void
(gdb)
5 is a literal and when you pass it to the function the compiler tries to store it in the address allocated for the function parameter i. But since i is a reference there is no where 5 can be stored in memory thus your error.