Pull to refresh

Создание самомодифицирующихся программ

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

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

Для чего это все нужно?

1) Циклическое усовершенствование программы или ее алгоритма. Программа модифицирует себя, решает некоторую эталонную задачу и оценивает результат. На основе результата принимается решение о новом цикле модификации.
2) В случае вирусной программы такой подход может использоваться для модификации своего кода при переходе на новую машину и обхода таким образом антивирусов. При этом можно как менять уже существующий код, так и добавлять новый, который не несет смысловой нагрузки.
3) Программа может запоминать конкретного пользователя и подстраиваться под него. Например, можно экспериментировать с цветами и формой окна и спрашивать пользователя о приемлемом для него варианте или анализировать наиболее часто используемые пользователем функции программы. В случае оператора типа switch() может иметь смысл наиболее часто используемые варианты выбора передвигать вверх для того, что бы пытаться избежать проверок тех вариантов выбора, которые практически не используются.
4) Программа может попытаться найти в сети Интернет исходный код нового решения какой-то из своих функций, загрузить его, соответствующим образом изменить свой код с учетом новой реализации данной функции и попробовать откомпилировать и проверить работу новой копии. Таким образом можно создать программу, которая со временем будет сама находить лучшие решения проблем и использовать их в своей роботе. Такая программа будет идти в ногу со временем без постоянного участия своего разработчика(это пока область фантастики, к сожалению =( ).

Пример технической реализации данного подхода на C#

В случае наличия платформы .NET на машине пользователя добавлять компилятор в ресурсы не обязательно, поскольку он поставляется из самим .NET.

Код программы имеет следующий вид:

using System;
using System.Windows.Forms;
using System.Resources;
namespace SMC
{
static class Program
{
[STAThread]
static void Main()
{
// Достаем из ресурсов собственный код
ResourceManager rm = new ResourceManager("my", System.Reflection.Assembly.GetExecutingAssembly());
string code = rm.GetString("Program");
// Проверяем версию программы
if (code.Substring(0, 7) != "//mark0")
{
MessageBox.Show("I am the first program");
// Если работает родительская программа - добавляем метку в начало кода
code = @"//mark0" + Environment.NewLine + code;
// Создаем файл ресурсов
ResXResourceWriter rw = new ResXResourceWriter(@"c:\my.resx");
rw.AddResource("Program", code);
rw.Close();
// Создаем файл с исходным кодом
System.IO.File.WriteAllText(@"c:\Program.cs", code);
// Преобразовываем файл ресурсов из .resx в .resources
System.Diagnostics.Process proc1 = new System.Diagnostics.Process();
proc1.StartInfo.FileName = "cmd";
proc1.StartInfo.Arguments = @"/C " + "\"C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0A\\bin\\ResGen.exe\" c:\\my.resx c:\\my.resources";
proc1.StartInfo.UseShellExecute = false;
proc1.StartInfo.RedirectStandardOutput = true;
proc1.StartInfo.CreateNoWindow = true;
proc1.Start();
proc1.WaitForExit();
// Компилируем новую версию программы
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "cmd";
proc.StartInfo.Arguments = @"/C " + @"C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /target:winexe /resource:c:\my.resources /nologo /warn:0 /out:c:\myprog.exe c:\Program.cs";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.WaitForExit();
}
else
{
MessageBox.Show("I am the second program");
}
}
}
}


Хотелось бы услышать конструктивную критику и ссылки на источники, где такой подход применяется, если таковые имеются. Всем спасибо за внимание.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.