2011-05-24 3 views
2

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

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

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

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

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

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

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

+0

Вы пытаетесь изменить подпись на диске в памяти? –

+0

Пришло ли вам в голову, что исполняемый файл может использовать эти байты? –

+0

@Seth: На диске, как еще он будет сохраняться после завершения процесса? @Neil: Полностью, вот почему я спрашиваю, могу ли я «зарезервировать» эти байты или указать, где они написаны при компиляции? – amireh

ответ

1

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


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

#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) 
+0

Я только что открыл игру игры World of Warcraft - не пусковую установку, в шестнадцатеричном редакторе, и на самом деле это версия, встроенная там. Таким образом, я считаю, что ваш ответ - это путь, хотя мое требование состояло в том, чтобы не испортить сам код приложения, но вместо этого сохраните его в пусковой установке. – amireh

+0

@amireh: Смотрите мое редактирование, я нашел хорошее решение для Visual Studio. – Xeo

3

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

+0

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

+1

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

+0

Определенно. По правде говоря, я могу просто сохранить его как обычный текст, ведь если они будут с ним конфликтовать, клиент не будет проверен, и в конечном итоге они будут отсутствовать на патчах, а сохранение его в виде простого текста упростит исправить фактически. Мне просто интересно, как это делают другие, как пусковые установки Blizzard. – amireh

2

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

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

1

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

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

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

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

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

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

+0

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

Смежные вопросы