Jump to content

A file editing itself


Azu
 Share

Recommended Posts

Okay, renaming has been accomplished.

Now I am trying to figure out how to get a file to EDIT itself.

I am able to this is a little bit, but in a suboptimal way.

Problem 1: It seems to only work on uncompiled scripts.

Problem 2: I can't figure out how to make it wipe something out; only append to.

I want to have ;<random gibberish>

Inserted somewhere in the file where it won't effect how it runs.

Please tell me how to make it so it can find out whether a comment is there, and if it is, then replace the comment with a new one, rather then appending to it, and if isn't already there, then create it. And if it, by chance, the random comment it comes up with is the same as what's already there, then it will keep making new random ones until it is different. The length of the comment should also be random, and be made different each time. I could do the above 2 myself if I knew how to do the rest.

And also, please tell me how to make it so this will work for compiled scripts also.

This should result in the file having a different checksum every time it is ran, and also a different size.

Link to comment
Share on other sites

I have experimented with this and have discovered some inroads. First if the script is saved but not as a .au3 file, then it will not run. Besides this another idea is to cut and paste script from notepad. If you want a script to write to another script but without pasting from a different source, then you can try to send key presses with {SHIFTDOWN} command. So a dollar sign ($)will be written as {SHIFTDOWN}4{SHIFTUP}. This way a script can be generated without recognition of many standard commands. 4 becomes $, " becomes 2 etc... Then of course you have to save the result, with an appropriate name. This isn't quite what you are asking for, but you can delete the original if the new version is better. Automate this too. I'm not sure if this is useful.

Edited by czardas
Link to comment
Share on other sites

I have experimented with this and have discovered some inroads. First if the script is saved but not as a .au3 file, then it will not run. Besides this another idea is to cut and paste script from notepad. If you want a script to write to another script but without pasting from a different source, then you can try to send key presses with {SHIFTDOWN} command. So a dollar sign ($)will be written as {SHIFTDOWN}4{SHIFTUP}. This way a script can be generated without recognition of many standard commands. 4 becomes $, " becomes 2 etc... Then of course you have to save the result, with an appropriate name.

Hi, thanks for the reply.

I don't understand how the script would edit itself in notepad though. Would you please explain?

I was hoping there was some command I missed, like a fileeditline or something like that.

And it would be really great if it would work with it in exe form also rather then only working uncompiled. :)

Edited by Azu
Link to comment
Share on other sites

I think that you need two parralel scripts, one updating the other. At key moments one script would become active whilst the other receives new arguments. Perhaps it would make more sense if the script were to create newer and more advanced versions of itself, whilst discarding older versions, a kind of evolutionary approach. Keeping an original copy would be wise. This method is not too clear to me, but I think that it is worth some consideration. I am not familiar enough with AutoIt to give examples of how you would do this. one thing is for sure though. You will have to guide the script through the evolutionary process. You can't get more out than you put in (I think).

Edited by czardas
Link to comment
Share on other sites

Here is some code that I dug up from this topic - Exe Binder. It will allow you to change data at the end of an exe, affecting it in no way.

CODE
#include <GUIConstants.au3>

Opt("GUIResizeMode", 1)
Opt("GUIOnEventMode", 1)

$gui = GUICreate("Exe Binder", 500, 400)
$exe_input = GUICtrlCreateInput("", 10, 10, 400, 20)
$browse_btn = GUICtrlCreateButton("Browse", 420, 10, 70, 20, $BS_DEFPUSHBUTTON)
$edit = GUICtrlCreateEdit("", 10, 40, 480, 320)
$save_btn = GUICtrlCreateButton("Save", 10, 370, 70, 20)

$selected = False
$exe = ""
$data = ""

GUICtrlSetOnEvent($browse_btn, "_EventHandler")
GUICtrlSetOnEvent($save_btn, "_EventHandler")
GUISetOnEvent($GUI_EVENT_CLOSE, "_EventHandler", $gui)

GUISetState()

