Восстановление 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: