Разыменование двойного указателя (указателя на указатель на значение) в GDB

#c #pointers #gdb

Вопрос:

Я пишу сценарий для обратного проектирования исполняемого файла. У меня есть ситуация, когда RAX-это указатель на значение, которое само по себе является указателем на объект. Самое первое значение этого объекта, в свою очередь, является указателем на строку. Визуализация должна прояснить это:

 RAX
 |
 | points to
 |
 V
Value on the stack
 |
 | points to
 |
 V
The start of an object (std::vector<std::string)
 |
 | the very first value of that object points to
 |
 V
A string in memory
 

Я хочу получить доступ к строке в памяти. Как мне это сделать с помощью одной команды?

Ответ №1:

Вот как я это сделал:

 # Dereference RAX to get the value on the stack
(gdb) x/gx $rax         
0x7fffffffe0d0: 0x0000555555598700  

# Dereference the value on the stack to get the start of the object                        
(gdb) x/gx *((uint64_t*)$rax)            
0x555555598700: 0x0000555555578ea0    

# Dereference the start of the object because it points to a string
(gdb) x/s *((uint64_t*)*((uint64_t*)$rax))
0x555555578ea0: "/root/.ssh/id_rsa"       
 

Мне пришлось привести значения в uint64_t , потому что в противном случае GDB будет думать, что это 32-разрядное значение (я работаю с 64-разрядным исполняемым файлом).

Кроме того, был еще один указатель на строку в 4 байта после начала векторного объекта. Вот как я получил доступ к этой строке:

 x/s *((uint64_t*)*((uint64_t*)$rax)   4)