вторник, 27 июля 2021 г.

Reverse Engineering шпаргалка.

 Сразу скажу, тут я нуб! Это шпаргалка для меня (как я решил задачу). Ну может кому ещё будет полезна. Данные черпал из Reverse Engineering for Beginners (berkeley.edu)

Вводная:

    По работе нужно было исправить логику 3rdparty библиотек, которые предоставил заказчик с хидерами и сборками как static lib в дебажном и релизном варианте. Так как были дебажные версии то решил, что RE будет не сложным. Так и получилось.

Шпаргалка:

1. Получаем asm листнинг библиотеки через утилиту dumpbin, которая идёт в составе Visual Studio.

2. В asm листинге ищем функцию, которую надо "расшифровать" простым поиском по тексту.

3. Для анманглинга имён функций используем утилиту undname из состава Visual Studio.

4. Читаем и пишем свой вариант функции (допустим на С++).

5. Пишем тест на расшифрованную логику.

6. Прогоняем через тест свою функцию и функцию из препарируемой библиотеке.


Детали.


Дело было в винде и я использовал Notepad++. Сделал вертикальный разрез. Справа был чистый asm-листинг - слева был "рабочий" файл, в котором я писал комментарии при расшифровке.


На картинке мои комментарии зелёным.
В процессе расшифровки в комментариях переменные обычно называл так, что бы по asm листингу было проще отследить. Например на скриншоте  по адресу [ebp-24h] находится адрес std::vector< uint8_t >. В комментариях я так и назвал переменную - ebp_24. Все переменные ebp-X - это локальные переменные функции.  ebp-0h - это адрес нашей функции, в которой мы "находимся". Если функция возвращает значение, то выше 0 в стеке лежит (в случае x86) адрес возвращаемой переменной. Дальше ( ebp+X ) лежат входные параметры функции. Указатели (в этом случае) занимают 8 байт, простые значения (uint8_t, uint32_t) - 4 байта или больше (double, int64_t - 8 байт). Про остальные не скажу, но это легко вычисляется при анализе.

Затем написал функцию и к ней написал тест.

На скриншоте слева код теста, а справа код, который я "родил" в процессе расшифровки. Тест пассится, но с кодом надо ещё разобраться (непонятные магические цифры - надо поглядеть предметную область и понять зачем, может в исходном коде ошибка). AfdxPack::GetIpPack - это препарируемая функция, а AfdxPack2::GetIpPack - это то, что я "родил". Как всегда, тест сильно снижает вероятность ошибки при дешифровке.


среда, 26 мая 2021 г.

GitSvn - ошибка fatal: bad object


 При обновлении данных из SVN репозитория заказчика через `git svn fetch` получил следующую ошибку:

W: -empty_dir: branch/MC21FMSINT-583/OHBS/OHBSioGUI/MainForm.resx
Checking svn:mergeinfo changes since r2852: 13 sources, 3 changed
fatal: bad object a3e4f2cbe92958764e31197c3391fe7eccc33f88
rev-list -1 46d79549314a6c8bfd87ce1d50ab15db8992c326
a3e4f2cbe92958764e31197c3391fe7eccc33f88 --not b93da3edf57134b3bd9722ec875219d9ac67c166: command returned error: 128

В поисках решения наткнулся на заметку: Alieniloquent: "git svn fetch dies with \"fatal: bad object\""

Шпаргалка для решения:

  1. Заходим в директорию .git
  2. Запускаем поиск упоминаний о проблемном коммите (в моём случае a3e4f2cbe92958764e31197c3391fe7eccc33f88)
  3. Удаляем бинарные файлы, которые относятся к мержу и черри-пику.
  4. Ещё раз запускаем `git svn fetch`
В моём случае выглядело так (через GitBash в Windows):

rgade@DESKTOP-TFEG50M MINGW64 ~/workspace/myproject/.git (GIT_DIR!)
$ find . -exec grep -Hin a3e4f2cbe92958764e31197c3391fe7eccc33f88 {} \; | grep "Binary file"
Binary file ./svn/.caches/check_cherry_pick2.db matches
Binary file ./svn/.caches/lookup_svn_merge.db matches

rgade@DESKTOP-TFEG50M MINGW64 ~/workspace/myproject/.git (GIT_DIR!)
$ rm ./svn/.caches/check_cherry_pick2.db

rgade@DESKTOP-TFEG50M MINGW64 ~/workspace/myproject/.git (GIT_DIR!)
$ rm ./svn/.caches/lookup_svn_merge.db

воскресенье, 23 мая 2021 г.

Работа с SVN репозиторием через git-svn

Речь не о переносе проекта с SVN на GIT, а про работу с SVN репозиторием через git-svn.

