Haii
I made this tutorial earlier and saw that I didn't post it yet, so here it is.
NOTE: Invoking VB.NET applications may not work all of the time (has no entrypoint in certain cases)! Invoking a C# application usually (there are exceptions, rarely) works.
Let's get started. Things that you'll need:
- VB.NET Compiler (Visual Studio for example)
- Know a tiny little of the .NET language Visual Basic
- And all the obvious items, computer etc.
Put a textbox on the form, and set the '(Name)' property to "txtLinkToFile":
Put two buttons on the form, and make it (kinda) look like this:
Now double click at the Browse button ()
Now we'll make an OpenFileDialog, to select the file that needs to be encrypted.
Follow this little gif:
The code:
Dim d As New OpenFileDialog
If d.ShowDialog = Windows.Forms.DialogResult.OK Then txtLinkToFile.Text = d.FileName
What it does, is make a new OpenFileDialog, open it, and checks if the user presses OK after selecting a file in the OpenFileDialog. If the user has pressed OK, the filename of the selected file will be in the textbox.
Now double click the Crypt! button ()
We need to encrypt the data, and decrypt it when the program runs. So here's what we do: We take an RC4 function (You can take other encryptions functions as well!) , and paste it outside a sub.
The RC4 function:
Private Shared Function RC4EncryptDecrypt(ByVal Input As Byte(), ByVal _Key As String) As Byte()
Dim Key As Byte() = System.Text.Encoding.ASCII.GetBytes(_Key)
Dim i, j, swap As UInteger
Dim s As UInteger() = New UInteger(255) {}
Dim Output As Byte() = New Byte(Input.Length - 1) {}
For i = 0 To 255
s(i) = i
Next
For i = 0 To 255
j = (j + Key(i Mod Key.Length) + s(i)) And 255
swap = s(i)
s(i) = s(j)
s(j) = swap
Next
i = 0 : j = 0
For c = 0 To Output.Length - 1
i = (i + 1) And 255
j = (j + s(i)) And 255
swap = s(i)
s(i) = s(j)
s(j) = swap
Output(c) = Input(c) Xor s((s(i) + s(j)) And 255)
Next
Return Output
End Function
Then we go back to the crypting button ("Crypt!") and make a ResourceWriter. The ResourceWriter will create a resource file for our project, which will contain the encrypted file.
We do it like this:
Dim w As New Resources.ResourceWriter("res.resources") w.AddResource("file", RC4EncryptDecrypt(IO.File.ReadAllBytes(txtLinkToFile.Text), "CaptainBriKEY"))
w.Close()
So we make the ResourceWriter,
read all the bytes of the file-to-be-encrypted,
encrypt the bytes with our RC4 function,
and add it as a resource!
Then we close the ResourceWriter, which will (when closing) add the file to the resource-file.
How it should look like at this moment:
Next up is setting up the compiler parameters. Quite easy, follow the steps:
We make a CompilerParameters' variable:
Dim p As New CodeDom.Compiler.CompilerParameters()
And we add these options:
p.GenerateExecutable = True p.OutputAssembly = "encrypted.exe"
p.ReferencedAssemblies.Add("System.dll")
p.EmbeddedResources.Add("res.resources")
GenerateExecutable => Makes sure it does not generate any DLL file.
OutputAssembly => This is the path your executable will be generated (compiled) to.
ReferencedAssemblied.Add => Adds the main DLL (System.dll). It's required to run the application (& compile it)
EmbeddedResources.Add => Adds the resource to the executable when compiled with these parameters.
So now we're done with the parameters, we add a source to the resources.
Press CTRL+ALT+L to open up the Solution Explorer. Right click at your projects name and click at "Properties".
From the tab at the left, choose "Resources":
Then click "Add Resource" and after that; "Add New Text File".
Enter the name "Source":
Then paste this code inside of it:
Imports System
Module CaptainBri
Sub Main()
Dim m As New Resources.ResourceManager("res", System.Reflection.Assembly.GetExecutingAssembly())
Dim b As Byte() = RC4EncryptDecrypt(DirectCast(m.GetObject("file"), Byte()), "CaptainBriKEY")
m.ReleaseAllResources()
System.Reflection.Assembly.Load(.EntryPoint.Invoke(Nothing, Nothing)
Console.WriteLine("Yaw, we ran your .NET executable!")
Console.Read()
End Sub
Public Function RC4EncryptDecrypt(ByVal Input As Byte(), ByVal _Key As String) As Byte()
Dim Key As Byte() = System.Text.Encoding.ASCII.GetBytes(_Key)
Dim i, j, swap As UInteger
Dim s As UInteger() = New UInteger(255) {}
Dim Output As Byte() = New Byte(Input.Length - 1) {}
For i = 0 To 255
s(i) = i
Next
For i = 0 To 255
j = (j + Key(i Mod Key.Length) + s(i)) And 255
swap = s(i)
s(i) = s(j)
s(j) = swap
Next
i = 0 : j = 0
For c As Integer = 0 To Output.Length - 1
i = (i + 1) And 255
j = (j + s(i)) And 255
swap = s(i)
s(i) = s(j)
s(j) = swap
Output(c) = Input(c) Xor s((s(i) + s(j)) And 255)
Next
Return Output
End Function
End Module
So now all is left to do, is compile the source! We do that with a VBCodeProvider, like this:
Dim r As CodeDom.Compiler.CompilerResults = New VBCodeProvider().CompileAssemblyFromSource(p, My.Resources.Source)
Then we delete the resources file:
IO.File.Delete("res.resources");
After that, we check for any errors. We loop through all the errors and show a messagebox for each error. If there are no errors, it shows none, because it
skips the for-each loop.
The Code:
For Each err As CodeDom.Compiler.CompilerError In r.Errors
MessageBox.Show(err.ToString())
Next
That's about it! So after this little tutorial, your source looks like this:
And here's a little video:
Extra thing: To disable the console window, make it a Windows Application by specifieing the compiler-parameter "target".
You add this parameter to the compileroptions:
p.CompilerOptions += "/t:winexe"
For the ones who'd like to know: By setting the parameter /target (or /t) to "winexe", it changes the subsystem from 0x002 to 0x003 which is a non-console executable.
However 0x002 is a console executable. (Check out ILDASM for the ones that like to know more about this)
So your code would look like this:
Bearbeitet von Mr_NiceGuy, 31 January 2013 - 10:35 Uhr.