I am storing all of the bytes of an external .exe file, and then re-writing them to another .exe file that I am currently creating with FileOutputStream/BufferedOutputStream.
The bytes are written fine, and the second program is created in the location of my choice, but when I come to run the file, it says it's not a valid .exe file or not a valid 32/64bit application.
I'm guessing because it's not packed and generated properly.
How would I make it so it's an executable file and works the same as the first one?
p.s I can't use any copying of the file, because eventually I'm going to be encrypting the bytes and writing them to the file, but I still want it to be usable.
If all the bytes are identical it will run. If the original file runs and the copy doesn't then some of the bytes have to be different. It has nothing to do with packing.
Maybe you are using a byte variable to store the read data. Don't do that. Just use int. If you don't use byte variables correctly you can run into problems due to automatic sign extension.
This works fine for me
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("a.exe"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("b.exe"));
int data = in.read();
while(data >= 0) {
out.write(data);
data = in.read();
}
in.close();
out.close();
}
}
Related
I am getting issue when trying to read and write to the same file using RandomAcessFile.
I am reading block of 16 bytes from a file and write them in the same file on given position (eg. 256-th).
The problem is on ra.write(b) line. When the following line is execute i got a message on the text editor Kate (I am using Linux Manjaro) saying:
The file /home/mite/IdeaProjects/IspitJuni2015/dat.txt was opened with UTF-8 encoding but contained invalid characters.
It is set to read-only mode, as saving might destroy its content.
Either reopen the file with the correct encoding chosen or enable the read-write mode again in the tools menu to be able to edit it.
and it turns on read-only mode.
Also I tried manually to uncheck the read-only permission in Kate but it's not working either. What seems to be the problem?
public static byte[] read(long i) throws IOException{
File in = new File("./dat.txt");
RandomAccessFile ra = new RandomAccessFile(in,"rw");
byte[] readObj= new byte[16];
if (i>in.length()/16)
{
return null;
}
ra.seek(i*16);
ra.read(readObj);
ra.close();
return readObj;
}
public static void write(long i, byte[] obj) throws IOException{
File out=new File("./dat.txt");
RandomAccessFile ra=new RandomAccessFile(out,"rw");
if (!out.exists())
{
out.createNewFile();
}
long size=out.length();
if (i*16>size)
{
ra.seek(out.length());
for (long j=size;j<i*16;j+=16)
{
byte[] b=new byte[16];
ra.write(b);
}
}
ra.seek((i)*16);
System.out.println(new String(obj));
ra.write(obj);
ra.close();
}
public static void main(String[] args) throws IOException{
write(35,read(4));
}
I think you misunderstand what your editor tells you.
First of all, not every possible sequence of bytes is a valid UTF-8 string, see for example "UTF-8 decoder capability and stress test". So when you copy 16 bytes from one place of UTF-8 file to another you might get a file which no longer contains a valid UTF-8 text.
I suspect that you have the same file opened in Kate to see results of your editing. What the editors says to you is that it noticed that the file you opened is not a valid UTF-8 file and thus it doesn't know how to handle it correctly and thus to prevent accidental damage to your potentially precious data which now looks as binary (not text) to the editor, the editor refuses to save anything from UI back to that file. This doesn't change any permission on file-system level and probably other (dumber) editors will not warn you about such possible corruptions.
Thank you for your replies. I figured out the problem.
Sometimes text editors are adding one extra byte at the end of the file which is not supported as byte in Java. Usually this is EOF byte and is treated as UTF-8 which Java only accepts writing/reading ASCI bytes, except manipulating through writeUTF() method.
Also this byte is invisible in text editors and that was the reason why I write this post.
It took me two days to find out what is the issue, but if someone gets stuck here keep in mind the EOF byte.
Most of the examples I have seen deal with external memory or show how to create a new directory inside internal memory but not how to write to it, I tried implementing my own code into it but can't seem to find the created file even though the directory has been created, here is the code that I have been trying to use:
public void fileCreate(Context context, String fileDir) throws Exception{
File myNewDir = context.getDir(fileDir, Context.MODE_PRIVATE);
if (!myNewDir.exists()){
myNewDir.mkdirs();
File testContnet = new File(myNewDir + "/hello_file.txt");
String hello = "Hello world";
FileOutputStream fos = openFileOutput(testContnet.toString(), Context.MODE_PRIVATE);
fos.write(hello.getBytes());
fos.close();
}
}
Now, when I call this function I use:
try {
fileCreate(this, "testerDirectory");
}catch(Exception e) {
e.printStackTrace();
}
With no results. It is just for a small experiment I am doing so it is nothing too serious, but I still want to know about the proper way of creating a directory(in this case one called testerDirectory, and saving the file to it, I believe that my code is wrong but I do not have much experience with this to know exactly where to go. The Android documentation did show me how to create and save files although in this case I am trying to merge that example with that of creating a new directory and saving a file to it. Any help/pointers would be greatly appreciated.
I know also that the file is not being written accordingly upon inspecting the contents of the directory by using the adb shell.
You are only writing a file to the directory if the directory does not already exist.
Move your work with testContnet to be outside of the if block:
public void fileCreate(Context context, String fileDir) throws Exception{
File myNewDir = context.getDir(fileDir, Context.MODE_PRIVATE);
if (!myNewDir.exists()){
myNewDir.mkdirs();
}
File testContnet = new File(myNewDir, "hello_file.txt");
String hello = "Hello world";
FileOutputStream fos = new FileOutputstream(testContnet);
fos.write(hello.getBytes());
fos.flush();
fos.getFD().sync();
fos.close();
}
This way, you create the directory if it does not exist, but then create the file in either case. I also added fos.flush() and fos.getFD().sync(), to ensure all bytes get written to disk before you continue.
UPDATE: You were using openFileOutput(), which does not write to your desired directory. Moreover, it is unnecessary. Just create a FileOutputStream on your File.
How can I download .class file and and load it into jvm using class loader , I have write a simple code simulates downloading a .class file the I tried to load it into JVM
public class face {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
File f = new File("Task.class");
int count;
byte[] buffer = new byte[1024];
DataInputStream dis = new DataInputStream(new FileInputStream(f));
StringBuilder all = new StringBuilder();
while ((count = dis.read(buffer)) > 0) {
// System.out.write(buffer, 0, count);
all.append(buffer);
// System.out.flush();
}
File b = new File("Task.class");
FileOutputStream fos = new FileOutputStream(b);
DataOutputStream dos = new DataOutputStream(fos);
dos.write(all.toString().getBytes());
ClassLoader lod = face.class.getClassLoader();
lod.loadClass(b.getAbsolutePath());
}
}
Use Class.forName(<package_qualified_class_name>)
First, I would like to applogies for the long list of suggestion here, but you have managed to cram an impressive number of mistakes into a small piece of code.
I suggest don't do any of these things
don't use DataInputStream or DataOutputStream when it doesn't add anything. You don't use any method which requires it.
don't write binary data to a StringBuilder. A StringBuilder is for text.
don't copy an entire buffer if you only read part of it. i.e. you need to record the length actual read and copy only the amount used.
don't append a byte[] to a StringBuilder. It won't do what you expect.
don't use a String to store binary data.
don't convert a String to byte[] using the default encoding unless you know you have ASCII data (which you don't)
don't write to a file you just read. As this doesn't make sense. You should have tested this works without the file copy and you would have found this didn't work, before you attempted something more complicated.
you can't write to a file which you still have open in windows. I suggest you close() a file when you are finished with it.
don't attempt to load a class using the file name. You load it by package.class name.
I suggest you try a one liner to load a class first and show this works. The class should appear in your class path, and when you write to the file, you should write it to a directory appropriate for the package.
Instead of doing all this, you could add a http://yourserver/basepath to your class path and it will load the classes from a web service. i.e. you might be able to do this without writing any code at all.
I'm trying to create copy of a mp3 file.This I need to trim that mp3 file.So using input,output stream can be used to this I guess.Can the normal text file type of copying will be able to create a file that could be played .Someone with good knowledge of file handling in java help me in this.
MP3 file is binary file. So as long as you copy MP3 using binary file operations copy will succeed.
However to trim an MP3 file, you need to be aware of MP3 file structure. MP3 file consists of series of MP3 frames. Each frame starts with a MP3 header and followed by data. MP3 frame header contains information, using which you can find frame length.
More details on MP3 header at http://www.id3.org/mp3Frame
So as long as you copy at integral number of frames, you should be okay. Even otherwise, decoders will ignore incomplete frame.
Below code is a solution to copy an mp3 file or everything else. I have never experienced the trimming part. However, I think it is logically possible to trim your file just by specifying the amount of buffer you need.)
Actually dst is the name of the copied file in the directory.
private void copyFile(String src, String dst) {
FileInputStream inputStream; // create an input stream
FileOutputStream outputStream; // create an output stream
try {
inputStream = new FileInputStream(src); // create object
outputStream = openFileOutput(dst, Context.MODE_PRIVATE); // save your file in private mode, which makes it inaccessible by other applications
int bufferSize;
byte[] bufffer = new byte[512]; // I think logically here could be useful for trimming the file. I mean just copy an specified part of the file.
while ((bufferSize = inputStream.read(bufffer)) > 0) {
outputStream.write(bufffer, 0, bufferSize);
}
inputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
This is a suggestion about how to copy your files, which it will copy them in internal storage under your application package name. Moreover, I have not tested the trim part yet. So, I am not sure about that.
One more thing, you can get the path directory of your application by
getFilesDir();
I'm working on a game, and I need to load multiple image files (png, gif, etc.) that I'll eventually want to convert into BufferedImage objects. In my setup, I'd like to load all of these images from a single zip file, "Resources.zip". That resource file will contain images, map files, and audio files - all contained in various neatly ordered sub-directories. I want to do this because it will (hopefully) make resource loading easy in both applet and application versions of my program. I'm also hoping that for the applet version, this method will make it easy for me to show the loading progress of the game resources zip file (which could eventually amount to 10MB depending on how elaborate this game gets, though I'm hoping to keep it under that size so that it's browser-friendly).
I've included my zip handling class below. The idea is, I have a separate resource handling class, and it creates a ZipFileHandler object that it uses to pull specific resources out of the Resources.zip file.
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ZipFileHandler
{
private ZipFile zipFile;
public ZipFileHandler(String zipFileLocation)
{
try
{
zipFile = new ZipFile(zipFileLocation);
}
catch (IOException e) {System.err.println("Unable to load zip file at location: " + zipFileLocation);}
}
public byte[] getEntry(String filePath)
{
ZipEntry entry = zipFile.getEntry(filePath);
int entrySize = (int)entry.getSize();
try
{
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
byte[] finalByteArray = new byte[entrySize];
int bufferSize = 2048;
byte[] buffer = new byte[2048];
int chunkSize = 0;
int bytesRead = 0;
while(true)
{
//Read chunk to buffer
chunkSize = bis.read(buffer, 0, bufferSize); //read() returns the number of bytes read
if(chunkSize == -1)
{
//read() returns -1 if the end of the stream has been reached
break;
}
//Write that chunk to the finalByteArray
//System.arraycopy(src, srcPos, dest, destPos, length)
System.arraycopy(buffer, 0, finalByteArray, bytesRead, chunkSize);
bytesRead += chunkSize;
}
bis.close(); //close BufferedInputStream
System.err.println("Entry size: " + finalByteArray.length);
return finalByteArray;
}
catch (IOException e)
{
System.err.println("No zip entry found at: " + filePath);
return null;
}
}
}
And I use the ZipFileHandler class like this:
ZipFileHandler zfh = new ZipFileHandler(the_resourceRootPath + "Resources.zip");
InputStream in = new ByteArrayInputStream(zfh.getEntry("Resources/images/bg_tiles.png"));
try
{
BufferedImage bgTileSprite = ImageIO.read(in);
}
catch (IOException e)
{
System.err.println("Could not convert zipped image bytearray to a BufferedImage.");
}
And the good news is, it works!
But I feel like there might be a better way to do what I'm doing (and I'm fairly new to working with BufferedInputStreams).
In the end, my question is this:
Is this even a good idea?
Is there a better way to load a whole bunch of game resource files in a single download/stream, in an applet- AND application-friendly way?
I welcome all thoughts and suggestions!
Thanks!
Taking multiple resources and putting in them in one compressed file is how several web applications work (i.e. GWT) It is less expensive to load one large file than multiple small ones. This assumes that you are going to use all those resources in your app. If not Lazy loading is also a viable alternative.
That being said, it is usually best to get the app working and then to profile to find where the bottlenecks are. If not you will end up with a lot of complicated code and it will take you a lot longer to get your app working. 10%-20% of the code takes 80-90% of the time to execute. You just don;t know which 10-20% that is until the project is mostly complete.
If your goal is to learn the technologies and tinker, then good going - looks good.
If you are using a Java program, it is usually considered good practice to bundle it as a jar file anyway. So why do not put your classes simply inside this jar file (in directories, of course). Then you can simply use
`InputStream stream = MayClass.class.getResourceAsStream(imagePath);`
to load the data for each image, instead of having to handle all the zip by yourself (and it also works for jars not actually on the file system, such as http url in applets).
I also assume the jar will be cached, but you should measure and compare the performance to your solution with an external zip file.