осу! это популярная ритм-игра, написанная на .Net C #. Я его большой поклонник. Я ценю невероятную работу всего сообщества. Есть люди, которые создают сторонние инструменты, чтобы использовать наш игровой опыт и достичь чего-то невозможного с помощью простой игры.

Однако из-за закрытого процесса разработки независимые разработчики не могут получить доступ к подробным реализациям игровой программы. Я надеюсь, что эта серия статей поможет вам разобраться в принципах ОСУ! двоичные файлы и создавать лучшие приложения на благо сообщества. Поэтому я ожидаю, что вы знакомы с объектно-ориентированными языками программирования и имеете опыт разработки программного обеспечения, иначе было бы больно понимать мои слова.

Для справки, я не собираюсь реконструировать осу! программа. Вся цель этой серии - помочь вам понять, как работает osu! работает, раскрывая некоторые из его внутренних реализаций. Написание статьи о процессе обратного проектирования позволит вам узнать о нем больше самостоятельно, поэтому я не получу много вопросов о том, как я это сделал. Я также не хотел бы, чтобы кто-то делал крэк из игры, поэтому я не буду писать ничего ни об изменении программы, ни об обмане.

Деобфускация osu! .Exe

В целях безопасности osu! .Exe запутывается на уровне .Net IL. Это означает, что если вы попытаетесь восстановить исходный код из .Net IL, вы получите беспорядочные имена идентификаторов, а все строковые константы будут скрыты в большом запутанном двоичном объекте.

Следовательно, мы должны деобфускировать его, прежде чем мы действительно сможем взглянуть на код. Я выбираю de4dot, чтобы делать эту грязную работу. Вы можете загрузить последнюю версию или использовать следующую команду git для клонирования проекта с его подмодулями.

git clone --recursive https://github.com/0xd4d/de4dot.git

Откройте файл проекта de4dot.sln с помощью Visual Studio. Мы должны исправить код, чтобы обойти некоторые фатальные ошибки, которые добавил обфускатор, чтобы не допустить его деобфускации. Выполните поиск по всему решению, чтобы найти «Метод был удален, на который все еще ссылается этот модуль» (без кавычек), и замените строку на

return 0;

Теперь вы можете его скомпилировать. После этого перетащите osu! .Exe на скомпилированный de4dot.exe, чтобы сгенерировать деобфусцированный файл osu! -Cleaned.exe.

Восстановить Raw C # из .Net IL

Теперь нам нужно декомпилировать программу, чтобы преобразовать двоичные файлы .Net IL в необработанный код C #. Я выбираю Telerik’s JustDecompile, чтобы выполнить эту работу. Альтернативы - Red Gate’s Reflector и ILSpy. Просто загрузите osu! -Cleaned.exe, и вы увидите читаемый исходный код. В JustDecompile вы можете экспортировать сгенерированный код в проект Visual Studio, щелкнув правой кнопкой мыши загруженную сборку и выбрав Создать проект…. Затем вы можете открыть проект в Visual Studio.

Примечание. Не существует идеального деобфускатора или декомпилятора, который создает компилируемый исходный код без каких-либо модификаций, поэтому не ожидайте, что сгенерированный код будет компилируемым сам по себе. Тот, который я создал, содержит более 4000 ошибок по всему проекту.

Однако компьютерные программы не могут автоматически определять все исходные имена переменных. Большинство имен, которые вы видите, сгенерированы в соответствии с их типами и использованием, если только они не являются перечислениями. К счастью, на этот раз мы легко можем распознать строковые константы, что очень поможет нам понять код.

Общий подход к анализу кода

Прежде чем я проанализирую конкретные реализации в следующих статьях, я расскажу вам, как выполнять эту работу, чтобы вы могли делать это самостоятельно.

Для начала нужна удобная среда программирования. Что наиболее важно, вам потребуются инструменты для поиска строковых констант, изменения имен идентификаторов, определения местоположения и поиска всех ссылок для идентификатора. Я рекомендую использовать Visual Studio с Telerik’s JustCode, который предоставляет богатый набор инструментов, включая некоторые полезные функции рефакторинга, которые помогут вам с необработанным кодом. Однако это не является обязательным требованием, поскольку это коммерческий продукт, и у вас могут быть замены или собственные средства для этого. Если ты сможешь дойти так далеко, я верю, что сможешь.

Чтобы изучить исходный код, не просматривайте каждый файл, так как их сотни. Попробуйте подумать о функции в osu! вы хотите узнать, а затем подумайте о строковой константе, тесно связанной с ней. Затем используйте функцию поиска, чтобы найти его по всему решению.

Например, я хотел бы посмотреть, как работает osu! анализирует свой файл конфигурации. Сначала я знаю, что файл называется «osu! .Cfg», поэтому могу найти его.

Выберите «Найти все», чтобы перечислить все вхождения, и вот результат, который нам нужен. Из структуры кода и с помощью всех строковых констант мы можем легко выяснить, как используются многие из этих идентификаторов. Например, поскольку мы видим, что шаблон представляет собой несколько назначений, он подразумевает, что метод считывает значения из файла конфигурации и присваивает их статическим переменным, что означает, что метод используется в процессе инициализации.

На собственном опыте могу сказать

Class203.smethod_14(String field, int defaultValue, int min, int max)

Метод читает указанное поле как целое число с предоставленным значением по умолчанию и диапазоном проверки. В этом случае я могу присвоить ему новое имя, чтобы легко узнать его в следующий раз. Для этого с установленным JustCode мне просто нужно переместить курсор на идентификатор и нажать F2, чтобы ввести новое имя, а затем нажать клавишу ВВОД, чтобы подтвердить каждое появление в проекте. Чтобы переименовать его параметры, нажмите F12, чтобы перейти к определению, и повторите описанный выше метод, чтобы переименовать их.

Из кода мы знаем, что Class1164 управляет громкостью звука. Чтобы узнать, какие другие методы используют эти значения, используйте Shift-F12 для поиска по проекту и перечисления всех вхождений. Вы найдете то, что ищете, если у вас будет терпение копаться в коде.

Этот общий подход применим почти ко всем ситуациям, ближе или дальше вы найдете точку входа, чтобы откопать. В следующем посте я начну анализировать, как система подачи оценок взаимодействует с osu! сервер.