Сейчас на форуме: asfa (+6 невидимых) |
![]() |
eXeL@B —› Вопросы новичков —› Пытаюсь распаковать, но что-то не получается :( |
. 1 . 2 . >> |
Посл.ответ | Сообщение |
|
Создано: 27 мая 2010 23:08 · Поправил: Semenov · Личное сообщение · #1 Всё началось вот тут: http://exelab.ru/f/action=vthread&forum=2&topic=15227&page=-1#22 По намёку модератора переехал сюда. Краткое содержание предыдущих серий: Пытаюсь распаковать _deleted_ дабы изучить как это и что это. По наводке людей было выяснено, что OEP -- 406874. Но на это стадии приложение ещё не выглядит окончательно распаковыванным и сдампить её не получилось. Вот прошу помощи у гуру в доведении дела до конца. ![]() |
|
Создано: 28 мая 2010 07:02 · Личное сообщение · #2 В деле распаковки говнокрипторов главное не зарыватся очень глубоко ) Наиболее распространены два варианта, каждый из которых использует второй слой декриптора. В первом случае данные во втором декрипторе фигачатся в выделенную область и там запускаются (полегче) и во втором случае освобождается память по ImageBase. Существуют ещё несколько способов работы крипторов по типу запуска дочернего процесса в суспенженном состоянии и внедрению туда нового образа или подмены длл в памяти, но они намного более редкие чем первые два. Главный подход - найти ключевые переходы без пошагового выполенения кода. В данном деле очень помогают апи шпионы - главное следить за резкими перепадами адреса возврата - они указывают на эти самые ключевые переходы. В первом распространенном варианте достаточно поставить бряк на VirtualAlloc/HeapAlloc/ZwAllocateVirtualMemory в зависимости от того что используется в крипторе и немного потрейсить на втором (возможно больше) срабатывании (можно сделать бряк на ешё одной апи после - смотреть в шпионе, тогда не придется трейсить) - и в буфере у нас окажется распакованный образ, возможно уже промапленный и с релоками - тогда придется править образ вручную или с помощью разных полезных тулз. Во втором случае всё немного сложнее. Но обычно переходы видны невооруженным глазом. Если же нет опять же апи шпион в помощь. Впрочем код второго слоя декриптора обычно приметивен и быстро анализируется, но я ленивый и обычно этого не делаю )) хотя зря, порою бывают закопаны неочевидные фичи )) В данном конкретном случае я делал следующее: bp VirtualAlloc прокрутил вниз в поисках возможного перехода увидел call edx, интуиция подсказала, что это оно самое, брякнулся там и перешел на второй слой Покрутил вниз, увидел два ret`a и после нули. Интуиция опять посказала, что это возможно наше. Поставил там бряки. Первый ret - просто возврат. Второй ret - переход к выравниванию стека и jmp edx который очевидно приводит нас к oep. Далее ollydump и рабочий образ. Как видишь, опыт решает, но пока его нет, пользуйся апи шпионами )) >>Но на это стадии приложение ещё не выглядит окончательно распаковыванным дык это зевс, там нету стаба. Сразу код идет выполняющий инициализацию и тд. Так что все нормально. ![]() |
|
Создано: 28 мая 2010 10:21 · Личное сообщение · #3 |
|
Создано: 28 мая 2010 11:01 · Личное сообщение · #4 |
|
Создано: 28 мая 2010 11:15 · Поправил: Semenov · Личное сообщение · #5 Вот сейчас закрыл глаза на отсутствие стаба. Перекинул получившийся дамп в ещё один Olly и пошёл его отлаживать. По адресу 0x40764D отладчик тупо зацикливается, с ошибкой Access denied и в следствии процесс "терминатед". Если это дамп запустить просто так, то он падает с ошибкой. В этом месте как я понял сохранение результата работы (Module Handle) функции LoadLibrary() в адрес 414D0C А адреса нет? ![]() В другом отладчике у меня исходный объект который я так же пытаюсь пройти пошагово, он же в этом месте замечательно проходит. Что такое? Там дальше GetprocAddress() и видать будет тоже самое. ЗЫ. Кстати, в 0x407647 стоит PUSH EBX - это вроде как тот самый параметр для функции, но тут какая-то своя обёртка для функций как я понял? Так да? ![]() |
|
Создано: 28 мая 2010 11:24 · Личное сообщение · #6 |
|
Создано: 28 мая 2010 11:26 · Поправил: Semenov · Личное сообщение · #7 А как это править? ![]() Как я понял с адреса 0x407626 по 0x40763C идёт расчёт адреса библиотеки kernel32.dll затем по 4 строчки на выколупывание из нё адресов функций LoadLibraryA() и GetProcAddress() с последующим сохранением их адресов впамяти по адресам 0x414D0C и 0x414CA4 соответственно. Если в оригинале всё гладко, то тут падение с access violation. Причём я не понимаю пока почему. Если в Olly открыть View->Memmory то видно, что участок от 0x413000 размером 0x5000, куда попадают наши указатели выше, принадлежит к .rdata и с флагом только для чтения. Что нужно править чтобы ошибки не было? Флаг секции или адреса куда сохранять? ![]() |
|
Создано: 28 мая 2010 12:29 · Личное сообщение · #8 |
|
Создано: 28 мая 2010 12:37 · Личное сообщение · #9 |
|
Создано: 28 мая 2010 12:50 · Личное сообщение · #10 |
|
Создано: 28 мая 2010 12:59 · Поправил: BoRoV · Личное сообщение · #11 эм... сразу после оеп идут две ф-ии подряд вот они и заполняют табличку импорта... дампишь на оеп, делаешь выполнение тех ф-ий, ищешь начало таблички импорта и конец(чтоб посчитать её размер), потом идешь в импрек вбиваешь там оеп, адресс начала импорта и размер какой там у тя уже вышол, жмешь гет импортб потом авто трейс(он находит невалидные), удаляешь невалидные, и ещё одну с всок, и прикручиваешь к дампу, а вообще почитай о анпаке простых пакеров. ----- Лучше быть одиноким, но свободным © $me ![]() |
|
Создано: 28 мая 2010 13:02 · Личное сообщение · #12 опираюсь на информацию из вот этой статьи: http://exelab.ru/art/?action=view&id=271 а как найти начало и размер? ![]() |
|
Создано: 28 мая 2010 13:10 · Личное сообщение · #13 после ГетПроцАдрес этот адрес должен ложится в ячейку памяти, отображаешь её в дампе, делаешь там вид отображение адреса, и там потом должен соринтироватся... я уже удалил файл и влом его снова качать, чтоб всё точно объяснить... поищи и посмотри мувики по распаковке, в некоторых я видел этот приём ----- Лучше быть одиноким, но свободным © $me ![]() |
|
Создано: 28 мая 2010 13:36 · Личное сообщение · #14 |
|
Создано: 28 мая 2010 14:03 · Поправил: Semenov · Личное сообщение · #15 Нашёл мануал как правильно рабоать с Таблице импорта и ImpREC но вот беда. После того как делаю Fix Dump, ошибка что дамп кривой. Дамп заранее сделан из OllyDmp с убраной галочкой Rebuild Imports. Всё. Вроде как получилась таблица импорта. Много читал и пробовал в итоге при помощи ImpREC и OllyDMP получилось сделать PE с таблицей импорта. Когда его подгружаю в дебагер сразу видны вызовы функций и даже ничего не падает по началу. Но вот по адресу 0x412BFD по прежнему ноли. А в оригинале туда распаковывается код. Получается что после дампа он не сдампился. Можно это как-то исправить? ![]() |
|
Создано: 28 мая 2010 14:26 · Личное сообщение · #16 |
|
Создано: 28 мая 2010 14:36 · Поправил: Semenov · Личное сообщение · #17 4С0 у меня в итоге получилось, а начало в 14А40, но вот куска .text не хватает ![]() Ещё при перестроении таблицы импорта функция WSAConnect почему-то Invalid... ААААА!!! УРА!!!! LordPE как-то это сделал иначе и получилось! Теперь у меня есть dump.exe с пофиксеной таблицей и который отлаживается уже довольно далеко. Теперь он зараза переходит на ExitProcess(). Предварительно прошерстив список процессов. Подозреваю он ищет какой-нить отладчик или ещё кого... Буду ковырять дальше. ОГРОМНОЕ спасибо за помощь! ![]() |
|
Создано: 28 мая 2010 20:19 · Поправил: Semenov · Личное сообщение · #18 |
|
Создано: 28 мая 2010 21:01 · Поправил: BoRoV · Личное сообщение · #19 |
|
Создано: 28 мая 2010 21:38 · Личное сообщение · #20 |
|
Создано: 28 мая 2010 21:48 · Личное сообщение · #21 |
|
Создано: 28 мая 2010 22:12 · Личное сообщение · #22 аааа, спасибо ![]() Пока очень напрягает 100% загрузка проца... Причём что самое интересное, я думал что это может быть из-за того что оно распаковано или под дебагером, но ведь если взять оригинал, запустить его из под дебага, он себя инсталит в систему и после перезагрузки системы снова жрёт 100%, но ведь он уже без всякой отладки и из оригинального образа... Вот же фигня какая. ![]() |
|
Создано: 28 мая 2010 22:19 · Личное сообщение · #23 аааа, спасибо ![]() Пока очень напрягает 100% загрузка проца... Причём что самое интересное, я думал что это может быть из-за того что оно распаковано или под дебагером, но ведь если взять оригинал, запустить его из под дебага, он себя инсталит в систему и после перезагрузки системы снова жрёт 100%, но ведь он уже без всякой отладки и из оригинального образа... Вот же фигня какая. ![]() |
|
Создано: 28 мая 2010 22:41 · Личное сообщение · #24 это нормально, он активно работает, делает свои пакости, я конечно хз, что он делает, то что инсталится и куда я увидел, но я потом его снес нах... соответствено я не могу понять, зачем ты его запускал, чтоб он прописывался, ладно ещё дебаг, хотя и это не пойму, чё ты так на нем зациклился, хочешь рипнуть алго и собрать своего конька?? ----- Лучше быть одиноким, но свободным © $me ![]() |
|
Создано: 28 мая 2010 22:53 · Личное сообщение · #25 Ну мне как бы не жалко, пусть ставится - делаю я это всё на виртуалке, специально для этого созданой. У меня отпуск и мне очень интересно как работают такие пакости, заодно изучу искуство диазссемблинга и как всё работает. А то всё Си да Си++. Это не нормально. Если его запустить просто как он есть после билдера, то он тихо мирно запускается. Если же вот так, то беда. Сижу сейчас изучаю параметры RtlCreateUserThread() и оказывается она не документирована. Но нашёл кое что на CodeProject. А неё передаётся куча параметров, мой подопытный прежде чем зависнуть передаёт в неё всего 2 весомых параметра, это ProcessHandle и StartAddress, всё остальное ноли. Так вот StartAddress величина где-то нигде, например BD7038, Олли при попытке перейти на этот адрес грит unknown identifer. Что это за адрес такой? И что должен исполнять этот поток если в этом адресе нет никого? ![]() |
|
Создано: 28 мая 2010 23:23 · Личное сообщение · #26 Разобрался, BD7038 это 0xBD0000 как ImageBase нашего тела в результате инжекта в чужой процесс в адресном пространстве чужого процесса. 7038 это адрес функции треда. Стал вникать по глубже выяснил, что проц жрёт тот процесс куда инжектились, получается чтобы узнать почему жрёт надо до запуска нити войти в отладку жертвы и добраться до тела нити и посмотреть что же так жрёт проц... Завтра продолжу свои поиски с отчётом что получилось. ![]() |
|
Создано: 29 мая 2010 08:26 · Личное сообщение · #27 |
|
Создано: 29 мая 2010 09:46 · Личное сообщение · #28 Archer пишет: Создай левый процесс сразу под олькой типа блокнота да подмени пид при открытие процесса, чтобы инжект шёл сразу в твой отлаживаемый левый процесс. можно еще проще, при инжекте ставить пид отлаживаемого процесса (зевса), а при запуске нового потока пропускать эту API и просто переходить на StartAddress создаваемого потока. Можно также при выделении памяти возвращать адресс заранее специально созданной дополнительной секции в файле, тогда и сдампить расшифрованный инжектируемый код можно продолжив его изучение уже в IDA ![]() |
|
Создано: 29 мая 2010 18:30 · Поправил: Semenov · Личное сообщение · #29 Инжектируется бинарник целиком. т.е. как есть пишеться в память чужого процесса, а там уже исполняется. Как рекомендовали подменяю пид на блокнот и внутри блокнота смотрю что оно там делает. Разобрался с загрузкой проца. После инжекта себя в чужой процесс, заразка внутри userThread опять строит таблицу импорта. Так вот первый же вызов LoadLibraryA() CALL указывает на адресное пространство внутри оригинального пройесса 0x040xxxxx когда в оригинале должен указывать на ижектрированное, к примеру 0x0EAxxxx. У оригинального ЕХЕ всё так и есть, а вот у распакованного всё плохо. Что влияет на это? Куда смотреть? Ну подтолкните на что-нить... Плииз ![]() ![]() |
|
Создано: 07 июня 2010 15:34 · Личное сообщение · #30 В общем суть такая. Ни с каким Import Table заморачиваться не надо, толку от этого ноль (ну может и не ноль но я пока не нашёл в чём толк). Эта зараза не изспольщует таблицу инмпорта на той стадии на которой я. У первых строках своего кода она пользуется двумя функциями LoadLibrary() и GetProcAddress() для построения в памяти своей собственной таблицы импорта путём GetProcAddress(LoadLibrary("filename.dll"),"functionname"); Видать чтобы не светить используемые им функции. Адреса к LoadLibrary и GetProcAddress получаются вот из этого: Примерно так: Code:
Так вот проблема у меня сейчас в следующем: После распаковки exe предложеным выше методом, значение 0x4011EC, указывающее в памяти на строку "LoadLibraryA", из кода выше, уже установлено и является константой. Но зараза в ходе свой работы копирует своё тело внутрь чужих процессов как то winlogon.exe и остлаьные, и там снова исполняется с позичии указанной в CreateUserThread. И там она снова начинает строить свою таблицу импорта и снова обращается к строке "LoadLibraryA" вот тут то и происходит Access violation потому как новый ImageBase уже не 0x400000, а некий другой относительно процесса-жертвы. А мы всё ещё пытаемся обратиться в 4011EC. Какой механизм меняет эти смещения? Кто такие "Relocation Table" и "Import Address table"? Могут они влиять на это? Когда бинарник в памяти у него есть ещё одна секция .rsrc с непонятным мне содержимым, и предыдущие Директории указывают именно на её адресное пространство. ЗЫ. Огромное спасибо всем помогающим. За это время что я ковыряю PE, я уже разобрался с кучей всего. ![]() |
. 1 . 2 . >> |
![]() |
eXeL@B —› Вопросы новичков —› Пытаюсь распаковать, но что-то не получается :( |