Ситуация: у заказчика SVN репозиторий. Помимо прочего он ещё и в приватном VPN (Checkpoint VPN, по факту не получилось подключиться к нему из Линукса через `snx`, пришлось подключаться из Windows). 
Что бы дальше так не мучиться, решил работать через `git-svn`. Наступил на пару граблей. Ниже шпаргалка как работать в таких случаях.

Зачем?


1) При работе с git-svn не нужен постоянный коннект к репозиторию заказчика.
2) Простота создания веток для проверок различных вариантов решения проблемы.

Важно

Вне зависимости от того, в какой git-ветке мы находимся, при вызове git svn dcommit изменения будут заливаться в SVN ветку, на которую мы "настроены" во внешнем SVN репозитории. Я, по ошибке, залил не отревьювленные коммиты в транк, хотя был в другой ветке. Потому и решил эту шпаргалку написать.

Посмотреть, на какую ветку в SVN репозитории сейчас настроены

git svn dcommit -n или git svn dcommit --dry-run. Без реального пуша коммита покажет в какую ветку в SVN репозитории будет заливать данные при вызове git svn dcommit.

Альтернативный вариант.

git svn info

Смотреть поле URL. Например:

$ git svn info
Path: .
URL: http://customer/svn/projectX/trunk
Repository Root: http://customer/svn/projectX
Repository UUID: 10230cbc-1c0b-47a3-9371-a2b47a5679dc
Revision: 843
Node Kind: directory
Schedule: normal
Last Changed Author: Rinat.Gadelshin
Last Changed Rev: 843
Last Changed Date: 2021-05-23 19:32:30 +0300 (Sun, 23 May 2021)

Мы находимся в транке.

Создать новую ветку в SVN репозитории

git svn branch <new_branch_name>

Примечание: после создания новой ветки в SVN репозитории мы не переключились на неё, а остались в настроены на предыдущую SVN ветку. В данном случае на trunk.

Пример создания SVN ветки OHBS-29-3 и переключения Git репозитория на неё. С демонстрацией того, что автоматом не перенастраивается после создания:

$ git svn branch OHBS-29-3
Copying http://customer/svn/projectX/trunk at r843 to http://customer/svn/projectX/branch/OHBS-29-3...
Found possible branch point: http://
customer/svn/projectX/trunk => http://customer/svn/projectX/branch/OHBS-29-3, 843
Found branch parent: (refs/remotes/OHBS-29-3) 762910dc607920a9b59d0b5809102e03c19bc7cd
Following parent with do_switch
Successfully followed parent
r845 = c55b0f28e08d0a6db8c06230e0f620e40832a175 (refs/remotes/OHBS-29-3)
$ git svn info
Path: .
URL: http://customer/svn/projectX/trunk
Repository Root: http://
customer/svn/projectX
Repository UUID: 10230cbc-1c0b-47a3-9371-a2b47a5679dc
Revision: 843
Node Kind: directory
Schedule: normal
Last Changed Author: Rinat.Gadelshin
Last Changed Rev: 843
Last Changed Date: 2021-05-23 19:32:30 +0300 (Sun, 23 May 2021)
$ git reset OHBS-29-3
HEAD is now at c55b0f28e Create branch OHBS-29-3
$ git svn info
Path: .
URL: http://customer/svn/projectX/branch/OHBS-29-3
Repository Root: http://
customer/svn/projectX
Repository UUID: 10230cbc-1c0b-47a3-9371-a2b47a5679dc
Revision: 845
Node Kind: directory
Schedule: normal
Last Changed Author: Rinat.Gadelshin
Last Changed Rev: 843
Last Changed Date: 2021-05-23 19:32:30 +0300 (Sun, 23 May 2021)


Переключиться на другую ветку в SVN репозитории

git reset <branchname>

<branchname> это то, что идёт после remotes/ в выводе `git branch -a`.

Примечание: trunk отображается как remotes/origin/trunk.

Пример переключения на ветку tftp_refactoring и обратно на trunk:

$ git reset tftp_refactoring
$ git reset origin/trunk

Удалить ветку в SVN репозитории

Удалить ветку в SVN репозитории средствами git-svn нельзя (на момент версии 2.31.1). Удалять ветку необходимо средствами Subversion.

Либо через svn rm <full_path_to_branch_folder_on_the_repo
Либо через TortoiseSVN (в винде).

После того, как ветка удалена в SVN репозитории, git svn всё равно её отображает.

Для того, что бы удалить её из Git репозитория, необходимо:

1.  git update-ref -d remotes/<branchname>
2. git gc --prune=now 

Например, что бы удалить упоминания о ветке OHBS-29 надо выполнить:

git update-ref -d remotes/OHBS-29 && git gc --prune=now