2017-01-23 2 views
2

Я разрабатываю упражнения для переполнения буфера для студентов. В этом контексте вам часто приходится предоставлять двоичные байты в качестве входных данных для программ (обратные адреса).Как отправить произвольные байты в STDIN программы в gdb?

Пусть этот пример:

#import <stdio.h> 
#import <string.h> 

void func() { 
    char buf[4]; 
    gets(buf); 
} 

int main (int argc, char** argv) { 
    func(); 

    return 0; 
} 

Обычно я экспериментирую с GDB, пока я не нашел решение, которое затем может быть сформулирована как

python -c 'print "A"*8+"\x08\x04\88\72"' | ./program 

При разработке более и более сложные упражнения, трудности чтобы найти решение. Иногда переписывание обратного адреса в gdb через

set {int}address_of_address = new_address 

работает, но подход python этого не делает. Было бы неплохо отладить это и иметь возможность вводить байты типа «\ x04» в gdb, а программа работает, анализируя эффекты.

Есть ли способ сделать это?

Этот вопрос кажется родственными, но отвечает с питона-подхода: Sending arbitrary bytes to fgets from stdin

Mine выходит за рамки: -/

+0

FYI, вам не нужен Python, вы можете использовать 'bash':' echo $ 'AAAAAAAA \ x08 \ x04 \ 88 \ 72' | ./program' – Barmar

+1

Будет ли это работать для вас http://stackoverflow.com/q/8422259/72178? – ks1322

+0

Да. Это очень полезно! Но есть ли способ ввода байтов в байтах, когда программа уже запущена? –

ответ

0

«в то время как программа работает» одна часть проблемы. Другой может установить контрольные точки заранее, «проанализировать эффекты».

Поведение GDB по умолчанию заключается в том, чтобы запустить программу как дочерний процесс, используя те же стандартные потоки. Таким образом, невозможно писать на stdin ребенка, находясь в CLI GDB, потому что в данный момент он читается GDB, а не вашей программой.

Самое простое решение, избегая TTY обходные (tty команда + stty расстановок + чтение/запись к /proc/<pid>/fd/{0,1}), чтобы сделать ваш код тестируемым и «вызываемая» из GDB. Затем вы сможете передать свои строковые аргументы в свои функции, чтобы проверить и отладить их.

Например:

#include <stdio.h> 
#include <unistd.h> 

void exploitme(char* str) 
{ 
    printf(str); 
} 

int main() 
{ 
    while (1) 
    { 
    char str[10]; 
    fgets(str, sizeof (str), stdin); 
    exploitme(str); 
    } 

    return 0; 
} 

exploitme() случай использовать правильно завернутый в единой точке входа, так что теперь можно назвать это, как только все это используется правильно инициализирован. Затем вы можете вызвать его, используя команду call, как только будет достигнута точка останова main() (чтобы выполнялись команды выполнения C, выполняемые в вызывающем абоненте основного пользователя).

~/test $ gdb ./a.out                      
(gdb) call exploitme("hello") 
You can't do that without a process to debug. 
(gdb) b main 
Breakpoint 1 at 0x4005ae: file helloworld.c, line 14. 
(gdb) r 
Starting program: /home/julio/test/a.out 

Breakpoint 1, main() at helloworld.c:14 
14   fgets(str, sizeof (str), stdin); 
(gdb) call exploitme("hello") 
(gdb) call exploitme("hello\n") 
hellohello 
(gdb) call exploitme("AAAAAAAA\x08\x04\88\72\n") 
AAAAAAA�: 
(gdb) b exploitme 
Breakpoint 2 at 0x400592: file helloworld.c, line 6. 
(gdb) call exploitme("foo") 
Breakpoint 2, exploitme (str=0x602010 "foo") at helloworld.c:6 
6   printf(str); 
The program being debugged stopped while in a function called from GDB. 
Evaluation of the expression containing the function 
(exploitme) will be abandoned. 
When the function is done executing, GDB will silently stop. 

Обратите внимание, что вы используете расширение аргументов GDB, которое включает в себя оценку строки C.

Другое (более длинное & complexer) решение, как объяснено, заключается в том, чтобы запустить вашу программу под другим tty, чтобы вы могли независимо писать GDB и программу.

0

Было бы неплохо, чтобы отладить это и, чтобы иметь возможность ввести байты как «\ x04» в БГД, в то время как программа работает, анализируя эффекты

Для этого нужно 2 консолей: первый для ввода байтов в программе stdin, второй для сеанса отладки gdb.

Вы можете сначала запустить программу в 1-й консоли, пока она не перестанет ждать байтов из stdin. Затем запустите gdb на 2-й консоли и прикрепите к нему программу pid. Вы сможете одновременно отлаживать и вводить байты из двух разных консолей.

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