Набор статей и руководств по дизассемблеру IDA

Восстановление IDA.WLL и модулей в их "почти" первоначальное состояние.


Прежде чем двигаться дальше, Вам следует хорошо понять структуру PE-файлов [например, хорошо прочитать статьи Randy Kath или Hard Wisdom, для них есть переводы на русском - прим. перев.].

IDA.WLL и все модули имеют обычную точку входа.  Воспользовавшись PE-редактором ProcDump'а, Вы обнаружите, что точка входа IDA.WLL находится по адресу $100AA000.

Установите по этому адресу контрольную точку 'bpmb' и загрузите IDA.

001B:100AA000 60                 PUSHAD           <-- Вы оказались здесь


001B:100AA001 E841060000         CALL    100AA647


001B:100AA006 EB41               JMP     100AA049


001B:100AA008 0000               ADD     [EAX],AL


001B:100AA00A E177               LOOPZ   100AA083


001B:100AA00C 0C00               OR      AL,00


001B:100AA00E 0000               ADD     [EAX],AL


001B:100AA010 0000               ADD     [EAX],AL

Перед Вами типичная процедура распаковки или дешифрования - 'PUSHAD' сохраняет содержимое всех регистров, следующим шагом выполняется расшифровка DLL, а затем окончательный переход на точку входа.  Чтобы найти ее Вы должны знать, что все DLL имеют секцию инициализации, которая и является фактической точкой входа.  Здесь происходит выделение памяти, инициализация переменных и т.п.  При этом те же самые функции осуществляют выгрузку DLL.  Поэтому выйдите из IDAG.EXE сразу после появления информационного окна, установите контрольную точку, а когда сработает 'BPMB' выполните 'p ret' (F12), и Вы окажетесь в следующем фрагменте:

001B:10001000 A1E0A10710         MOV     EAX,[1007A1E0] <--- Вы оказались здесь



001B:10001005 C1E002             SHL     EAX,02

001B:10001008 A3E4A10710         MOV     [1007A1E4],EAX

001B:1000100D 8B442408           MOV     EAX,[ESP+08]

001B:10001011 A356A20710         MOV     [1007A256],EAX



001B:10001016 FF148546A20710     CALL    [EAX*4+1007A246]

001B:1000101D 833D56A2071001     CMP     DWORD PTR [1007A256],01

001B:10001024 0F8580000000       JNZ     100010AA

001B:1000102A 803DECA1071000     CMP     BYTE PTR [1007A1EC],00

001B:10001031 7424               JZ      10001057

001B:10001033 E88A850700         CALL    KERNEL32!GetVersion

001B:10001038 BAEDA10710         MOV     EDX,1007A1ED

001B:1000103D 2500000080         AND     EAX,80000000

001B:10001042 7405               JZ      10001049

001B:10001044 BA0DA20710         MOV     EDX,1007A20D

001B:10001049 52                 PUSH    EDX
Именно этот фрагмент является фактической точкой входа в IDA.WLL, она одинакова для всех модулей, и всегда отстоит на 1000h от базового адреса.
Нам нужно целиком сбросить эту DLL из памяти на диск; сначала я попытался сделать это с помощью ProcDump'а, однако этот способ терпит неудачу, когда IDA снова загружает в память сброшенную DLL.  Почему?
Все очень просто.  Для загрузки IDA.WLL в свой адресный контекст ProcDump использует загрузочную библиотеку (огромная ошибка при сбросе защищенных DLL), затем вызывает секцию инициализации по адресу 10001000, распределяет память и сбрасывает образ памяти на диск.  Но при распределении памяти секция инициализации устанавливает некоторые флаги, которые при сбросе сохраняются.  Если IDA затем загрузит эту сброшенную DLL, то флаги уже окажутся установленными, что и выявляется системой защиты.  Основные флаги располагаются в секции данных и тестируются процедурой инициализации DLL.
Следовательно, нам необходимо сбросить DLL до начала работы процедуры инициализации.  Для этого нам понадобится IceDump.
Установим контрольную точку по адресу 1b:10001000, загрузим IDA, и дождемся ее второго срабатывания (первый раз она сработает по команде ret во время дешифровки), когда Вы вновь придете к тому же самому адресу, но в этот момент DLL окажется загруженной, память распределенной, однако флаги еще не будут установлены.
ProcDump сообщит о IDA.WLL следующее:
базовый  адрес образа - 10000000
длина - ac000
Теперь воспользуемся IceDump и выполним команду 'd 10000000 ac000 "Ваша директория, что-нибудь типа \??\temp\ida.dmp"'
Вы получите файл IDA.TMP, содержащий все расшифрованные секции, но с заголовком, который еще требуется восстановить.  Сделаем это с помощью автоматической процедуры ProcDump'а.  Также с помощью ProcDump'а измените адрес точки входа на 10001000, и все заработает.
Не забудьте исправить IDA.WLL таким образом, чтобы 'CALL 10013298' никогда не возвращал 0 в EAX.  Постарайтесь найти нужные смещения сами!  А вот что я сам сделал в IDA.WLL.
0008:10013298 83C4E8             ADD     ESP,-18