While 1
   ; reduce memory
   DllCall("psapi.dll", "int", "EmptyWorkingSet", "long", -1)
   Sleep(5000)
Wend

Func _EventHandler()
   Switch @GUI_CtrlId
      Case $GUI_EVENT_CLOSE
         Exit
      Case $browse_btn
         $exe = FileOpenDialog("Select File", "", "Executable Files (*.exe)", 1)
         If @error Then Return
         $data = _BindLoad($exe)
         If @error Then Return mError("Read error! The program is not accessable.")
         $selected = True
         GUICtrlSetData($exe_input, $exe)
         GUICtrlSetData($edit, _BindRead($data))
      Case $save_btn
         If $selected and MsgBox(4, "Exe Binder", "Are you sure you want to save?") = 6 Then
            _BindSave($exe, _BindSet($data, GUICtrlRead($edit)))
            If @error Then mError("Write error! The program may be in use.")
         EndIf
   EndSwitch
EndFunc

Func mError( $sText, $iFatal = 0, $sTitle = "Error", $iOpt = 0 )
   Local $ret = MsgBox(48 + 4096 + 262144 + $iOpt, $sTitle, $sText)
   If $iFatal Then Exit
   Return $ret
EndFunc

Func _BindLoad( $sEXE )
   Local $sData = FileRead($sEXE)
   If @error Then Return SetError(1)
   If not _BindExists($sData) Then $sData = _BindCreate($sData)
   Return $sData
EndFunc

Func _BindSave( $sEXE, $sData )
   Local $hFile = FileOpen($sEXE, 2)
   If $hFile = -1 Then Return SetError(1)
   FileWrite($hFile, $sData)
   FileClose($hFile)
   Return 1
EndFunc

Func _BindExists( $sData )
   Return StringLen($sData) - StringInStr($sData, Chr(190), 0, -1) <= 16
EndFunc

Func _BindCreate( $sData )
   Return $sData & Chr(190) & StringLen($sData)
EndFunc

Func _BindSet( $sData, $sValue )
   Local $iSize = StringRight($sData, StringLen($sData) - StringInStr($sData, Chr(190), 0, -1))
   Return StringLeft($sData, $iSize) & $sValue & Chr(190) & $iSize
EndFunc

Func _BindRead( $sData )
   Local $iSize = StringRight($sData, StringLen($sData) - StringInStr($sData, Chr(190), 0, -1))
   Return StringTrimLeft(StringTrimRight($sData, StringLen($iSize) + 1), $iSize)
EndFunc

Func _BindClear( $sData )
   Return _BindSet($sData, "")
EndFunc

Func _BindRemove( $sData )
   Local $iSize = StringRight($sData, StringLen($sData) - StringInStr($sData, Chr(190), 0, -1))
   Return StringLeft($sData, $iSize)
EndFunc
Make sure to read that last post:

Found a bug, now it will give an error when you try to open an executable that is already running, which means self-modifying executables are not probable this way (please, someone prove me wrong!)

Again, I would really enjoy it if someone proved me wrong. It would be sweet if you made a stand-alone program that updates itself! :)

I assume this is for a game, no?

Edited by erifash
Link to comment
Share on other sites

Why? Programs should be written to be the final version, not to edit themselves. Why a comment, just a test? In compiled, the comments make no difference so what is the point?

If, for example, you wanted to make it harder for other programs to detect your's based on checksums/file size.

I think an easy way to get around the "can't be able already running" limitation is this;

Have the file make another file adding some data of where it's at, and what it does is close the main file, and then the editing stuff, and then run the file again. When the main file is ran, it checks to see if the spawned file exists, and if it does, it checks the data at the end of it, so it can tell where it was at, and resume to that point, so to the user it won't look like it closed to begin with. And then delete the spawn file.

Of course, the second to the last stuff I mentioned wouldn't be necessary for this, unless you wanted it to do it in the middle of it's execution, and seamlessly pick back up where it left off.

