eXeL@B —› Вопросы новичков —› Неизвестный переход |
Посл.ответ | Сообщение |
|
Создано: 16 июня 2019 11:24 · Личное сообщение · #1 Всем привет! Разъясните пожалуйста поведение приложения, не понимаю как это работает. Ситуация следующая: Перед отправкой пакета перенаправляется вызов WSASend на какую-то кастомную функцию, после этого пакет зашифровывается и вызывается оригинальный WSASend. (Моя теория). Начал дебажить, расставил трассировку, пытаюсь понять порядок вызова функций. Вижу в IDA такой блок: [Скриншот 1] Судя по скриншоту мы находимся по адресу: .text:00423A80 push esi Логично подумать что, так как операции выполняются друг за другом мы перейдем в адрес: .text:00423A81 stosd И далее .text:00423A82 loopne near ptr unk_423ADD выходим из функции. НО! Когда в дебаггере я выполняю переход к следующей операции, я оказываюсь вообще в другом блоке кода с другой адресацией: debug078:029C1B30 push ebp <---------- Тут debug078:029C1B31 mov ebp, esp debug078:029C1B33 sub esp, 20h debug078:029C1B36 push ebx debug078:029C1B37 push esi debug078:029C1B38 push edi debug078:029C1B39 jmp loc_2A1D88 Скорее всего это и есть перехват управления на кастомную функцию, но я в упор не понимаю где описано что нужно перейти в другое место, те вроде как ни в регистрах, нигде не описан этот адрес вообще, на момент ПЕРЕД переходом. Можете пояснить пожалуйста каким образом происходит этот переход? Спасибо! b26f_16.06.2019_EXELAB.rU.tgz - jpg.png |
|
Создано: 16 июня 2019 11:35 · Личное сообщение · #2 |
|
Создано: 16 июня 2019 11:37 · Поправил: Osoro · Личное сообщение · #3 Скажите какую информацию отправить, чтобы помочь разобраться? @f13nd: Можно ли посмотреть список исключений, которые могли бы сработать? Просто получается что наверняка методов которые позволяют делать такие переходы ограниченное количество? Процессор же должен понимать какие инструкции он "должен" выполнить далее? |
|
Создано: 16 июня 2019 11:41 · Поправил: f13nd · Личное сообщение · #4 Об исключениях отладчик всегда предупреждает, если ты не настроил его игнорировать определенные. В иде это выгдялит как мерзкое окошко, куда надо кликать. Список обработчиков находится в цепочке SEH (был еще VEH, но хоть раз бы его увидеть), такие трюки с прыжками делает обычно самый верхний, который устанавливается после пролога функции. ----- 2 оттенка серого |
|
Создано: 16 июня 2019 11:43 · Поправил: Osoro · Личное сообщение · #5 |
|
Создано: 16 июня 2019 11:44 · Личное сообщение · #6 |
|
Создано: 16 июня 2019 11:50 · Личное сообщение · #7 |
|
Создано: 16 июня 2019 11:55 · Поправил: plutos · Личное сообщение · #8 Osoro пишет: если не секрет)? да тот же An open-source x64/x32 debugger for windows. IDA это прежде всего decompiler. ----- Give me a HANDLE and I will move the Earth. |
|
Создано: 16 июня 2019 11:55 · Личное сообщение · #9 |
|
Создано: 16 июня 2019 11:57 · Личное сообщение · #10 |
|
Создано: 16 июня 2019 12:03 · Поправил: plutos · Личное сообщение · #11 difexacaw пишет: так что Olly пойдёт ОllyDbg конечно пойдет, но You can now run ----- Give me a HANDLE and I will move the Earth. |
|
Создано: 16 июня 2019 23:54 · Личное сообщение · #12 |
|
Создано: 17 июня 2019 17:28 · Поправил: Osoro · Личное сообщение · #13 Форум мне позволяет, к сожалению, только несколько сообщений в день писать. Благодаря x64dbg и @f13nd (спасибо) удалось выяснить следующее: Нормальный дебаггер преобразерует инструкцию (каким то магическим методом через пару минут после запуска приложения): .text:00423A80 push esi .text:00423A81 stosd .text:00423A82 loopne near ptr unk_423ADD В: 00423A80 jmp 39C1B30 В теории срабатывает какойто умный механизм который видит что тут срабатывает какое-то исключение и меняет код. Не совсем понимаю как это работает. Вообщем я решил углубится в изучение этого jmp который дебаггер подставляет, там очень странная ситуация происходит. Приложение просто зацикливается на нескольких блоках инструкций, я врубал трассировку и анимацию, но в итоге из цикла выйти не могу. Самое интересное, что когда я просто делаю продолжение работы программы, то она каким то чудом из этого цикла выходит (хотя я не вижу куда там можно вообще брейкпоинт поставить на выход, там кольцо из jmp -> jmp -> jmp.). Похоже на какую-то защиту от дебаггеров (возможно). По большому счету я пока в тупике. Пытался исследовать SEH цепочку, но там судя по адресам вообще к этому куску кода никакого отношения нет: http://prntscr.com/o2y5kr Прочитал несколько статей о том, каким образом от дебаггеров защищаются, про возню с PEB, флагами и тд. Пытаюсь найти намеки на эти методы в коде. Вообщем если есть мысли куда меня направить, то было бы супер. |
|
Создано: 17 июня 2019 23:41 · Личное сообщение · #14 Osoro Для начала нужно сказать что ты зря решил использовать x64dbg. Разумно использовать Олли для отладки 86. Почему ты поймёшь сам со временем. > Нормальный дебаггер преобразерует инструкцию Нет, если память изменяется, то отладчик тут не причём. Хотелось бы увидеть сам цикл полный, может там выходы есть - к примеру вызовы апи или возвраты. Тоесть инструкции передающие управление. > каким то чудом из этого цикла выходит Выйти из цикла поток может двумя способами(за исключением ветвлений). Эти оба способа касаются манипуляций с контекстом, те управление задачами. Это либо второй поток изменил контекст первого, либо действительно произошло исключение. Может быть есчо вариант что есть ядерный вызов в цикле, но нужно видеть весь цикл что бы не гадать. В случае если это исключение, то следует сделать следующее. Никакой сех/вех трогать не нужно. Поток меняет режим при выходе из ядра на фиксированные адреса. За исключением оконных вызовов, это вам пока не нужно(при этом нужен ядерный отладчик). Так вот это фиксированные адреса в системном модуле(ntdll), Kixx. На эти адреса ядро возвращает управление. При исключении это KiUserExceptDisp.., туда ставь точку останова, на стеке будет контекст(задача выгружена). Там в параметрах будет причина исключения. Далее обработка исключения, та же структурная к примеру, изменяется контекст и управление возвращается в ядро для загрузки задачи(контекста), но это не обязательно. Если в цикле нет инструкций передачи управления за пределы цикла, нет ядерных вызовов(или вложенных процедур к ним приводящим), то единственный способ выйти из цикла это исключение. Но почему то мне это кажется сомнительным, те это врядле так. Незачем покидать цикл через ловушки. Цикл это монотонные операции, к примеру заполнение памяти, исключение возникнет при её исчерпании, но это не имеет смысла, так как это тупо переполнение буфера. Думаю вы просто пропустили инструкции выхода их цикла и всё проще. ----- vx |
|
Создано: 17 июня 2019 23:58 · Личное сообщение · #15 difexacaw Спасибо! Завтра более подробно углублюсь в эту часть, а пока пишу о небольшом шаге вперед: УРА! Есть небольшой успех, решил поискать больше информации в блоке перехвата функций и нашел кучу вот таких вот участков: http://prntscr.com/o334li http://prntscr.com/o334sz http://prntscr.com/o33505 Все как и предполагалось похоже, действительно в цепочку загоняются дополнительные обработчики исключений, в связи с этим несколько вопросов: 1) Я точно знаю что выполняется перехват всего двух функций RECV и SEND из винсок, почему тогда в блоке где инжектятся исключения - их там около 8 - 9 в цепочку добавляется, почему так много? 2) Как определяется какое исключение должно обрабатывать какую функцию? Ведь даже на PHP у исключения есть тип и они каскадом идут получается, и первое которое сделало catch выполняется. 3) Сперва выполняется функция сохранения адресов send recv и хендлера коннекта в память: http://prntscr.com/o339f3 Далее выполняются инжекты, то о чем я выше писал, и далее странная функция: http://prntscr.com/o33a7a Зачем еще раз загружать ту же самую либу, если она уже была загружена ранее? Причем до того как запушится ее имя, в стеке зачем то это выполняется: 0042354C | C74424 18 60717500 | mov dword ptr ss:[esp+18],talonexe.757160 | [esp+18]:"PE", 757160:"connect" 00423554 | C74424 1C 54717500 | mov dword ptr ss:[esp+1C],talonexe.757154 | [esp+1C]:"LdrUnregisterDllNotification", 757154:"closesocket" 0042355C | C74424 20 4C717500 | mov dword ptr ss:[esp+20],talonexe.75714C | [esp+20]:"LdrUnregisterDllNotification", 75714C:"send" 00423564 | C74424 24 44717500 | mov dword ptr ss:[esp+24],talonexe.757144 | 757144:"select" |
|
Создано: 18 июня 2019 00:12 · Личное сообщение · #16 Osoro > почему тогда в блоке где инжектятся исключения - их там около 8 - 9 в цепочку добавляется Что это значит ? Предполагалось что цикл без вложенных функций, иначе исключения не причём. > 2) Как определяется какое исключение должно обрабатывать какую функцию? Я выше описал. Механизм прост - возникает исключение, ядро выгружает задачу и причину на поточный стек и возвращает управление на обработчик исключения - Ki*. Если прицеплен отладчик, он до этого подхватит исключение и возможно его обработает, от настроек зависит. По этой причине вы можете запутаться или не верно понять события. > Зачем еще раз загружать ту же самую либу, если она уже была загружена ранее? Хз причём тут загрузка и что за инжекты. Не понятно ничего. Добавлено спустя 3 минуты Покажите само апп. ----- vx |
|
Создано: 18 июня 2019 00:21 · Поправил: VOLKOFF · Личное сообщение · #17 Osoro пишет: Нормальный дебаггер преобразерует инструкцию (каким то магическим методом через пару минут после запуска приложения): .text:00423A80 push esi .text:00423A81 stosd .text:00423A82 loopne near ptr unk_423ADD В: 00423A80 jmp 39C1B30 Если делать какие-то выводы (что делать не стоит), то исходя из опкодов, это не "шифты" инструкций и не "прятки", что методом исключений дает прямую перезапись секции кода приложения (судя по адресам), что легко ловится и анализируется. Если приложенька уже скомпилена с перезаписываемой секцией .text|.code|%anyname%, то смотри непосредственно начиная с записи в участок. Но как и говорил, это абстрактное вангование на основе ваших выводов (которые могут быть далеки от истины). Кидайте поциента, будет какой-то предметный разговор. Ну или курите дальше "реверс-философию" мультов Инде, скоро думаю их еще парочка в тему подтянется (если вы не один из них конечно, тогда все норм, продолжаем развеивать скуку) Osoro пишет: Как определяется какое исключение должно обрабатывать какую функцию Вам бы почитать матчасть про принцип работы цепочек исключений, вопросы пропадут. Osoro пишет: Зачем еще раз загружать ту же самую либу По скринам угадывать? Вариантов много, если это про код для инжекта, то стандартная практика, если нет, может юзаться просто для получения базы, код вообще сильно контекстозависим, особенно при наличии антиотладки... |
|
Создано: 18 июня 2019 00:32 · Поправил: difexacaw · Личное сообщение · #18 VOLKOFF Я один акк тут только использую, какие мульты. Зачем мне второй, думаешь я эти мелкие темы бы смотрел, если бы были норм ? Я использовал кучу аккаунтов когда была облава", те цепь банов. А в норм обстановке мне это не нужно совершенно. Чушь какую то пишешь. Нет тут пока тех. тем или каких то интересных, тогда уделю внимание этой. ----- vx | Сообщение посчитали полезным: VOLKOFF |
|
Создано: 19 июня 2019 12:04 · Поправил: Osoro · Личное сообщение · #19 Вообщем ввел я всех в заблуждение. Оказалось все гораздо проще (это по поводу перехвата wsasend/recv). Никакого перехвата нету, пакет шифруется ДО того как попасть в стандартный send. Вообщем то оказалось следующее: В статическом виде через IDA можно видеть такие инструкции: .text:00423A80 push esi .text:00423A81 mov esi, ecx .text:00423A83 cmp byte ptr [esi+78h], 0 .text:00423A87 jnz short loc_423ACF После того как приложение запускается, инструкции меняются на такие: .text:00423A80 jmp near ptr unk_3971B30 .text:00423A80 ; --------------------------------------------------------------------------- .text:00423A85 db 78h ; x .text:00423A86 db 0 .text:00423A87 ; --------------------------------------------------------------------------- .text:00423A87 jnz short loc_423ACF Вообщем туда просто по этому адресу ставится джамп. Поэтому я сначала видел одно, потом другое и думал что это Exception или что-то еще. Оказалось все проще. С этим разобрались. Если перейти по этому джампу, то как раз я и попадаю в тот бесконечный цикл где jmp->jmp->jmp. Сейчас я загружу картинку, там есть инструкция: js 3237274 В конце нее есть джамп: jmp dword ptr ds:[edi+eax*4], он перепрыгивает в 03235CB9, те опять в круг. Вот собственно остался вопрос: каким образом из этого круга выходит, если сделать просто Resume дебага. Цикл идет от адреса 323600D ea56_19.06.2019_EXELAB.rU.tgz - graph.png |
|
Создано: 19 июня 2019 17:10 · Личное сообщение · #20 |
|
Создано: 19 июня 2019 17:18 · Личное сообщение · #21 |
|
Создано: 19 июня 2019 17:35 · Личное сообщение · #22 |
|
Создано: 19 июня 2019 18:05 · Поправил: Osoro · Личное сообщение · #23 |
|
Создано: 19 июня 2019 18:14 · Личное сообщение · #24 Osoro В разделе Железная антиотладка поясняется, почему вы не вышли с цикла руками, а без трейса всё чудесно. ----- Stuck to the plan, always think that we would stand up, never ran. | Сообщение посчитали полезным: Osoro |
|
Создано: 19 июня 2019 22:42 · Личное сообщение · #25 |
|
Создано: 20 июня 2019 00:47 · Личное сообщение · #26 ARCHANGEL Очень интересная статья, спасибо. Единственное что меня смущает, если в статье рассматривают STOS и MOVS, которые фактически модифицируют инструкции, при этом из-за того что используется кеш при нормальном выполнении - команда выполняется без внезапного возврата, то в моем случае я могу предположить что lodsb берет также из памяти значения которые НЕ закешированы в дебаг режиме, изза этого рассчитывает "неправильно" (для меня) в блоке джампа jmp dword ptr ds:[edi+eax*4] адрес и поэтому попадает опять сама на себя. Единственное что можно подозревать, другого ничего не вижу. Тогда если в случае с примером и STOS я знаю в EDI адрес куда она пишет, и могу фактически реальную функцию найти, которая должна была бы вызваться, то в случае с lodsb каким образом можно получить значение в памяти, которое динамически там появляется, при этом не используя дебаггер. Или я неправильно понял? difexacaw Форум для новичков же? Профи вопросы в основном форуме пишут. |
|
Создано: 20 июня 2019 02:16 · Личное сообщение · #27 |
|
Создано: 20 июня 2019 14:18 · Личное сообщение · #28 Во-первых у иды вообще проблемы с синхронизацией во время отладки. Во-вторых софтварный бряк это замена первого байта инструкции на 0xC3 (int3), этим свойством часто пользуются рассчитав например кс выбранного участка и используя ее для чего-нибудь. Приведенный фрагмент просто гоняет значения регистров меж собой и через стек. Возможно на входе при нормальном исполнении должны быть не эти значения, а может быть ты свернул в эту ветку из-за того, что до этого был обнаружен отладчик. А может быть и так, что другой поток должен остановить этот тред и накрутить в нем контекст. Скорей всего (случайно показалось) ты ищешь где клиент игры шифрует обмен, наверное от этого и надо плясать (от внешних или внутренних криптографических функций). Потому что либо надо детально разбираться как работает протектор, либо не лезть туда (особенно отладчиком, в котором не применяется никаких техник сокрытия), искать другие способы. ----- 2 оттенка серого |
|
Создано: 20 июня 2019 14:51 · Личное сообщение · #29 0xC3 это RETN, INT3 это 0xCC. Но вряд-ли это поможет автору темы... | Сообщение посчитали полезным: f13nd |
|
Создано: 22 июня 2019 14:57 · Личное сообщение · #30 ARCHANGEL Я проверил интереса ради: Code:
Очевидно что перезапись строковой инструкции зависит от проца. Так на i5 что на варе, что напрямую одинаково. Заполняется 64 байта, а не вся строка. Не зависимо от выравнивания. Code:
Если через F8 в отладчике(step over) выполнить, то так же разницы никакой - Олли ставит точку останова за инструкцией (_Tempbreakpoint()). Наверно подразумевается пошаговая трассировка(TF). 44f7_22.06.2019_EXELAB.rU.tgz - rep.png ----- vx |
eXeL@B —› Вопросы новичков —› Неизвестный переход |