
Как снять ограничение на размер изображения в DxO ViewPoint

Скриншот программы DxO ViewPoint
Для обработки цифровых фотографий я давно пользуюсь очень классной программой DxO ViewPoint 2. О том, что и как она умеет делать, лучше посмотреть на офсайте, статья не об этом. Дело в том, что после очередного обновления (линейка версий 2.5, если быть точным) DxO ViewPoint 2 наотрез отказалась открывать файлы с моего Nikon D800, при этом предыдущие версии с этими же фотографиями работали без каких-либо затруднений. Из краткой отмазки "Image file cannot be loaded" никакой полезной информации извлечь не удалось. Поскольку программа мне все-таки нужна, и желательно самой новой версии, я решил найти причину такого поведения и устранять ее.
Казалось бы, чем это будет отличаться от обычного разбора какой-нибудь защиты? Находим строчку в файле, находим перекрестные ссылки в дизассемблере, определяем условия срабатывания, патчим код. Но проблема в том, строка сообщения "Image file cannot be loaded" нигде не обнаруживается. Ни в исполняемых файлах, ни в файлах данных, ни в ASCII, ни в юникоде, ни фразой целиком, ни по отдельным словам. Хотя файлы не накрыты никакими упаковщиками или навесными протекторами. Пришлось подходить к проблеме с другой стороны.
При всей моей нелюбви к Qt, на котором написана DxO ViewPoint, его заморочки сейчас сыграли мне на руку. Я имею в виду "говорящие" наименования вызываемых функций, например, "warning@CMessageBox", "CMainWindow::doImageRotation", "DXO_dvpv2::licenseManager" и всякое подобное. Дизассемблер любезно предоставляет всю информацию о названиях в автокомментариях, и просто посмотрев на листинг можно с большой вероятностью узнать, что там происходит. Предположив, что в функции открытия изображения должны быть как-то обозначены ключевые слова "open" и "file", а затем проверяя все подозрительные функции в отладчике, я вышел на функцию, обозначенную как "CMainWindow::doOpenFile" (ну кто бы мог подумать! :)) Точка останова в отладчике подтвердила догадку, что при открытии файла выполняется именно этот код. Прохождение функции в пошаговом режиме под отладчиком также привело к появлению искомого сообщения об ошибке открытия файла.
Code (Assembler) : Убрать нумерацию
- .text:00412CC4 push eax
- .text:00412CC5 lea eax, [ebp+var_C]
- .text:00412CC8 mov large fs:0, eax
- .text:00412CCE mov ebx, ecx
- .text:00412CD0 mov edi, [ebp+arg_0]
- .text:00412CD3 push 3BEh
- .text:00412CD8 push offset aCBambooBambo_0
- .text:00412CDD lea eax, [ebp+var_58]
- .text:00412CE0 push offset aCmainwindowDoo
- ; "CMainWindow::doOpenFile"
- .text:00412CE5 push eax
- .text:00412CE6 call sub_519C90
- .text:00412CEB add esp, 10h
- .text:00412CEE mov ecx, edi
- .text:00412CF0 mov [ebp+var_4], 0
- .text:00412CF7 mov [ebp+var_41], 0
- .text:00412CFB call ds:?isEmpty@QString@@QBE_NXZ
- ; QString::isEmpty(void)
- .text:00412D01 test al, al
- .text:00412D03 jnz loc_413072
- .text:00412D09 push 0
- .text:00412D0B push 1
- .text:00412D0D mov ecx, ebx
- .text:00412D0F call sub_44B560
- .text:00412D14 call sub_4461E0
- .text:00412D19 mov esi, eax
- .text:00412D1B test esi, esi
- .text:00412D1D jz loc_412FC4
- .text:00412D23 push edi
- .text:00412D24 call sub_417230
- .text:00412D29 add esp, 4
- .text:00412D2C test al, al
- .text:00412D2E jz loc_412FC4
- .text:00412D34 mov eax, [esi]
- .text:00412D36 push 0
- .text:00412D38 push offset a2fileopencompl
- ; "2fileOpenCompleated(bool)"
- .text:00412D3D mov ecx, esi
- .text:00412D3F call dword ptr [eax+0BCh]
- .text:00412D45 push eax
- .text:00412D46 lea ecx, [ebp+var_28]
- .text:00412D49 call ds:??0COperationCompletionWaiterWithResult
- .text:00412D4F mov eax, [esi]
- .text:00412D51 push edi
- .text:00412D52 mov ecx, esi
- .text:00412D54 mov byte ptr [ebp+var_4], 1
- .text:00412D58 call dword ptr [eax+40h]
- .text:00412D5B lea ecx, [ebp+var_28]
- .text:00412D5E call ds:?startWaiting
- .text:00412D64 lea ecx, [ebp+var_28]
- .text:00412D67 call ds:?isOperationSuccess
- .text:00412D6D test al, al
- .text:00412D6F jz loc_412F59
- .text:00412D75 call sub_4461E0
- .text:00412D7A mov edx, [eax]
- .text:00412D7C lea ecx, [ebp+var_50]
- .text:00412D7F push ecx
- .text:00412D80 mov ecx, eax
- .text:00412D82 call dword ptr [edx+104h]
- .text:00412D88 push eax
- .text:00412D89 mov ecx, ebx
- ; Вызвать функцию проверки
- .text:00412D8B call sub_415A20
- ; Если результат AL=0, то выполнить переход, иначе сообщение об ошибке
- .text:00412D90 test al, al
- .text:00412D92 jz loc_412E8E
- .text:00412D98 push 0
- .text:00412D9A lea eax, [ebp+var_48]
- .text:00412D9D push offset aSorryFileCould
- ; "Sorry, file could not be opened"
- .text:00412DA2 push eax
- .text:00412DA3 call sub_427660
- .text:00412DA8 add esp, 0Ch
- .text:00412DAB mov ecx, eax
- .text:00412DAD push 0
- .text:00412DAF push ecx
- .text:00412DB0 mov eax, esp
- .text:00412DB2 push ecx
- .text:00412DB3 push offset unk_5E451C
- .text:00412DB8 push ebx
- .text:00412DB9 mov byte ptr [ebp+var_4], 2
- .text:00412DBD mov dword ptr [eax], 400h
- .text:00412DC3 call ds:?warning@CMessageBox
- .text:00412DC9 add esp, 14h
- .text:00412DCC lea ecx, [ebp+var_48]
- .text:00412DCF mov byte ptr [ebp+var_4], 1
- .text:00412DD3 call ds:??1QString@@QAE@XZ
Code (Assembler) : Убрать нумерацию
- .text:00415A20 sub_415A20 proc near
- .text:00415A20 arg_0 = dword ptr 8
- .text:00415A20 push ebp
- .text:00415A21 mov ebp, esp
- .text:00415A23 mov ecx, [ebp+arg_0]
- .text:00415A26 push edi
- ; Высота изображения
- .text:00415A27 call ds:?height@QSize ; QSize::height(void)
- .text:00415A2D mov ecx, [ebp+arg_0]
- .text:00415A30 mov edi, eax
- ; Ширина изображения
- .text:00415A32 call ds:?width@QSize ; QSize::width(void)
- ; Перемножить ширину на высоту
- .text:00415A38 imul edi, eax
- .text:00415A3B xor eax, eax
- ; Результат больше 24000000 (в десятичной)?
- .text:00415A3D cmp edi, 16E3600h
- ; AL=1 - изображение превышает допустимый размер, открывать нельзя
- ; AL=0 - изображение можно открыть
- .text:00415A43 setnle al
- .text:00415A46 pop edi
- .text:00415A47 pop ebp
- .text:00415A48 retn 4
- .text:00415A48 sub_415A20 endp
Чтобы снять ограничение, достаточно пропатчить команду SETNLE AL по адресу 00415A43, заменив ее на двухбайтовую команду XOR EAX,EAX, а оставшийся байт заменив командой NOP. Теперь любое изображение будет успешно проходить проверку на допустимый размер.

