Ответ 1
GDB - довольно мощный инструмент, но имеет немного кривой обучения.
В принципе, вы хотите установить условную точку останова.
Сначала используйте флаг -i для strace или objdump -d, чтобы найти адрес открытой функции или более реалистично что-то в цепочке попадания туда, например, в plt.
установите точку останова на этом адресе (если у вас есть символы отладки, вы можете использовать их вместо этого, опустив *, но я предполагаю, что вы этого не сделаете, хотя вы можете использовать их для библиотечных функций, если ничего другого.
break * 0x080482c8
Затем вам нужно сделать это условным
(В идеале вы могли бы сравнить строковый аргумент с нужной строкой. Я не пытался заставить это работать в течение первых нескольких минут попытки)
Можно надеяться, что строка является константой где-то в программе или одной из библиотек, которые она загружает. Вы можете посмотреть в /proc/pid/maps, чтобы получить представление о том, что загружено и где, затем используйте grep, чтобы проверить, что строка действительно находится в файле, objdump -s, чтобы найти его адрес, и gdb, чтобы убедиться, что вы фактически нашел его в памяти, объединив большую часть адреса с картами с низкой частью из файла. (EDIT: возможно, проще использовать ldd для исполняемого файла, чем смотреть в /proc/pid/maps )
Затем вам нужно будет что-то узнать об abi платформы, над которой вы работаете, в частности, как передаются аргументы. Я работал в руке в последнее время, и это очень приятно, поскольку первые несколько аргументов просто входят в регистры r0, r1, r2... и т.д. X86 немного менее удобен - кажется, они идут в стек, то есть * ($ esp + 4), * ($ esp + 8), * ($ esp + 12).
Итак, допустим, что мы находимся на x86, и мы хотим проверить, что первый аргумент в esp + 4 равен адресу, который мы нашли для константы, которую мы пытаемся поймать. Только, esp + 4 является указателем на указатель char. Поэтому нам нужно разыменовать его для сравнения.
cond 1 *(char **)($esp+4)==0x8048514
Затем вы можете ввести запустить и надеяться на лучший
Если вы поймаете свое условие точки останова и оглядетесь с помощью информационных регистров, и команда x для проверки памяти кажется правильной, вы можете использовать команду return, чтобы перколить резервную копию стека вызовов, пока не найдете то, что вы узнаете.