2017-02-11 3 views
3

Я пытаюсь проделать свою собственную виртуальную виртуальную машину Capture-the-Flag и застревать при попытке использовать gdb для изменения значения, переданного в стеке (последний элемент, который должен быть толкнул):GDB: изменить строку в памяти в стеке

system("date"); 

Для

system("ash"); 

до сих пор мои усилия GDB был следующим:

стек

Адрес Я заинтересован в последний элемент в стеке (первым в списке стека ниже)

(gdb) p $esp 
$1 = (void *) 0xbf902690 

(gdb) x/32w 0xbf902690 
0xbf902690: 0x080485ff 0x0000044c 0xb7783ff4 0xbf9026b8 
0xbf9026a0: 0xb76a8fa9 0xb7797356 0x08048529 0x0000044c 
0xbf9026b0: 0x08048520 0x08048410 0xbf902728 0xb7695cf7 
0xbf9026c0: 0x00000001 0xbf902754 0xbf90275c 0xbf9026e4 
.... 
(gdb) x/s 0x080485ff 
0x80485ff: "date" 
(gdb) x/s *0x080485ff 
0x65746164: <Address 0x65746164 out of bounds> 
(gdb) 

Попытка изменить память 1

(gdb) set {const char [4] *}0x080485ff = "ash " 
(gdb) x/s 0x080485ff 
0x80485ff: "\b`\354\b" 
(gdb) 

Как вы можете видеть , Я калечу указатель.

Попытка изменить память 2

(gdb) set *((const char *)0x080485ff) = "ash " 
(gdb) x/s 0x080485ff 
0x80485ff: "\bate" 
(gdb) 

Больше коверкая - что-то делать с неправильно разыменования?

Попытка изменить память 3

(gdb) set {int}0x080485ff = 68736100 
(gdb) x/s 0x080485ff 
0x80485ff: "d\324\030\004" 
(gdb) 

Попытка использовать значения ASCII вместо этого - не работает так, как планировалось.

Любая оцененная помощь - был чесать (лысый) голову на некоторое время теперь ...

Спасибо

SC.

ответ

3

set *((const char *)0x080485ff) = "ash "

Это неверно: тип объекта по адресу 0x080485ff является char[5], не char*. В то время как первые могут быть применены к последним, они не являются одинаковыми.

set {const char [4] *}0x080485ff = "ash "

Это неверно по той же причине: нет указателя по адресу 0x080485ff.

set {int}0x080485ff = 68736100

Это один не имеет смысла, так как 68736100 является 0x418d464 в шестнадцатеричном, и мусор в ASCII. Вы возможно предназначенный 0x68736100.

Это на самом деле очень близко:

(gdb) x/s 0x080485ff 
    0x80485ff: "" 
    (gdb) x/s 0x080485ff+1 
    0x08048600: "ash" 

Проблема заключается в том, что 0x68736100 является "hsa\0" - вы правильно поменять местами символы, но вы положили завершающий NUL на фронте вместо спины. Правильный вызов тогда:

(gdb) set {int}0x080485ff = 0x687361 
(gdb) c 
Continuing. 
sh: ash: command not found 

Это сработало!

+0

Спасибо, сэр! Это действительно то, что мне нужно было сделать - и ваши объяснения были высоко оценены. Что касается гексагона, я просто не предполагал, что rvalue может начинаться с 0x. Doh. Еще раз спасибо. – swisscheese

Смежные вопросы