Ребят, извините что вмешиваюсь, но просмотрел тему и нифига не понял, о чем вы говорите. Я, конечно, глобально не в курсе, т.к. даже не знаю, что из себя все эти игры представляют... но родилось все же пару мыслей. И по такому случаю, не расскажете ли в трех словах, что конкретно требуется сделать? Пока я понял, что надо заставить яп. прогу понимать анг., рус. и др.
Это не то случаем? ->
Спойлер
Если под автором имеется ввиду непосредственный автор программы, то ему нужно просто в функции CreateFont() использовать нужный параметр, определяющий Charset. А если вы хотите исправить уже откомпилированный файл, то нужно найти место в программе, где вызывается функция CreateFont(), и подредактировать место, где определяются параметры для этой функции. Для этого лучше использовать дизассемблер и шестнацетиричный редактор. Дело в том, что у функции CreateFont очень много параметров, и для втоматического исправления кода нужен достаточно надежный анализатор этого кода. На создание такого анализатора вы потратите уйму времени, а на анализ кода при помощи дизассемлера требуется от силы полчасика.
Итак, приступим к изучению программы.
1. Если программа упакована каким либо пакером, то нужно её распаковать, вернее - это уже отдельная тема (взлом упакованой программы). А если нет, как в случае с антиспаем, то переходим к следующему шагу.
2. Нужно найти библиотеки импорта. Для этого можно использовать depends.exe от microsotf. Эта программа показывает все библиотеки и импортируемые программой функции из этих библиотек (в упакованном виде весит примерно 380 Кб, могу выслать). Нас интересует библиотека GDI32.DLL и функция CreateFont().
3. Теперь о функциях API создания шрифта. Это могут быть
CreateFontA() / CreateFontW()
CreateFontIndirectA() / CreateFontIndirectW()
CreateFontIndirectExA() / CreateFontIndirectExW()
Поясню: CreateFontA() и CreateFontW() это разные реализации одной и той же функции, т.е. они выполняют одну и ту же работу, только отличаются типом параметров. CreateFontA() в качестве строкового параметра принимает ANSI строки, а CreateFontW() - строки в Юникоде. С остальными функциями - так же.
У функции CreateFont() очень много параметров-14, а все остальные принимают только указатель на структуру, в которой уже собраны все эти парамеры.С антиспаем - используется CreateFontA().
4. Теперь про CreateFontA().
BOOL CreateFont(int nHeight, // определяет высоту шрифта в логических единицах
int nWidth, // определяет ширину шрифта, (обычно равен 0,ширина по умолчанию)
int nEscapement, // наклон в десятых градуса базовой линии текста (обычно 0)
int nOrientation, // наклон в десятых градуса базовой линии символа (обычно 0)
int nWeight, // вес символа (жирность) (обычно 400)
BYTE bItalic, // курсив (обычно 0)
BYTE bUnderline, // подчеркивание (обычно 0)
BYTE cStrikeOut, // зачеркивание (обычно 0)
BYTE nCharSet, // определяет национальность шрифта (то что нам нужно)
BYTE nOutPrecision, // без комментариев (можно 0)
BYTE nClipPrecision, // без комментариев (можно 0)
BYTE nQuality, // без комментариев (можно 0)
BYTE nPitchAndFamily, // без комментариев (можно 0)
LPCTSTR lpszFacename);// название шрифра (например "Arial")
5. Нашли нужную функцию в импорте - теперь нужно найти место в программе, где она вызывается, проанализировать её парамеры, и попытаться исправить nCharSet. Здесь нужен какой либо дизассемблер. В антиспае - nCharSet равен 0, что соответсвует америке. А нам нужен RUSSIAN_CHARSET, его значение 204 или 0CCh. Как исправить? Для передачи параметров функции используется стек, первым с стек помещается последний параметр функции (lpszFacename), последним - первый (nHeight), а затем call [адрес в таблице импорта].
Трудность исправления значений параметров заключается в том, что много нулевых параметров и оптимизатор кода при компиляции программы сделал следующим образом: обнулил какой то регистр (например ebx), а затем, когда требуется записать в стек 0, выполняется команда push ebx. Эта команда занимает только один байт. Команда push 204 занимает уже два байта, и просто так ей не вставишь (нет места). Я же сделал так: nPitchAndFamily не был нулевым, и на него тратилось два байта, я его обнулил (заменил на push ebx), а освободившийся байт использовал для nCharSet. При этом все параметры между ними сместились на один байт. Это я проделал в двух местах. Для этого нужен шестнадцатиричный редактор. И все - антиспай у меня стал показывать нормальный текст.
Всего хорошего. На описание того что я сделал потребовалось больше времени, чем на сам патч.