Изображение успешно открывается
Я могу предположить, зачем сделано это ограничение, скорее всего, чтобы программа не падала от переполнения памяти на очень больших изображениях. И пусть я не собираюсь открывать в DxO ViewPoint гигапиксельные панорамы, терпеть неудобства с проверками размера тоже не намерен. Сигнатура для поиска приметная, можно легко сделать универсальный патч.
Просмотров: 5703 | Комментариев: 4
Метки: исследование защиты

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Never
(05.12.2014 в 10:58):
Спасибо за очередное открытие, в комплект must have забрал.

ManHunter
(05.12.2014 в 10:57):
Для исправления перспективы и дисторсии. Пока что самая лучшая из испробованных.
Исходное: http://rghost.ru/private/59431...de/image.png
После обработки: http://rghost.ru/private/59431...40/image.png
Исходное: http://rghost.ru/private/59431...de/image.png
После обработки: http://rghost.ru/private/59431...40/image.png

Never
(05.12.2014 в 10:50):
Ты великолепен! Впрочем как и всегда.
Прога для правки "широких" фотографий?
Прога для правки "широких" фотографий?

AyTkACT
(03.12.2014 в 10:41):
Qt такой Qt. © Manhunter
Тут и добавить нечего.
Тут и добавить нечего.

Добавить комментарий
Заполните форму для добавления комментария
