Создание версий исполняемого файла и его изменение во время выполнения - PullRequest
2 голосов
/ 25 мая 2011

Я пытаюсь подписать первые 32 байта моего скомпилированного исполняемого файла подписью версии, скажем «1.2.0», и мне нужно изменить эту подпись в runtime , помня, что :

  • это будет сделано самим исполняемым файлом
  • исполняемый файл находится на стороне клиента, что означает, что перекомпиляция невозможна
  • использование внешнего файла для отслеживания версии вместо кодирования его в самом двоичном файле также не вариант
  • решение должно быть независимым от платформы; Мне известно, что Windows / VC позволяет вам создавать версии исполняемого файла с использованием ресурса .rc, но я не знаю эквивалента для Mac (может быть, Info.plist?) И Linux

Решение в моей голове состояло в том, чтобы написать сигнатуру версии в первых или последних 32 байтах двоичного файла (что я пока не выяснил , как это сделать ), а затем я изменю эти байты, когда мне нужно. К сожалению, это не так просто, поскольку я пытаюсь изменить тот же двоичный файл, который я выполняю.

Если вы знаете, как я могу это сделать, или о более чистом / общепринятом решении этой проблемы, я был бы очень признателен. FWIW, приложение представляет собой патчер / лаунчер для игры; Я решил закодировать версию в самом патчере вместо исполняемого файла игры, поскольку хотел бы, чтобы он был автономным и не зависел от цели.

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

Я бы предпочел использовать внешний файл для хранения подписи и изменять его при каждом обновлении, но я не понимаю, как я могу защититься от подделки пользователем этого файла: если они испортят номера версий, как я могу определить, какую версию я использую?

Update2 : Спасибо за все ваши ответы и комментарии, по правде говоря, есть два способа сделать это: либо использовать внешний ресурс для отслеживания версии, либо встроить его в двоичный файл основного приложения. Я мог выбрать только 1 ответ на SO, поэтому я сделал тот, с которым я иду, хотя это не единственный. : -)

Ответы [ 4 ]

3 голосов
/ 25 мая 2011

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

2 голосов
/ 25 мая 2011

Это будет немного сложным по ряду причин.Во-первых, запись в первые N байтов двоичного файла, вероятно, наступит на информацию заголовка двоичного файла, которая используется загрузчиком программы, чтобы определить, где в файле находятся сегменты кода и данных и т. Д.Это будет по-разному на разных платформах (см. Сравнение ELF и форматов исполняемых файлов ) - существует множество различных стандартов двоичного формата.

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

1 голос
/ 25 мая 2011

Если ваше приложение предназначено для исправления игры, почему бы не вставить туда версию, пока вы в ней?Вы можете использовать строку, такую ​​как @Juliano, показывать и изменять ее из патчера, пока игра не запущена - что должно быть в случае, если вы в любом случае исправляете в данный момент.: P


Редактировать : Если вы работаете с Visual Studio, действительно легко внедрить такую ​​строку в исполняемый файл с #pragma comment, в соответствии с эта страница MSDN :

#pragma comment(user, "Version: 1.4.1")

Поскольку второй аргумент является простым строковым литералом, его можно объединить, и я получу версию в простом #define:

// somehwere
#define MY_EXE_VERSION "1.4.1"
// somewhere else
#pragma comment(user, "Version: " MY_EXE_VERSION)
1 голос
/ 25 мая 2011

Я дам несколько идей о том, как это сделать.

Я думаю, что невозможно изменить некоторые произвольные байты в исполняемом файле без побочных эффектов. Чтобы преодолеть это, я бы создал некоторую строку в вашем исходном коде, например:

char *Version = "Version: AA.BB.CC";

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

Поскольку файл используется (работает), вам нужно запустить внешнюю программу, которая сделает это. После изменения файла эта внешняя программа может перезапустить исходное приложение.

Версия будет храниться в вашем двоичном коде в некоторой части. Это полезно? Как вы получите номер версии?

...