Image

Listens: Дело было в Пеньково — [К.Молчанов - Н.Доризо #] Песня Матвея

Category:

Заголовок окна AlReader2

Одна из лучших читалок fb2 AlReader2 лет 5 как не обновляется для десктопа. У нее есть недостаток, который мешает мне жить. Независимо от того, какой файл открыт, заголовок окна остается прежним, “AlReader2”. Это мешает увидеть на панели задач название книги и не дает понять в отчете хронофагуса, какую книгу я читал в определенное время и сколько времени это заняло. Поэтому я взял hex-редактор и исправил недоработку.


В отладчике найдем, откуда вызывается CreateFileW с параметром-именем файла открываемого fb2. Это здоровенная функция sub_47D490. Забегая вперед, скажу, что она вызывается и при запуске программы с аргументом командной строки (причем после создания окна), и при выборе в меню Файл > Открыть файл.

0047D53B  53                 push    ebx             ; hTemplateFile
0047D53C  68 80 00 00 00     push    80h             ; dwFlagsAndAttributes
0047D541  6A 03              push    3               ; dwCreationDisposition
0047D543  53                 push    ebx             ; lpSecurityAttributes
0047D544  6A 01              push    1               ; dwShareMode
0047D546  68 00 00 00 80     push    80000000h       ; dwDesiredAccess
0047D54B  57                 push    edi             ; lpFileName
0047D54C  FF 15 84 98 62 00  call    ds:CreateFileW

Заменим инструкции, выделенные желтым, на безусловный джамп в достаточно большую и пустую (заполненную CC) область в сегменте кода, где разместим патч. Выровняем по числу байт с помощью nop (в образовательных целях).

0047D53B  E9 3A F4 07 00  jmp     loc_4FC97A
0047D540  90              nop

В ранее пустой области поместим код, который копирует edi с указателем на имя файла (в UCS2) в eax, ищет в нем сначала конец строки, затем в обратном направлении бэкслеш. Полученный указатель передаем API-функции SetWindowTextW вместе с глобальной переменной hwnd, хранящей хандл главного окна, в качестве первого аргумента. После выполнения полезной нагрузки исполняем инструкции, замененные на джамп (выделены желтым), и прыгаем обратно, продолжать нормальное исполнение программы.

004FC97A                     loc_4FC97A:
004FC97A  8B C7                  mov     eax, edi
004FC97C  66 83 38 00            cmp     word ptr [eax], 0
004FC980  74 09                  jz      short loc_4FC98B
004FC982                    
004FC982                     loc_4FC982:
004FC982  83 C0 02               add     eax, 2
004FC985  66 83 38 00            cmp     word ptr [eax], 0
004FC989  75 F7                  jnz     short loc_4FC982
004FC98B                    
004FC98B                     loc_4FC98B:
004FC98B  66 83 38 5C            cmp     word ptr [eax], 5Ch
004FC98F  74 09                  jz      short loc_4FC99A
004FC991                    
004FC991                     loc_4FC991:
004FC991  83 E8 02               sub     eax, 2
004FC994  66 83 38 5C            cmp     word ptr [eax], 5Ch
004FC998  75 F7                  jnz     short loc_4FC991
004FC99A                    
004FC99A                     loc_4FC99A:
004FC99A  83 C0 02               add     eax, 2
004FC99D  50                     push    eax             ; lpString
004FC99E  FF 35 0C DD 5F 00      push    hwnd            ; hWnd
004FC9A4  FF 15 E0 9A 62 00      call    ds:SetWindowTextW
004FC9AA  53                     push    ebx             ; hTemplateFile
004FC9AB  68 80 00 00 00         push    80h             ; dwFlagsAndAttributes
004FC9B0  E9 8C 0B F8 FF         jmp     loc_47D541

Скрипт для патча:

from ultra import file_get, file_put
import shutil

def unhex(s):
    return s.replace(' ', '').decode('hex')

shutil.copyfile('AlReader2.exe', 'AlReader2 - Copy.exe')
f = file_get('AlReader2.exe')
f = f.replace(unhex('E0 00 00 00 83 CD FF 3B C5 75 1D 53 68 80 00 00 00'),
              unhex('E0 00 00 00 83 CD FF 3B C5 75 1D E9 3A F4 07 00 90')
    ).replace(unhex('40 97 62 00 FF 25 F4 98 62 00 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC'),
              unhex('40 97 62 00 FF 25 F4 98 62 00 8B C7 66 83 38 00 74 09 83 C0 02 66 83 38 00 75 F7 66 83 38 5C 74 09 83 E8 02 66 83 38 5C 75 F7 83 C0 02 50 FF 35 0C DD 5F 00 FF 15 E0 9A 62 00 53 68 80 00 00 00 E9 8C 0B F8 FF'))
file_put('AlReader2.exe', f)

MD5:
0ac9594f977896e578815204e5258d42 оригинал
03df6b45dccecf2665a634525cd8d3d4 пропатченный файл