Заголовок окна AlReader2
Одна из лучших читалок fb2 AlReader2 лет 5 как не обновляется для десктопа. У нее есть недостаток, который мешает мне жить. Независимо от того, какой файл открыт, заголовок окна остается прежним, “AlReader2”. Это мешает увидеть на панели задач название книги и не дает понять в отчете хронофагуса, какую книгу я читал в определенное время и сколько времени это заняло. Поэтому я взял hex-редактор и исправил недоработку.
В отладчике найдем, откуда вызывается CreateFileW с параметром-именем файла открываемого fb2. Это здоровенная функция sub_47D490. Забегая вперед, скажу, что она вызывается и при запуске программы с аргументом командной строки (причем после создания окна), и при выборе в меню Файл > Открыть файл.
Заменим инструкции, выделенные желтым, на безусловный джамп в достаточно большую и пустую (заполненную CC) область в сегменте кода, где разместим патч. Выровняем по числу байт с помощью nop (в образовательных целях).
В ранее пустой области поместим код, который копирует edi с указателем на имя файла (в UCS2) в eax, ищет в нем сначала конец строки, затем в обратном направлении бэкслеш. Полученный указатель передаем API-функции SetWindowTextW вместе с глобальной переменной hwnd, хранящей хандл главного окна, в качестве первого аргумента. После выполнения полезной нагрузки исполняем инструкции, замененные на джамп (выделены желтым), и прыгаем обратно, продолжать нормальное исполнение программы.
Скрипт для патча:
MD5:
0ac9594f977896e578815204e5258d42 оригинал
03df6b45dccecf2665a634525cd8d3d4 пропатченный файл
В отладчике найдем, откуда вызывается 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 пропатченный файл