Сохранить/восстановить состояние процесса

Тема в разделе "WASM.NT.KERNEL", создана пользователем x64, 1 авг 2008.

  1. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Привет.
    Хотелось бы коллективно обсудить вот такую идейку.

    Постановка задачи

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

    На начальном этапе нужно, чтобы была возможность сохранять процессы на базе хотя бы вот такого исполняемого файла (без CRT):

    Код (Text):
    1. #include <windows.h>
    2.  
    3. char text[] = "Message text.";
    4. char title[] = "Message title.";
    5.  
    6. int main (...)
    7. {
    8.   HANDLE hFile = CreateFile ("C:\\filename.ext", ...);
    9.   MessageBox (NULL, text, title, MB_ICONINFORMATION);    // в этом месте нужно иметь возможность сохранить состояние процесса
    10.   if (hFile != INVALID_HANDLE_VALUE) CloseHandle (hFile);
    11.   ExitProcess (0);
    12. }
    Т.е. при восстановлении мы должны получить процесс с одним потоком и с окном MеssageBox() на экране, а также как минимум с одним файловым хендлом и несколькими объектами из win32k.sys. На следующим этапе было бы неплохо научиться сохранять Блокнот, при чём в произвольный момент времени. На третьем этапе что-нибудь посложнее, вроде Word, WinAmp или ICQ. На четвёртом этапе нужно уметь сохранять любой процесс, будь то 3D Studio Max, игра "Сталкер", Apache или служба Kaspersky Internet Security (avp.exe).

    Требования

    ОС: Windows XP, Windows Server 2003, Windows Vista и Windows Server 2008.
    Для начала хотя бы x86 освоить.

    Предположительное решение

    Грубо говоря мыслей особых пока нет, за исключением вот такой банальщины:

    1.1. Открываем процесс с необходимыми правами.
    1.2. Останавливаем все потоки.
    1.3. Извлекаем и сохраняем информацию обо всех объектах, которые были созданы, но ещё не удалены процессом к моменту сохранения.
    1.4. Дампим образы всех модулей процесса и запоминаем адреса, по которым они были загружены.

    Восстановление должно бы выглядеть как-то так:

    2.1. Создаём объект-процесс.
    2.2. Подгружаем все модули и заменяем их образы в памяти дампами, сохранёнными ранее.
    2.3. Воссоздаём объекты-потоки и восстанавливаем их контексты и другую информацию.
    2.4. Воссоздаём все объекты, информацию о которых мы сохраняли на шаге 1.3.
    2.5. При обращении к ранее созданным объектам подставлять новые объекты, созданные на предыдущим шаге.

    Проблемы реализации

    Основные проблемы технического плана при реализации я могу выделить вот такие:

    3.1. См. пункт 1.3. Ну, положим, объекты ядра можно извлечь через NtQuerySystemInformation(SystemHandleInformation). Но непонятно как получить объекты GDI и USER, ибо функций пользовательского режима для этого недостаточно, а win32k.sys сплошь и рядом не документирован. В принципе, решение существует. А именно - перехватить в режиме пользователя все функции, которые создают и/или возвращают хендлы. Это весьма трудоёмко, ибо функций этих, мягко говоря, огромное количество, но справиться с этим вполне можно.

    3.2. См. пункт 2.5. Проблема, надеюсь, понятна. Суть её в том, что значения тех же хендлов, сохранённые, например, в локальных переменных или в секции данных, будут отличаться от значений хендлов, которые мы получим в результате восстановления этих объектов. Непонятно, как подставить новые значения в воссозданном процессе. Можно, конечно, делать через тупой перехват в режиме пользователя, но здесь ещё ещё две проблемы. А именно, что придётся перехватывать просто неимоверное кол-во функций, а точнее вообще все, в которые явно или неявно передаются хендлы и уже в перехватчиках заменять старые значения на новые, для этого можно карту создать. А во-вторых, этот способ не будет работать для выделенных блоков памяти. Если мысль анализировать машинный код в перехватчиках ещё до сохранения с целью анализа и поиска того места, куда в итоге будет сохранено возвращённое перехваченной функцией значение. Но думается мне, что метод этот крайне не надёжный и связываться с ним не хотелось бы.

    Вопросы

    4.1. Какой вы видите реализацию этой идеи с технической точки зрения?
    4.2. Какое, по вашему мнению, может быть решение для двух вышеозначенных проблем?
    4.3. Существует ли уже продукт, решающий поставленную задачу? Если да, то поделитесь ссылкой, я ничего похожего не нашёл.
    4.4. Знаете ли вы open-source проекты такого плана или хотя бы контакты тех, кто занимается подобным?

    Сорри, немного сумбурно всё описал, но смысл должен быть понятен.
    Заранее спасибо и надеюсь на продуктивную беседу.
     
  2. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    А что делать, если открытые файлы были изменены (или удалены) между сохранением/восстановлением процесса?
    А что делать, если процесс подразумевает только сингле-инстанс, а при восстановлении уже запущена одна копия этой же программы?
    А что делать, если процесс ждал где-то в начале синхронизации с кем-то другим, и дождался? Или не дождался... Или дожидается, а после восстановления (на следующий день, в другом окружении) - уже и не дождется никогда?
    Имхо, данная задача не разрешима в общем случае, либо разрешима, но для некоторых процессов не имеет смысла. Существует целый ряд процессов, для которых нельзя после восстановления добиться правильного поведения
     
  3. Novi4ek

    Novi4ek New Member

    Публикаций:
    0
    Регистрация:
    3 авг 2007
    Сообщения:
    317
    хехехе, интересно, правда интересно - буквально недавно сам решил такое точно сделать и составил себе примерно точно такой же to-do лист как вы. з.ы. нашел одну книжку, где автор приоткрывает завесу недокументированности над GDI, т.е. он там нашел некие структуры и их таблицы в т.ч. в ядре, которые связаны с объектами gdi (напиши в пм если нужна ссылка на книжку), хотя с др. стороны бродят ведь исходники вин2000 можно там покопаться
     
  4. Novi4ek

    Novi4ek New Member

    Публикаций:
    0
    Регистрация:
    3 авг 2007
    Сообщения:
    317
    З.Ы. без перехвата функций создающих хэндлы имхо никак не обойтись, можно будет попробовать при восстановлении создать для объектов такие же хэндлы какие были раньше, но не всегда это выйдет, так что это если только сэкономить "карту" заменялок хэндлов
     
  5. Novi4ek

    Novi4ek New Member

    Публикаций:
    0
    Регистрация:
    3 авг 2007
    Сообщения:
    317
    Некоторые частные случаи наиболее вероятные можно отрабатывать персонально, конечно нельзя сделать универсальную такую прогу, но можно попробовать сделать почти универсальную
     
  6. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    О, это самые простые вопросы из тех, что можно было бы задать )) Вот я в первом посте посложнее вопросики задал.

    А в чём проблема-то? Ну нет файла и нет, будем тупо возвращать соответствующую ошибку (типа STATUS_INVALID_HANDLE или как там его) при обращении по его хендлу.

    Ничего не делать, зачем что-то делать? Оставим это на совести пользователя. Возможно, не самое удачное решение, т.к. пользователь может не знать об этом нюансе, но ничего лучше пока в голову не приходит.

    Вообще не вижу смысла в решении этих, по сути, мелочных проблем. Опять же - это не наша забота. Наша задача при восстановлении - вернуть процесс в исходное состояние, в том числе и объекты синхронизации, если они были созданы внутри процесса. К каким последствиям приведёт восстановление ранее сохранённого процесса - пусть нас не волнует, нас попросили восстановить точную копию - мы восстановили. И точка.

    А наша задача - не "добиться правильного поведения", это, думается мне, нереально. Нам нужно восстановить точную копию, большего на начальном этапе не требуется.

    Кстати, кому тема реально интересна и кто готов заняться непосредственно реализацией, стучите в icq, пообщаемся. А сейчас нас уже трое единомышленников, не факт, что из этого что-то выйдет, но можно попробовать. Работа сродни написанию sandbox'а, по сути, тут и драйвера фильтрующие, я так чувствую, придётся пописать и другой-разный системный код. Надеюсь, кому-то будет интересно, - пишите!
     
  7. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    А в чем смысл сохранения/восстановления процесса, если "правильного поведения" от оного никто не ждет?
     
  8. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    x64
    Вышло что-то ?..
     
  9. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Я не стал заниматься этим.
    Заказа не было, а на энтузиазме такое не сделаешь.
     
  10. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    трудно представить способ применения
     
  11. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Это ты потому что неподумавши сказал.
    Навскидку, - сохранение игр, в которых оное не предусмотрено.
    Ну и разумеется, безопасность, т.к. технология сходная с "песочницей".
     
  12. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    не, наоборот, я хорошо подумал. в общем случае нельзя восстанавливать процесс, который взаимодействует с другими процессами. то есть процесс не должен использовать скажем внешние COM сервера, службы, именованные пайпы, файлы, к которым могут обращаться другие процессы, сеть. ну то есть, он может это использовать, если оба участника корректно смогут обработать ошибку разрыва соединения или отказа в доступе и если состояние после разрыва и восстановления будет иметь большую ценность, чем просто запуск процесса с нуля. кроме того, некоторые приложения сами пытаются взаимодействовать с другими приложениями например ставят оконные хуки на систему. у меня, например, в всех процессах торчит lingvo hook dll. об этом вы тоже не подумали.
    то есть если бы решение было бы создано, то оно могло бы использоваться для узкого класса процессов на специально подготовленной системе. да, насколько я понимаю, игры часто делаются как, чтобы всё иметь в себе. но это, пожалуй, единственный класс приложений. а в общем, интересные приложения как правило взаимодействуют с другими приложениями.
    подъитоживая, я бы сказал ещё вот что. допустим, что удалось решить массу нетривиальных проблем, которые вы описали в начальном посте, и решение готово. в общем если есть некий процесс, то заранее нельзя сказать, удасться ли его сохранить и восстановить, а некое суждение удасться вынести, если сделать 10-20 попыток сохранений и восстановлений. и не факт, что эта возможность не исчезнет, если модифицировать систему.
     
  13. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    Невозможно.
     
  14. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    думаю задача чисто академическая и полного решение не нужно, а вот например сделать рефлектор на GUI(Влючая манипуляцию битов и всего остального ) ...
     
  15. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Что именно невозможно?
    Какая конкретно из возможных подзадач не имеет решения?
     
  16. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    x64
    Обьекты не живут отдельно от системы, особенно такой как процесс. Придётся состояние всей системы сохранять.
     
  17. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Ясно.
     
  18. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    получается и функции которые меняют состояния объекта тоже.

    ARTmoney чето подобное умеет, но не пробовал.

    Если кого интересует мое мнение, то подход лучше выбрать другой. А именно "воспроизведение" процесса до того момента когда сохранялись. те если возврат всех функций которые могут вернуть "рандомное" значение, придет один и тот же ответ, то результат тоже будет один и тот же. Естественно с такой реализацией тоже куча мароки, то имхо меньше. лишь синхронизация, и выявления какие "рандомные" факторы влияют на процесс. Если коротко мы помещаем процесс в одну и туже среду, и создаем теже события в теже моменты (например событие от клавы ) и в результате раз код процесса на менялся, то и результат будет такой же. Беда в том что надо все записывать.

    не придется, тут вся загвоздка в том что многое не документировано, зная внутреннее устройсво было бы не так сложно сохранить состояние, игры же в конце концов сохраняют, а там тоже куча объектов и различных процессов (не в смысле системных) протекает.
     
  19. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    spa
    Игры сохраняют "изнутри" и на ходу игру не сохраняют, только на паузе.
    Одна из проблем в хендлах - если они сохранены в стеке, в памяти. После сохранения придется создавать все с сохранением номеров.
     
  20. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    valterg
    согласен. хотя тоже решаемо, но имхо стабильней это "воспроизведение", как реплеи в играх. И проблем со стеком не будет