0008:1001329B 33C9               XOR     ECX,ECX

0008:1001329D 8BC4               MOV     EAX,ESP

0008:1001329F C644240424         MOV     BYTE PTR [ESP+04],24

0008:100132A4 C644240520         MOV     BYTE PTR [ESP+05],20

0008:100132A9 C644240675         MOV     BYTE PTR [ESP+06],75

0008:100132AE C644240773         MOV     BYTE PTR [ESP+07],73

0008:100132B3 C644240865         MOV     BYTE PTR [ESP+08],65

0008:100132B8 C644240972         MOV     BYTE PTR [ESP+09],72

0008:100132BD C644240A31         MOV     BYTE PTR [ESP+0A],31

0008:100132C2 C644240B00         MOV     BYTE PTR [ESP+0B],00

0008:100132C7 8D542404           LEA     EDX,[ESP+04]

0008:100132CB E878410100         CALL    10027448

0008:100132D0 8BC4               MOV     EAX,ESP

0008:100132D2 B153               MOV     CL,53

0008:100132D4 33D2               XOR     EDX,EDX

0008:100132D6 E825480100         CALL    10027B00



0008:100132DB 85C0               TEST    EAX,EAX

0008:100132DD 7504               JNZ     100132E3

0008:100132DF B001               MOV     AL,01     * измененная часть, было 'XOR eax,eax'

0008:100132E1 EB31               JMP     10013314

0008:100132E3 8B5004             MOV     EDX,[EAX+04]

0008:100132E6 81FAC030D737       CMP     EDX,37D730C0

0008:100132EC 7D04               JGE     100132F2

0008:100132EE B001               MOV     AL,01     * то же самое

0008:100132F0 EB22               JMP     10013314

0008:100132F2 8B5010             MOV     EDX,[EAX+10]

0008:100132F5 81C2C9FDFFFF       ADD     EDX,FFFFFDC9

0008:100132FB 81FA0605FFA5       CMP     EDX,A5FF0506

0008:10013301 7404               JZ      10013307

0008:10013303 B001               MOV     AL,01     * то же самое

0008:10013305 EB0D               JMP     10013314



0008:10013307 8B500C             MOV     EDX,[EAX+0C]

0008:1001330A 85D2               TEST    EDX,EDX

0008:1001330C 7404               JZ      10013312

0008:1001330E B001               MOV     AL,01     * то же самое

0008:10013310 EB02               JMP     10013314

0008:10013312 B001               MOV     AL,01

0008:10013314 83C418             ADD     ESP,18

0008:10013317 C3                 RET
Таким образом, мы получили образ IDA.WLL и заменили зашифрованный файл практически исходным ему.
Теперь Ваша IDA работает нормально, все декомпилирует без ошибок и не помещает регистрационных записей в создаваемые файлы.  Теперь же в качестве упражнения давайте восстановим в свое "почти" исходное состояние  модули *.W32 и *.LDW.  Воспользуемся для этого той же самой техникой сброса образа на диск, восстановлением заголовка и смещением адреса точки входа на +1000.
Однако, на этот раз при попытке вызова из IDA функции loadlibraryA для загрузки модуля мы получим ошибку.  Рассмотрим в качестве примера PE.LDW.  Для сравнения сброшенного образа PE.LDW с исходным файлом воспользуемся таким замечательным инструментом как PEBrowse, и он покажет нам, что секция импорта в полученном образе немного отличается от оригинала.  Почему?  Да потому, что Windows изменяет адреса API-функций в секции импорта, и эти адреса оказываются в сброшенном модуле неработоспособными.
Секция импорта оказалась поврежденной.  Чтобы найти ее местонахождение, взгляните в ProcDump.  Он показывает, что ее виртуальный адрес равен 178f4.  Чему равно смещение файла?  Взгляните на секции: виртуальное смещение (Virtual offset) секции .adata равно 17000, а полное смещение (Raw Offset) = f200.  Следовательно, смещение секции импорта равно (178f4-17000) = 8f4 + f200 = faf4.
Взгляните на таблицу импорта в ASCII-режиме шестнадцатеричного редактора.  Дальше есть 2 пути: наиболее интересный из них - все сделать самому: изучить структуру таблицы импорта и самостоятельно восстановить ее так как это сделал я.  Этот путь требует некоторых затрат труда и времени, однако, в будущем он себя окупит с лихвой.  Более простой, воспользоваться таблицей импорта из оригинального файла PE.LDW:
 

Содержание раздела