I'm going to try your code erifash and see if I can get it to accomplish what I'm aiming for. Thanks for your contribution. :)

Oh BTW, another thing this could be used for, is auto updating. And storing settings inside of itself.

Edited by Azu
Link to comment
Share on other sites

I beg to differ. There is talk of a trend towards giving computers more individual personalities. One reason is to make them less vunerable to attacks. Attacking a paranoid operating system would be different from attacking a bolshy one. Viruses would have to do something similar to a flu jumping species. Not unheard of, but still less common. This was intended as a reply to Icekirby1's comment.

Edited by czardas
Link to comment
Share on other sites

Okay, renaming has been accomplished.

Now I am trying to figure out how to get a file to EDIT itself.

I am able to this is a little bit, but in a suboptimal way.

Problem 1: It seems to only work on uncompiled scripts.

Problem 2: I can't figure out how to make it wipe something out; only append to.

I want to have ;<random gibberish>

Inserted somewhere in the file where it won't effect how it runs.

Please tell me how to make it so it can find out whether a comment is there, and if it is, then replace the comment with a new one, rather then appending to it, and if isn't already there, then create it. And if it, by chance, the random comment it comes up with is the same as what's already there, then it will keep making new random ones until it is different. The length of the comment should also be random, and be made different each time. I could do the above 2 myself if I knew how to do the rest.

And also, please tell me how to make it so this will work for compiled scripts also.

This should result in the file having a different checksum every time it is ran, and also a different size.

Please indicate that, other than viruses, why you would want to have a self modifying .EXE file that has a changing checksum?
Link to comment
Share on other sites

  • Moderators

Please indicate that, other than viruses, why you would want to have a self modifying .EXE file that has a changing checksum?

Are you asking the forum in general, or specifically the thread starters intentions?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Anything that you want to make harder to detect.

Off the top of my head;

Emulation software

Bots

Anti-DRM software

Stuff you want to be harder for viruses to mess with

E.G. could be useful for anti virus programs themselves

My personal reason, though, is seeing what can be achieved in AutoIt.

Edited by Azu
Link to comment
Share on other sites

I'm going to try your code erifash and see if I can get it to accomplish what I'm aiming for. Thanks for your contribution. :P

Oh BTW, another thing this could be used for, is auto updating. And storing settings inside of itself.

Thanks. My original idea for that was to have a program save settings inside itself. That way it is completely portable and you don't have to worry about registry stuff or extra files! :)
Link to comment
Share on other sites

Thanks. My original idea for that was to have a program save settings inside itself. That way it is completely portable and you don't have to worry about registry stuff or extra files! :)

What happens if there is a corrupt setting somehow? That instance is completely unusable and all settings are lost because the user can't wipe out a file or registry key to reset the settings. What happens if you need to migrate to a newer version of the program? Without doing extensive work writing migration code, again, settings will be lost.
Link to comment
Share on other sites

What happens if there is a corrupt setting somehow? That instance is completely unusable and all settings are lost because the user can't wipe out a file or registry key to reset the settings. What happens if you need to migrate to a newer version of the program? Without doing extensive work writing migration code, again, settings will be lost.

I see your point. I haven't thought about that! :)
Link to comment
Share on other sites

What happens if there is a corrupt setting somehow? That instance is completely unusable and all settings are lost because the user can't wipe out a file or registry key to reset the settings. What happens if you need to migrate to a newer version of the program? Without doing extensive work writing migration code, again, settings will be lost.

Why would it get corrupted?

Unless the power went out right at the exact instant when it was in the middle of saving..

:)

Link to comment
Share on other sites

Why would it get corrupted?

Unless the power went out right at the exact instant when it was in the middle of saving..

:)

There are any number of reasons it could get corrupted ranging from physical problems such as hardware errors to power failure. It could always be the result of human error with a coding problem. Imagine a simple little mistake in saving or restoring a setting making an executable completely uselss.
Link to comment
Share on other sites

That's why you should take backups. Because you do take backups of your registry right :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...