Как реверсят протоколы клиент-серверных приложений?
тут нет единственно верного решения. Условно протоколы можно разделить на 3 группы:
- json\soap\xml. Там уже все описано, даже мозг включать не надо; 
- текстовые протоколы без описания структуры. Придется немного подумать, но весь текст у тебя перед глазами, выявить закономерности довольно просто. Записываешь, что настраивал на клиенте, смотришь как изменился запрос и ответ сервера. На крайняк декомпилируешь клиента и смотришь разбор протокола :) 
- бинарные протоколы. Вот тут реально хардкор. Если не получиться декомпилировать код клиента, то можно зависнуть надолго. Нужно будет строить предположения о структуре данных, проводить огромное количество экспериментов. И если для простых протоколов это еще реально, то для сложных проще заплатить кому-то из разработчиков, чтобы слили структуру. Например, мы реверсили протокол автомобильных весов. Клиентской программы не было, за нее просили несколько сот тысяч рублей, больше чем стоимость весов. Но в течение пары дней подобрали структуру и успешно расшифровали протокол, интегрировали весы в систему. А вот с протоколом  навигационного оборудования это не прокатило- слишком сложный протокол, очень много переменных. Оказалось дешевле закупать другие приборы с открытым протоколом.
В дополнение к ответу Артем Воронов стоит еще добавить, что помимо данных в открытом виде, существет еще потоковое шифрование траффика. Самый распространенный пример - https, где данные представляются в зашифрованном виде. Так же существет куча "движков" для потокового симметричного шифрования траффика. В этом случае, неплохо быть или стать продвинутым математиком.
Самый простой вариант для примера, запустить утилиту tcpdump на интерфейсе выхода в интернет для https:tcpdump -i eth0 'port 443' -X
и в браузере открыть какой-нибудь https://goo.gl
В остальном, чтобы понять, что отправляется нужно понять, как формируется структура данных при передаче.
Поэтому пишите свои клиент-серверные программы, желательно на сях, и смотрите как выглядит траффик.
Так же, стоит узнать о том как данные хранятся в памяти, например, что байты слова будут расположены в обратном порядке, что обычно строки передаются с предшествуюшим словом из количества байт в строке.
Для примера дизассемблируйте предварительно скомпилированную программу:int main(int argc, char** argv)
{
  static int var = 0xcc00ffee;
  return 0;
}
К прочтению: https://www.reddit.com/r/ReverseEngineering/commen...