From b35b3db63066ed911162e28702f45604e50c2f52 Mon Sep 17 00:00:00 2001 From: mguessan Date: Mon, 16 May 2011 08:47:54 +0000 Subject: [PATCH] Update Jsmooth patch with 64bits exe support git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1681 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- .../jsmoothgen/application/ExeCompiler.java | 955 +++++++++--------- .../application/JSmoothModelBean.java | 408 ++++++++ .../application/PropertiesBuilder.java | 250 +++++ .../application/gui/util/HTMLPane.java | 126 +++ .../net/charabia/jsmoothgen/pe/PEFile.java | 478 +++++++++ .../net/charabia/jsmoothgen/pe/PEHeader.java | 482 +++++++++ .../jsmoothgen/pe/PEResourceDirectory.java | 625 ++++++++++++ .../net/charabia/jsmoothgen/pe/PESection.java | 133 +++ 8 files changed, 2957 insertions(+), 500 deletions(-) create mode 100644 jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/JSmoothModelBean.java create mode 100644 jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/PropertiesBuilder.java create mode 100644 jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/util/HTMLPane.java create mode 100644 jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEFile.java create mode 100644 jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEHeader.java create mode 100644 jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEResourceDirectory.java create mode 100644 jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PESection.java diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/ExeCompiler.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/ExeCompiler.java index ee045f72..d1973828 100644 --- a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/ExeCompiler.java +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/ExeCompiler.java @@ -20,211 +20,201 @@ package net.charabia.jsmoothgen.application; -import net.charabia.jsmoothgen.skeleton.*; -import net.charabia.jsmoothgen.pe.*; - -import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.*; -import java.awt.*; -import java.awt.image.*; -import java.lang.reflect.*; -import net.charabia.util.codec.*; +import net.charabia.jsmoothgen.pe.PEFile; +import net.charabia.jsmoothgen.pe.PEResourceDirectory; +import net.charabia.jsmoothgen.skeleton.SkeletonBean; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.awt.image.PixelGrabber; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; -public class ExeCompiler -{ +public class ExeCompiler { private java.util.Vector m_errors = new java.util.Vector(); private Vector m_listeners = new Vector(); - - public interface StepListener - { - public void setNewState(int percentComplete, String state); - public void failed(); - public void complete(); + + public interface StepListener { + public void setNewState(int percentComplete, String state); + + public void failed(); + + public void complete(); } - - public void addListener(ExeCompiler.StepListener listener) - { - m_listeners.add(listener); - + + public void addListener(ExeCompiler.StepListener listener) { + m_listeners.add(listener); + } - - public void cleanErrors() - { - m_errors.removeAllElements(); + + public void cleanErrors() { + m_errors.removeAllElements(); } - - public java.util.Vector getErrors() - { - return m_errors; + + public java.util.Vector getErrors() { + return m_errors; } - - public class CompilerRunner implements Runnable - { - private File m_skelroot; - private SkeletonBean m_skel; - private JSmoothModelBean m_data; - private File m_out; - private File m_basedir; - public CompilerRunner(File skelroot, SkeletonBean skel, File basedir, JSmoothModelBean data, File out) - { - m_skelroot = skelroot; - m_skel = skel; - m_data = data; - m_out = out; - m_basedir = basedir; - } - - public void run() - { - try - { - compile(m_skelroot, m_skel, m_basedir, m_data, m_out); - } catch (Exception exc) - { - exc.printStackTrace(); - } - } - - public ExeCompiler getCompiler() - { - return ExeCompiler.this; - } + public class CompilerRunner implements Runnable { + private File m_skelroot; + private SkeletonBean m_skel; + private JSmoothModelBean m_data; + private File m_out; + private File m_basedir; + + public CompilerRunner(File skelroot, SkeletonBean skel, File basedir, JSmoothModelBean data, File out) { + m_skelroot = skelroot; + m_skel = skel; + m_data = data; + m_out = out; + m_basedir = basedir; + } + + public void run() { + try { + compile(m_skelroot, m_skel, m_basedir, m_data, m_out); + } catch (Exception exc) { + exc.printStackTrace(); + } + } + + public ExeCompiler getCompiler() { + return ExeCompiler.this; + } } - - public ExeCompiler.CompilerRunner getRunnable(File skelroot, SkeletonBean skel, File basedir, JSmoothModelBean data, File out) - { - return new CompilerRunner(skelroot, skel, basedir, data, out); + + public ExeCompiler.CompilerRunner getRunnable(File skelroot, SkeletonBean skel, File basedir, JSmoothModelBean data, File out) { + return new CompilerRunner(skelroot, skel, basedir, data, out); } - - public void compileAsync(File skelroot, SkeletonBean skel, File basedir, JSmoothModelBean data, File out) - { - Thread t = new Thread(new CompilerRunner(skelroot, skel, basedir, data, out)); - t.start(); + + public void compileAsync(File skelroot, SkeletonBean skel, File basedir, JSmoothModelBean data, File out) { + Thread t = new Thread(new CompilerRunner(skelroot, skel, basedir, data, out)); + t.start(); } - - public boolean compile(File skelroot, SkeletonBean skel, File basedir ,JSmoothModelBean data, File out) throws Exception - { - try { - fireStepChange(0, "Starting compilation"); - - File pattern = new File(skelroot, skel.getExecutableName()); - if (pattern.exists() == false) - { - m_errors.add("Error: Can't find any skeleton at " + skelroot); - fireFailedChange(); - return false; - } - - fireStepChange(10, "Scanning skeleton..."); - PEFile pe = new PEFile(pattern); - pe.open(); - PEResourceDirectory resdir = pe.getResourceDirectory(); - boolean resb = false; - - // - // Adds the jar only if the user selected one - // - if (data.getEmbeddedJar() == true) - { - if (data.getJarLocation() == null) - { - m_errors.add("Error: Jar is not specified!"); - fireFailedChange(); - return false; - } - - fireStepChange(40, "Loading Jar..."); - File jarloc = concFile(basedir, new File(data.getJarLocation())); - if (jarloc.exists() == false) - { - m_errors.add("Error: Can't find jar at " + jarloc); - fireFailedChange(); - return false; - } + public boolean compile(File skelroot, SkeletonBean skel, File basedir, JSmoothModelBean data, File out) throws Exception { + try { + fireStepChange(0, "Starting compilation"); - ByteBuffer jardata = load(jarloc); + File pattern = new File(skelroot, skel.getExecutableName()); + if (pattern.exists() == false) { + m_errors.add("Error: Can't find any skeleton at " + skelroot); + fireFailedChange(); + return false; + } - fireStepChange(60, "Adding Jar to Resources..."); - resb = resdir.replaceResource(skel.getResourceCategory(), skel.getResourceJarId(), 1033, jardata); - if (resb == false) - { - m_errors.add("Error: Can't replace jar resource! It is probably missing from the skeleton."); - fireFailedChange(); - return false; - } - } - - fireStepChange(70, "Adding Properties to Resources..."); - String props = PropertiesBuilder.makeProperties(basedir, data); - ByteBuffer propdata = convert(props); - resb = resdir.replaceResource(skel.getResourceCategory(), skel.getResourcePropsId(), 1033, propdata); + fireStepChange(10, "Scanning skeleton..."); + PEFile pe = new PEFile(pattern); + pe.open(); + PEResourceDirectory resdir = pe.getResourceDirectory(); - if (data.getIconLocation() != null) - { - fireStepChange(80, "Loading icon..."); - String iconpath; - if (new java.io.File(data.getIconLocation()).isAbsolute()) - iconpath = data.getIconLocation(); - else - iconpath = new java.io.File(basedir, data.getIconLocation()).getAbsolutePath(); + boolean resb = false; - Image img = getScaledImage(iconpath, 32, 32); - //Hashtable set = calculateColorCount(img); - // System.out.println("COLORS TOTAL 4: " + set.size()); + // + // Adds the jar only if the user selected one + // + if (data.getEmbeddedJar() == true) { + if (data.getJarLocation() == null) { + m_errors.add("Error: Jar is not specified!"); + fireFailedChange(); + return false; + } - if (img != null) - { - net.charabia.jsmoothgen.pe.res.ResIcon32 resicon = new net.charabia.jsmoothgen.pe.res.ResIcon32(img); - pe.replaceDefaultIcon(resicon); - } - } + fireStepChange(40, "Loading Jar..."); + File jarloc = concFile(basedir, new File(data.getJarLocation())); + if (jarloc.exists() == false) { + m_errors.add("Error: Can't find jar at " + jarloc); + fireFailedChange(); + return false; + } - fireStepChange(90, "Saving exe..."); - pe.dumpTo(out); - - // System.out.println("PROPERTIES:\n" + props); - - fireCompleteChange(); - return true; - } catch (Exception exc) - { - m_errors.add("Error: " + exc.getMessage()); - exc.printStackTrace(); - fireFailedChange(); - return false; - } + ByteBuffer jardata = load(jarloc); + + fireStepChange(60, "Adding Jar to Resources..."); + resb = resdir.replaceResource(skel.getResourceCategory(), skel.getResourceJarId(), 1033, jardata); + if (resb == false) { + m_errors.add("Error: Can't replace jar resource! It is probably missing from the skeleton."); + fireFailedChange(); + return false; + } + } + + fireStepChange(70, "Adding Properties and Manifest to Resources..."); + // Properties... + String props = PropertiesBuilder.makeProperties(basedir, data); + ByteBuffer propdata = convert(props); + resb = resdir.replaceResource(skel.getResourceCategory(), skel.getResourcePropsId(), 1033, propdata); + + // Manifest... + String manifest = PropertiesBuilder.makeManifest(data, skel); + if (manifest == null || manifest.isEmpty()) { + manifest = ""; + } + ByteBuffer manifestData = convert(manifest); + resb = resdir.replaceManifest(1, 1033, manifestData); + + if (data.getIconLocation() != null) { + fireStepChange(80, "Loading icon..."); + String iconpath; + if (new java.io.File(data.getIconLocation()).isAbsolute()) + iconpath = data.getIconLocation(); + else + iconpath = new java.io.File(basedir, data.getIconLocation()).getAbsolutePath(); + + Image img = getScaledImage(iconpath, 32, 32); + //Hashtable set = calculateColorCount(img); + // System.out.println("COLORS TOTAL 4: " + set.size()); + + if (img != null) { + net.charabia.jsmoothgen.pe.res.ResIcon32 resicon = new net.charabia.jsmoothgen.pe.res.ResIcon32(img); + pe.replaceDefaultIcon(resicon); + } + } + + fireStepChange(90, "Saving exe..."); + pe.dumpTo(out); + + // System.out.println("PROPERTIES:\n" + props); + + fireCompleteChange(); + return true; + } catch (Exception exc) { + m_errors.add("Error: " + exc.getMessage()); + exc.printStackTrace(); + fireFailedChange(); + return false; + } } - - public Image[] loadImages(String path) - { - File f = new File(path); - if (path.toUpperCase().endsWith(".ICO")) - { - // - // Try to load with our ico codec... - // - try { - java.awt.Image[] images = net.charabia.util.codec.IcoCodec.loadImages(f); - if ((images != null) && (images.length>0)) - { - return images; - } - } catch (java.io.IOException exc) - { - exc.printStackTrace(); - } - } + public Image[] loadImages(String path) { + File f = new File(path); - // - // defaults to the standard java loading process - // + if (path.toUpperCase().endsWith(".ICO")) { + // + // Try to load with our ico codec... + // + try { + java.awt.Image[] images = net.charabia.util.codec.IcoCodec.loadImages(f); + if ((images != null) && (images.length > 0)) { + return images; + } + } catch (java.io.IOException exc) { + exc.printStackTrace(); + } + } + + // + // defaults to the standard java loading process + // BufferedImage bufferedImage; try { bufferedImage = ImageIO.read(f); @@ -235,345 +225,310 @@ public class ExeCompiler } catch (IOException e) { e.printStackTrace(); } - return null; + return null; } - public void checkImageLoaded(Image img) - { - MediaTracker mtrack = new MediaTracker(new Canvas()); - mtrack.addImage(img, 1); - try { - mtrack.waitForAll(); - } catch (InterruptedException e) { - } - } - - private Hashtable calculateColorCount(Image img) - { - int width = img.getWidth(null); - int height = img.getHeight(null); - int[] pixels = new int[width*height]; - PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pixels, 0, width); - try - { - grabber.grabPixels(); - } catch (InterruptedException e) - { - System.err.println("interrupted waiting for pixels!"); - // throw new Exception("Can't load the image provided",e); - } - - - - Hashtable result = new Hashtable(); - int colorindex = 0; - for (int i=0; i>24)&0xFF) > 0) - { - pix &= 0x00FFFFFF; - Integer pixi = new Integer(pix); - Object o = result.get(pixi); - if (o == null) - { - result.put(pixi, new Integer(colorindex++)); - } - // if (colorindex > 256) - // return result; - } - } - return result; - } - - public BufferedImage getQuantizedImage(Image img) - { - // 32 bit ico file already loaded as BufferedImage - if (img instanceof BufferedImage) { - return (BufferedImage) img; - } else { - int width = img.getWidth(null); - int height = img.getHeight(null); - int[][] data = new int[width][height]; - - int[] pixelbuffer = new int[width*height]; - PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pixelbuffer, 0, width); - try - { - grabber.grabPixels(); - } catch (InterruptedException e) - { - System.err.println("interrupted waiting for pixels!"); - throw new RuntimeException("Can't load the image provided",e); - } - for (int i=0; i> 24) & 0xFF) > 0) { + pix &= 0x00FFFFFF; + Integer pixi = new Integer(pix); + Object o = result.get(pixi); + if (o == null) { + result.put(pixi, new Integer(colorindex++)); + } + // if (colorindex > 256) + // return result; + } + } + return result; } - public Image getScaledImage(String path, int width, int height) - { - Image[] orgimages = loadImages(path); - - if ((orgimages == null) || (orgimages.length == 0)) - return null; + public BufferedImage getQuantizedImage(Image img) { + // 32 bit ico file already loaded as BufferedImage + if (img instanceof BufferedImage) { + return (BufferedImage) img; + } else { + int width = img.getWidth(null); + int height = img.getHeight(null); + int[][] data = new int[width][height]; - for (int i=0; imaxsize) - { - maxsize = size; - biggest = orgimages[i]; - } - } + for (int i = 0; i < palette.length; i++) { + // System.out.println(" i= " + (i)); + cmap[(i * 4)] = (byte) ((palette[i] >> 16) & 0xFF); + cmap[(i * 4) + 1] = (byte) ((palette[i] >> 8) & 0xFF); + cmap[(i * 4) + 2] = (byte) (palette[i] & 0xFF); + cmap[(i * 4) + 3] = (byte) 0xFF; + } - if (biggest != null) - { - BufferedImage result = getScaledInstance((BufferedImage)biggest, 32, 32, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); - checkImageLoaded(result); - return getQuantizedImage(result); - } - // - // Here, we have failed and return null - // - return null; + IndexColorModel colmodel = new IndexColorModel(8, palette.length, cmap, 0, true, 0); + BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + // + // The normal manner of quantizing would be to run + // result.setRGB(0,0, width, height, pixelbuffer, 0, width); + // where result is a BufferedImage of + // BufferedImage.TYPE_BYTE_INDEXED type. Unfortunately, I + // couldn't make it work. So, here is a work-around that + // should work similarly. + // + java.util.Hashtable set = new java.util.Hashtable(); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int alpha = (savedata[x][y] >> 24) & 0xFF; + if (alpha == 0) { + result.setRGB(x, y, 0); + // System.out.print("."); + } else { + int rgb = colmodel.getRGB(data[x][y]); + rgb |= 0xFF000000; + set.put(new Integer(rgb), new Integer(rgb)); + result.setRGB(x, y, rgb); + // System.out.print("*"); + } + } + // System.out.println(""); + } + + + return result; + } + } + + public Image checkImageSize(Image img, int width, int height) { + int w = img.getWidth(null); + int h = img.getHeight(null); + if ((w == width) && (h == height)) + return img; + return null; + } + + public Image getScaledImage(String path, int width, int height) { + Image[] orgimages = loadImages(path); + + if ((orgimages == null) || (orgimages.length == 0)) + return null; + + for (int i = 0; i < orgimages.length; i++) + checkImageLoaded(orgimages[i]); + + // System.out.println("Loaded " + orgimages.length + " images"); + for (int i = 0; (i < orgimages.length); i++) { + int w = orgimages[i].getWidth(null); + int h = orgimages[i].getHeight(null); + // System.out.println("Size of " + i + " = " + w + "," + h); + } + + // + // We prefer 32x32 pictures, then 64x64, then 16x16... + // + Image selected = null; + for (int i = 0; (i < orgimages.length) && (selected == null); i++) + selected = checkImageSize(orgimages[i], 32, 32); + for (int i = 0; (i < orgimages.length) && (selected == null); i++) + selected = checkImageSize(orgimages[i], 64, 64); + for (int i = 0; (i < orgimages.length) && (selected == null); i++) + selected = checkImageSize(orgimages[i], 16, 16); + + if (selected != null) { + return getQuantizedImage(selected); + } + + // + // If there is no 32x32, 64x64, nor 16x16, then we scale the + // biggest image to be 32x32... This should happen mainly when + // loading an image from a png of gif file, and in most case + // there is only one image on the array. + // + int maxsize = 0; + Image biggest = null; + for (int i = 0; (i < orgimages.length) && (selected == null); i++) { + int size = orgimages[i].getWidth(null) * orgimages[i].getHeight(null); + if (size > maxsize) { + maxsize = size; + biggest = orgimages[i]; + } + } + + if (biggest != null) { + BufferedImage result = getScaledInstance((BufferedImage) biggest, 32, 32, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); + checkImageLoaded(result); + return getQuantizedImage(result); + } + // + // Here, we have failed and return null + // + return null; + } + + /** + * Convenience method that returns a scaled instance of the + * provided {@code BufferedImage}. + * + * @param img the original image to be scaled + * @param targetWidth the desired width of the scaled instance, + * in pixels + * @param targetHeight the desired height of the scaled instance, + * in pixels + * @param hint one of the rendering hints that corresponds to + * {@code RenderingHints.KEY_INTERPOLATION} (e.g. + * {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR}, + * {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR}, + * {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC}) + * @param higherQuality if true, this method will use a multi-step + * scaling technique that provides higher quality than the usual + * one-step technique (only useful in downscaling cases, where + * {@code targetWidth} or {@code targetHeight} is + * smaller than the original dimensions, and generally only when + * the {@code BILINEAR} hint is specified) + * @return a scaled version of the original {@code BufferedImage} + */ + public BufferedImage getScaledInstance(BufferedImage img, + int targetWidth, + int targetHeight, + Object hint, + boolean higherQuality) { + int type = (img.getTransparency() == Transparency.OPAQUE) ? + BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; + BufferedImage ret = (BufferedImage) img; + int w, h; + if (higherQuality) { + // Use multi-step technique: start with original size, then + // scale down in multiple passes with drawImage() + // until the target size is reached + w = img.getWidth(); + h = img.getHeight(); + } else { + // Use one-step technique: scale directly from original + // size to target size with a single drawImage() call + w = targetWidth; + h = targetHeight; + } + + do { + if (higherQuality && w > targetWidth) { + w /= 2; + if (w < targetWidth) { + w = targetWidth; + } + } + + if (higherQuality && h > targetHeight) { + h /= 2; + if (h < targetHeight) { + h = targetHeight; + } + } + + BufferedImage tmp = new BufferedImage(w, h, type); + Graphics2D g2 = tmp.createGraphics(); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); + g2.drawImage(ret, 0, 0, w, h, null); + g2.dispose(); + + ret = tmp; + } while (w != targetWidth || h != targetHeight); + + return ret; } - - /** - * Convenience method that returns a scaled instance of the - * provided {@code BufferedImage}. - * - * @param img the original image to be scaled - * @param targetWidth the desired width of the scaled instance, - * in pixels - * @param targetHeight the desired height of the scaled instance, - * in pixels - * @param hint one of the rendering hints that corresponds to - * {@code RenderingHints.KEY_INTERPOLATION} (e.g. - * {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR}, - * {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR}, - * {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC}) - * @param higherQuality if true, this method will use a multi-step - * scaling technique that provides higher quality than the usual - * one-step technique (only useful in downscaling cases, where - * {@code targetWidth} or {@code targetHeight} is - * smaller than the original dimensions, and generally only when - * the {@code BILINEAR} hint is specified) - * @return a scaled version of the original {@code BufferedImage} - */ - public BufferedImage getScaledInstance(BufferedImage img, - int targetWidth, - int targetHeight, - Object hint, - boolean higherQuality) - { - int type = (img.getTransparency() == Transparency.OPAQUE) ? - BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; - BufferedImage ret = (BufferedImage)img; - int w, h; - if (higherQuality) { - // Use multi-step technique: start with original size, then - // scale down in multiple passes with drawImage() - // until the target size is reached - w = img.getWidth(); - h = img.getHeight(); - } else { - // Use one-step technique: scale directly from original - // size to target size with a single drawImage() call - w = targetWidth; - h = targetHeight; - } - - do { - if (higherQuality && w > targetWidth) { - w /= 2; - if (w < targetWidth) { - w = targetWidth; - } - } - - if (higherQuality && h > targetHeight) { - h /= 2; - if (h < targetHeight) { - h = targetHeight; - } - } - - BufferedImage tmp = new BufferedImage(w, h, type); - Graphics2D g2 = tmp.createGraphics(); - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); - g2.drawImage(ret, 0, 0, w, h, null); - g2.dispose(); - - ret = tmp; - } while (w != targetWidth || h != targetHeight); - - return ret; - } + private ByteBuffer load(File in) throws Exception { + FileInputStream fis = new FileInputStream(in); + ByteBuffer data = ByteBuffer.allocate((int) in.length()); + data.order(ByteOrder.LITTLE_ENDIAN); + FileChannel fischan = fis.getChannel(); + fischan.read(data); + data.position(0); + fis.close(); - private ByteBuffer load(File in) throws Exception - { - FileInputStream fis = new FileInputStream(in); - ByteBuffer data = ByteBuffer.allocate((int)in.length()); - data.order(ByteOrder.LITTLE_ENDIAN); - FileChannel fischan = fis.getChannel(); - fischan.read(data); - data.position(0); - fis.close(); - - return data; + return data; } - - private ByteBuffer convert(String data) - { - ByteBuffer result = ByteBuffer.allocate(data.length()+1); - result.position(0); - - for (int i=0; i + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +/* + * JSmoothModelBean.java + * + * Created on 7 aout 2003, 18:32 + */ + +package net.charabia.jsmoothgen.application; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.Vector; + +public class JSmoothModelBean { + private String m_skeletonName; + private String m_executableName; + private String m_currentDirectory; + + private String m_iconLocation; + private boolean m_embedJar = false; + private String m_jarLocation; + private String m_mainClassName; + private String m_arguments; + private String[] m_classPath; + private String m_minimumVersion = ""; + private String m_maximumVersion = ""; + private String[] m_jvmSearch = null; + + private int m_maxHeap = -1; + private int m_initialHeap = -1; + + private String m_vmParamter; + + private int m_uacRequireAdmin; + + private String m_noJvmMessage; + private String m_noJvmURL; + + private String m_bundledJVM = null; + + private JavaPropertyPair[] m_javaprops = new JavaPropertyPair[0]; + private JSmoothModelBean.Property[] m_skelproperties; + + static public class Property { + public String Key; + public String Value; + + public void setKey(String key) { + this.Key = key; + } + + public String getKey() { + return this.Key; + } + + public void setValue(String val) { + this.Value = val; + } + + public String getValue() { + return this.Value; + } + + public String toString() { + return getKey() + "==" + getValue(); + } + } + + transient Vector m_listeners = new Vector(); + + public static interface Listener { + public void dataChanged(); + } + + transient Vector m_skeletonChangedListener = new Vector(); + + public static interface SkeletonChangedListener { + public void skeletonChanged(); + } + + /** + * Creates a new instance of JSmoothModelBean + */ + public JSmoothModelBean() { + } + + public void addListener(JSmoothModelBean.Listener l) { + m_listeners.add(l); + } + + public void removeListener(JSmoothModelBean.Listener l) { + m_listeners.remove(l); + } + + public void addSkeletonChangedListener(JSmoothModelBean.SkeletonChangedListener l) { + m_skeletonChangedListener.add(l); + } + + public void removeSkeletonChangedListener(JSmoothModelBean.SkeletonChangedListener l) { + m_skeletonChangedListener.remove(l); + } + + + private void fireChanged() { + for (Iterator i = m_listeners.iterator(); i.hasNext();) { + JSmoothModelBean.Listener l = (JSmoothModelBean.Listener)i.next(); + l.dataChanged(); + } + } + + private void fireSkeletonChanged() { + for (Iterator i = m_skeletonChangedListener.iterator(); i.hasNext();) { + JSmoothModelBean.SkeletonChangedListener l = (JSmoothModelBean.SkeletonChangedListener)i.next(); + l.skeletonChanged(); + } + } + + public void setSkeletonName(String name) { + if (name != m_skeletonName) { + m_skeletonName = name; + fireSkeletonChanged(); + fireChanged(); + } + } + + public String getSkeletonName() { + return m_skeletonName; + } + + public void setExecutableName(String name) { + if (name != m_executableName) { + m_executableName = name; + fireChanged(); + } + } + + + public void setCurrentDirectory(String curdir) { + if (curdir != m_currentDirectory) { + m_currentDirectory = curdir; + fireChanged(); + } + } + + public String getCurrentDirectory() { + return m_currentDirectory; + } + + public String getExecutableName() { + return m_executableName; + } + + public void setIconLocation(String name) { + if (name != m_iconLocation) { + m_iconLocation = name; + fireChanged(); + } + } + + public String getIconLocation() { + return m_iconLocation; + } + + public boolean getEmbeddedJar() { + return m_embedJar; + } + + public void setEmbeddedJar(boolean b) { + m_embedJar = b; + fireChanged(); + } + + public void setJarLocation(String name) { + if (name != m_jarLocation) { + m_jarLocation = name; + fireChanged(); + } + } + + public String getJarLocation() { + return m_jarLocation; + } + + + public void setMainClassName(String name) { + if (name != m_mainClassName) { + m_mainClassName = name; + fireChanged(); + } + } + + public String getMainClassName() { + return m_mainClassName; + } + + public void setArguments(String args) { + m_arguments = args; + fireChanged(); + } + + public String getArguments() { + return m_arguments; + } + + public void setClassPath(String[] cp) { + m_classPath = cp; + fireChanged(); + } + + public String[] getClassPath() { + return m_classPath; + } + + public void setMaximumVersion(String version) { + m_maximumVersion = version; + fireChanged(); + } + + public String getMaximumVersion() { + return m_maximumVersion; + } + + public void setMinimumVersion(String version) { + m_minimumVersion = version; + fireChanged(); + } + + public String getMinimumVersion() { + return m_minimumVersion; + } + + public void setJVMSearchPath(String[] path) { + m_jvmSearch = path; + fireChanged(); + } + + public String[] getJVMSearchPath() { + return m_jvmSearch; + } + + public void setSkeletonProperties(JSmoothModelBean.Property[] props) { + // for (int i=0; i= 0)) + m_currentDirectory = checkRelativePath(exebase, m_currentDirectory, result, "Current directory", toRelativePath); + } + + if (m_classPath != null) { + for (int i = 0; i < m_classPath.length; i++) { + m_classPath[i] = checkRelativePath(filebase, m_classPath[i], result, "Classpath entry (" + i + ")", toRelativePath); + } + } + + if (result.size() == 0) + return null; + + String[] res = new String[result.size()]; + result.toArray(res); + + return res; + } + + private String checkRelativePath(java.io.File root, String value, java.util.Vector errors, String name, boolean toRelativePath) { + if (value == null) + return value; + + if (toRelativePath) { + File nf = JSmoothModelPersistency.makePathRelativeIfPossible(root, new File(value)); + if (nf.isAbsolute()) { + errors.add(name); + } + return nf.toString(); + } else { + File nf = new File(value); + if (nf.isAbsolute() == false) { + nf = new File(root, value); + nf = nf.getAbsoluteFile(); + + try { + nf = nf.getCanonicalFile(); + nf = nf.getAbsoluteFile(); + } catch (IOException iox) { + // do nothing + } + } + return nf.toString(); + } + } +} diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/PropertiesBuilder.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/PropertiesBuilder.java new file mode 100644 index 00000000..82b7421c --- /dev/null +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/PropertiesBuilder.java @@ -0,0 +1,250 @@ +/* + JSmooth: a VM wrapper toolkit for Windows + Copyright (C) 2003 Rodrigo Reyes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +package net.charabia.jsmoothgen.application; + +import java.io.File; + +import net.charabia.jsmoothgen.skeleton.SkeletonBean; + +/** + * @author Rodrigo + */ +public class PropertiesBuilder { + /** + * Creates a text containing all the relevant properties of a + * JSmoothModelBean object. The properties are output in the form + * "key=value". + *

+ *

+ * Note that all the paths are converted to be made relative to + * the basedir parameter provided. All the paths converted are + * expected to be relative to the targetted executable binary + * (before the conversion is applied, that is). + */ + static public String makeProperties(File basedir, JSmoothModelBean obj) { + StringBuffer out = new StringBuffer(); + + addPair("arguments", obj.getArguments(), out); + addPair("mainclassname", obj.getMainClassName(), out); + addPair("jvmsearch", makePathConc(obj.getJVMSearchPath()), out); + addPair("minversion", obj.getMinimumVersion(), out); + addPair("maxversion", obj.getMaximumVersion(), out); + + addPair("currentdir", obj.getCurrentDirectory(), out); + + if (obj.getEmbeddedJar() && (obj.getJarLocation().trim().length() > 0)) { + addPair("embedjar", "true", out); + } else { + addPair("embedjar", "false", out); + } + + if (obj.getMaximumMemoryHeap() > 1) { + addPair("maxheap", Integer.toString(obj.getMaximumMemoryHeap()), out); + } + + if (obj.getInitialMemoryHeap() > 1) { + addPair("initialheap", Integer.toString(obj.getInitialMemoryHeap()), out); + } + + if ((obj.getVmParameter() != null) && (!obj.getVmParameter().isEmpty())) { + addPair("vmparameter", obj.getVmParameter(), out); + } + // BundledVM & classpaths are changed to be accessible + // from the current directory + File curdir = new File(obj.getExecutableName()).getParentFile(); + + if (curdir == null) + curdir = basedir.getAbsoluteFile(); + + if (curdir.isAbsolute() == false) { + curdir = new File(basedir, curdir.toString()); + } + + + // System.out.println("... curdir1 : " + curdir.toString()); + + if (obj.getCurrentDirectory() != null) { + File newcurdir = new File(obj.getCurrentDirectory()); + // System.out.println("... curdir1.5 : " + obj.getCurrentDirectory()); + + if (!"${EXECUTABLEPATH}".equalsIgnoreCase(obj.getCurrentDirectory())) { + if (newcurdir.isAbsolute() == false) { + curdir = new File(curdir, newcurdir.toString()); + } else + curdir = newcurdir; + } + } + // System.out.println("... curdir2 : " + curdir.toString()); + + if (obj.getBundledJVMPath() != null) + addPair("bundledvm", getRenormalizedPathIfNeeded(obj.getBundledJVMPath(), basedir, curdir), out); + + if (obj.getClassPath() != null) { + String[] relcp = new String[obj.getClassPath().length]; + for (int i = 0; i < relcp.length; i++) { + relcp[i] = getRenormalizedPathIfNeeded(obj.getClassPath()[i], basedir, curdir); + } + addPair("classpath", makePathConc(relcp), out); + } + + // + // Adds all the skeleton-specific properties + // + if (obj.getSkeletonProperties() != null) { + for (int i = 0; i < obj.getSkeletonProperties().length; i++) { + JSmoothModelBean.Property prop = obj.getSkeletonProperties()[i]; + if (prop.getKey() != null) { + String val = prop.getValue(); + if (val == null) + val = ""; + addPair("skel_" + prop.getKey(), val, out); + } + } + } + + + // + // Adds all the java properties. Those properties are + // typically passed as -Dname=value arguments for the sun's + // JVM. + // + + JavaPropertyPair[] javapairs = obj.getJavaProperties(); + if (javapairs != null) { + addPair("javapropertiescount", new Integer(javapairs.length).toString(), out); + for (int i = 0; i < javapairs.length; i++) { + addPair("javaproperty_name_" + i, javapairs[i].getName(), out); + addPair("javaproperty_value_" + i, javapairs[i].getValue(), out); + } + } + + return out.toString(); + } + + /** + * Create a manifest entry for windows right elevation + * + * @param data + * @param skel + * @return the manifest xml + */ + public static String makeManifest(JSmoothModelBean data, SkeletonBean skel) { + StringBuilder retVal = new StringBuilder(); + String platform = "x86"; + String shortName = skel.getShortName(); + if (shortName.contains("64")) { + platform = "ia64"; + } + retVal.append("").append("\n"); + retVal.append("").append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + retVal + .append( + " ") + .append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + if (data.isUacRequireAdmin()) { + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + retVal.append(" ").append("\n"); + } + retVal.append(""); + return retVal.toString(); + } + + /** + * Converts a path relative to previousbasedir into a path + * relative to newbasedir. + */ + static public String getRenormalizedPathIfNeeded(String value, File previousbasedir, File newbasedir) { + // File f = new File(value); + // if (f.isAbsolute()) + // return value; + + if (newbasedir == null) + return value; + + if (value == null) + return ""; + + File abs = new File(previousbasedir, value).getAbsoluteFile(); + File n = JSmoothModelPersistency.makePathRelativeIfPossible(newbasedir, abs); + + return n.toString(); + } + + static public String escapeString(String str) { + if (str == null) + return ""; + + StringBuffer out = new StringBuffer(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + switch (c) { + case '\n': + out.append("\\n"); + break; + case '\t': + out.append("\\t"); + break; + case '\r': + out.append("\\r"); + break; + case '\\': + out.append("\\\\"); + break; + default: + out.append(c); + } + } + return out.toString(); + } + + static private void addPair(String name, String value, StringBuffer out) { + out.append(escapeString(name)); + out.append("="); + out.append(escapeString(value)); + out.append("\n"); + } + + static public String makePathConc(String[] elements) { + StringBuffer buf = new StringBuffer(); + if (elements != null) + for (int i = 0; i < elements.length; i++) { + buf.append(elements[i]); + if ((i + 1) < elements.length) + buf.append(";"); + } + return buf.toString(); + } + +} diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/util/HTMLPane.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/util/HTMLPane.java new file mode 100644 index 00000000..0129c4b6 --- /dev/null +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/util/HTMLPane.java @@ -0,0 +1,126 @@ +/* + JSmooth: a VM wrapper toolkit for Windows + Copyright (C) 2003 Rodrigo Reyes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +package net.charabia.jsmoothgen.application.gui.util; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.border.*; +import java.io.*; +import java.util.*; +import javax.swing.text.html.*; +import javax.swing.event.*; +import java.net.*; + +/** + * + */ + +public class HTMLPane extends JPanel +{ + private JScrollPane m_scroller; + private JEditorPane m_html; + private URL m_baseurl; + + edu.stanford.ejalbert.BrowserLauncher m_launcher; + + class Hyperactive implements HyperlinkListener { + + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + + JEditorPane pane = (JEditorPane)e.getSource(); + if (e instanceof HTMLFrameHyperlinkEvent) { + HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e; + HTMLDocument doc = (HTMLDocument)pane.getDocument(); + doc.processHTMLFrameHyperlinkEvent(evt); + } else { + try { + URL nurl = e.getURL(); + if (nurl == null) + nurl = new URL(m_baseurl, e.getDescription()); + if (jsmooth.Native.isAvailable()) + { + jsmooth.Native.shellExecute(jsmooth.Native.SHELLEXECUTE_OPEN, nurl.toString(), null, null, jsmooth.Native.SW_NORMAL); + } + else + m_launcher.openURLinBrowser(nurl.toExternalForm()); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + } + } + + + public HTMLPane() + { + try { + m_baseurl = new File(".").toURI().toURL(); + } catch (Exception ex) { ex.printStackTrace(); } + m_html = new JEditorPane("text/html","") { + public boolean getScrollableTracksViewportWidth() + { + return true; + } + }; + HTMLEditorKit hek = new HTMLEditorKit(); + m_html.setEditorKit(hek); + + m_scroller = new JScrollPane(m_html); + setLayout(new BorderLayout()); + m_html.setEditable(false); + add(m_scroller, BorderLayout.CENTER); + // add(m_html, BorderLayout.CENTER); + m_html.addHyperlinkListener(new Hyperactive()); + + try { + m_launcher = new edu.stanford.ejalbert.BrowserLauncher(); + }catch (Exception ex) + { + ex.printStackTrace(); + } + + } + + public java.awt.Dimension getPreferredSize() + { + return new java.awt.Dimension(200,200); + } + + public void setPage(URL url) + { + try { + URL u = new URL(m_baseurl, url.toExternalForm()); + m_html.setPage(u); + } catch (Exception ex) { ex.printStackTrace(); } + } + + public void setText(String s) + { + m_html.setContentType("text/html"); + m_html.setText(s); + m_html.setCaretPosition(0); + } + + +} diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEFile.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEFile.java new file mode 100644 index 00000000..e4bb9929 --- /dev/null +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEFile.java @@ -0,0 +1,478 @@ +/* + JSmooth: a VM wrapper toolkit for Windows + Copyright (C) 2003 Rodrigo Reyes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +/* + * PEFile.java + * + * Created on 28 juillet 2003, 21:28 + */ + +package net.charabia.jsmoothgen.pe; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.Vector; + +import net.charabia.jsmoothgen.pe.res.ResIcon; +import net.charabia.jsmoothgen.pe.res.ResIconDir; + +/** + * @author Rodrigo + */ +public class PEFile { + private File m_file; + private FileInputStream m_in = null; + private FileChannel m_channel = null; + + private PEOldMSHeader m_oldmsheader; + private PEHeader m_header; + private Vector m_sections = new Vector(); + + private PEResourceDirectory m_resourceDir; + + /** + * Creates a new instance of PEFile + */ + public PEFile(File f) { + m_file = f; + } + + public void close() throws IOException { + m_in.close(); + } + + public void open() throws FileNotFoundException, IOException { + m_in = new FileInputStream(m_file); + m_channel = m_in.getChannel(); + + m_oldmsheader = new PEOldMSHeader(this); + + m_oldmsheader.read(); + // m_oldmsheader.dump(System.out); + long headoffset = m_oldmsheader.e_lfanew; + + m_header = new PEHeader(this, headoffset); + m_header.read(); + // m_header.dump(System.out); + + int seccount = m_header.NumberOfSections; + // System.out.println("LOADING " + seccount + " sections..."); + + long offset = headoffset + (m_header.NumberOfRvaAndSizes * 8) + 24 + getPeHeaderOffset(); + + for (int i = 0; i < seccount; i++) { + // System.out.println("Offset: " + offset + " (" + this.m_channel.position()); + + PESection sect = new PESection(this, offset); + sect.read(); + // sect.dump(System.out); + m_sections.add(sect); + offset += 40; + } + // System.out.println("After sections: " + this.m_channel.position() + " (" + offset + ")"); + + ByteBuffer resbuf = null; + long resourceoffset = m_header.ResourceDirectory_VA; + for (int i = 0; i < seccount; i++) { + PESection sect = (PESection)m_sections.get(i); + if (sect.VirtualAddress == resourceoffset) { + // System.out.println(" Resource section found: " + resourceoffset); + PEResourceDirectory prd = new PEResourceDirectory(this, sect); + resbuf = prd.buildResource(sect.VirtualAddress); + break; + } + } + } + + private int getPeHeaderOffset() { + int pe32Offset = 96; + if (m_header.isPe32Plus()) { + // It is a pe32+ header (x64) + pe32Offset = 112; + } + return pe32Offset; + } + + public FileChannel getChannel() { + return m_channel; + } + + public static void main(String args[]) throws IOException, CloneNotSupportedException, Exception { + // (no)PEFile pe = new PEFile(new File("F:/Program Files/LAN Search PRO/lansearch.exe")); + + PEFile pe = new PEFile(new File("c:/scratch/rc3.exe")); + // PEFile pe = new PEFile(new File("c:/projects/jwrap/Copie.exe")); + // PEFile pe = new PEFile(new File("c:/projects/jwrap/test.exe")); + // PEFile pe = new PEFile(new File("F:/Program Files/bQuery/bQuery.exe")); + // PEFile pe = new PEFile(new File("F:/Program Files/Server Query/query.exe")); + // PEFile pe = new PEFile(new File("F:/Program Files/AvRack/rtlrack.exe")); + pe.open(); + System.out.println("OldMSHeader"); + pe.m_oldmsheader.dump(System.out); + System.out.println("COFFHeader"); + pe.m_header.dump(System.out); + + // System.out.println("===============\nADDING A RES"); + // File fout = new File("F:/Documents and Settings/Rodrigo/Mes documents/projects/jsmooth/skeletons/simplewrap/gen-application.jar"); + // FileInputStream fis = new FileInputStream(fout); + // + // ByteBuffer data = ByteBuffer.allocate((int)fout.length()); + // data.order(ByteOrder.LITTLE_ENDIAN); + // FileChannel fischan = fis.getChannel(); + // fischan.read(data); + // data.position(0); + // fis.close(); + + PEResourceDirectory resdir = pe.getResourceDirectory(); + System.out.println("ResourceDirectory"); + resdir.dump(System.out); + + // DataEntry inputResData = resdir.getData("JAVA", "#" + String.valueOf(103), "#" + String.valueOf(1033)); + // ByteBuffer inputResDataBuffer = ByteBuffer.allocate(inputResData.diskSize() + 1024); + // inputResDataBuffer.order(ByteOrder.LITTLE_ENDIAN); + // inputResData.buildBuffer(inputResDataBuffer, 0, 0); + // int inputResDataBufferSize = inputResDataBuffer.position(); + // inputResDataBuffer.flip(); + // int offset = inputResDataBuffer.getInt(); + // inputResDataBuffer.position(offset); + // StringBuilder inputResDataString = new StringBuilder(inputResDataBufferSize); + // while (inputResDataBuffer.position() <= inputResDataBufferSize - 2) { + // byte dummyByte = inputResDataBuffer.get(); + // inputResDataString.append((char)dummyByte); + // } + // // Modify the data... + // String newInputResDataString = inputResDataString.toString(); + // newInputResDataString = newInputResDataString.replace("samplejar", "ThisIsMyJarAndOnlyMine"); + // + // inputResDataBuffer = ByteBuffer.allocate(newInputResDataString.length() + 2); + // for (int index = 0; index < newInputResDataString.length(); index++) { // C- do not change because buffer can be modified during loop + // inputResDataBuffer.put((byte)newInputResDataString.charAt(index)); + // } + // inputResDataBuffer.put((byte)0); + // inputResDataBuffer.put((byte)0); + // inputResDataBuffer.position(0); + // + // boolean resb = resdir.replaceResource("JAVA", 102, 1033, inputResDataBuffer); + + // PEResourceDirectory.DataEntry entry = resdir.getData("#14", "A", "#1033"); + // entry.Data.position(0); + // System.out.println("DataEntry found : " + entry + " (size=" + entry.Data.remaining() + ")"); + // entry.Data.position(0); + // + // ResIconDir rid = new ResIconDir(entry.Data); + // System.out.println("ResIconDir :"); + // System.out.println(rid.toString()); + // int iconid = rid.getEntries()[0].dwImageOffset; + // System.out.println("Icon Index: " + iconid); + // + // PEResourceDirectory.DataEntry iconentry = resdir.getData("#3", "#"+iconid, "#1033"); + // iconentry.Data.position(0); + // ResIcon icon = new ResIcon(iconentry.Data); + // System.out.println("Icon :"); + // System.out.println(icon.toString()); + + // java.awt.Image img = java.awt.Toolkit.getDefaultToolkit().getImage ("c:\\test.gif"); + // java.awt.Image img = java.awt.Toolkit.getDefaultToolkit().getImage ("c:\\gnome-day2.png"); + // java.awt.Image img = java.awt.Toolkit.getDefaultToolkit().getImage("c:\\gnome-color-browser2.png"); + // + // java.awt.MediaTracker mt = new java.awt.MediaTracker(new javax.swing.JLabel("toto")); + // mt.addImage(img, 1); + // try { + // mt.waitForAll(); + // } catch (Exception exc) { + // exc.printStackTrace(); + // } + // + // ResIcon newicon = new ResIcon(img); + // + // pe.replaceDefaultIcon(newicon); + + // System.out.println("-----------------\nNEW ICON:"); + // System.out.println(newicon.toString()); + // + // rid.getEntries()[0].bWidth = (short)newicon.Width; + // rid.getEntries()[0].bHeight = (short)(newicon.Height/2); + // rid.getEntries()[0].bColorCount = (short)(1 < 0) + virtualAddress += peheader.SectionAlignment - (virtualAddress % peheader.SectionAlignment); + + long resourceoffset = m_header.ResourceDirectory_VA; + for (int i = 0; i < sections.size(); i++) { + PESection sect = (PESection)sections.get(i); + if (resourceoffset == sect.VirtualAddress) { + // System.out.println("Dumping RES section " + i + " at " + offset + " from " + sect.PointerToRawData + " (VA=" + virtualAddress + ")"); + out.position(offset); + long sectoffset = offset; + PEResourceDirectory prd = this.getResourceDirectory(); + ByteBuffer resbuf = prd.buildResource(sect.VirtualAddress); + resbuf.position(0); + + out.write(resbuf); + offset += resbuf.capacity(); + long rem = offset % this.m_header.FileAlignment; + if (rem != 0) + offset += this.m_header.FileAlignment - rem; + + if (out.size() + 1 < offset) { + ByteBuffer padder = ByteBuffer.allocate(1); + out.write(padder, offset - 1); + } + + long virtualSize = resbuf.capacity(); + if ((virtualSize % peheader.SectionAlignment) > 0) + virtualSize += peheader.SectionAlignment - (virtualSize % peheader.SectionAlignment); + + sect.PointerToRawData = sectoffset; + sect.SizeOfRawData = resbuf.capacity(); + if ((sect.SizeOfRawData % this.m_header.FileAlignment) > 0) + sect.SizeOfRawData += (this.m_header.FileAlignment - (sect.SizeOfRawData % this.m_header.FileAlignment)); + sect.VirtualAddress = virtualAddress; + sect.VirtualSize = virtualSize; + // System.out.println(" VS=" + virtualSize + " at VA=" + virtualAddress); + virtualAddress += virtualSize; + + } else if (sect.PointerToRawData > 0) { + // System.out.println("Dumping section " + i + "/" + sect.getName() + " at " + offset + " from " + sect.PointerToRawData + " (VA=" + virtualAddress + ")"); + out.position(offset); + this.m_channel.position(sect.PointerToRawData); + long sectoffset = offset; + + out.position(offset + sect.SizeOfRawData); + ByteBuffer padder = ByteBuffer.allocate(1); + out.write(padder, offset + sect.SizeOfRawData - 1); + + long outted = out.transferFrom(this.m_channel, offset, sect.SizeOfRawData); + offset += sect.SizeOfRawData; + // System.out.println("offset before alignment, " + offset); + + long rem = offset % this.m_header.FileAlignment; + if (rem != 0) { + offset += this.m_header.FileAlignment - rem; + } + // System.out.println("offset after alignment, " + offset); + + // long virtualSize = sect.SizeOfRawData; + // if ((virtualSize % peheader.SectionAlignment)>0) + // virtualSize += peheader.SectionAlignment - (virtualSize%peheader.SectionAlignment); + + sect.PointerToRawData = sectoffset; + // sect.SizeOfRawData = + sect.VirtualAddress = virtualAddress; + // sect.VirtualSize = virtualSize; + + virtualAddress += sect.VirtualSize; + if ((virtualAddress % peheader.SectionAlignment) > 0) + virtualAddress += peheader.SectionAlignment - (virtualAddress % peheader.SectionAlignment); + + } else { + // generally a BSS, with a virtual size but no + // data in the file... + // System.out.println("Dumping section " + i + " at " + offset + " from " + sect.PointerToRawData + " (VA=" + virtualAddress + ")"); + long virtualSize = sect.VirtualSize; + if ((virtualSize % peheader.SectionAlignment) > 0) + virtualSize += peheader.SectionAlignment - (virtualSize % peheader.SectionAlignment); + + sect.VirtualAddress = virtualAddress; + // sect.VirtualSize = virtualSize; + virtualAddress += virtualSize; + + } + } + + // + // Now that all the sections have been written, we have the + // correct VirtualAddress and Sizes, so we can update the new + // header and all the section headers... + + peheader.updateVAAndSize(m_sections, sections); + headbuffer = peheader.get(); + out.position(newexeoffset); + outputcount = out.write(headbuffer); + + // peheader.dump(System.out); + // System.out.println("Dumping the section again..."); + offset = oldmsheader.e_lfanew + (m_header.NumberOfRvaAndSizes * 8) + 24 + getPeHeaderOffset(); + out.position(offset); + for (int i = 0; i < sections.size(); i++) { + // System.out.println(" offset: " + out.position()); + PESection sect = (PESection)sections.get(i); + // sect.dump(System.out); + ByteBuffer buf = sect.get(); + outputcount = out.write(buf); + } + + fos.flush(); + fos.close(); + } + + /* + */ + + public void replaceDefaultIcon(ResIcon icon) throws Exception { + PEResourceDirectory resdir = getResourceDirectory(); + + PEResourceDirectory.DataEntry entry = resdir.getData("#14", null, null); + if (entry == null) { + throw new Exception("Can't find any icon group in the file!"); + } + + entry.Data.position(0); + // System.out.println("DataEntry found : " + entry + " (size=" + entry.Data.remaining() + ")"); + entry.Data.position(0); + + ResIconDir rid = new ResIconDir(entry.Data); + // System.out.println("ResIconDir :"); + // System.out.println(rid.toString()); + int iconid = rid.getEntries()[0].dwImageOffset; + // System.out.println("Icon Index: " + iconid); + + PEResourceDirectory.DataEntry iconentry = resdir.getData("#3", "#" + iconid, null); + iconentry.Data.position(0); + // System.out.println("Icon :"); + // System.out.println(icon.toString()); + + rid.getEntries()[0].bWidth = (short)icon.Width; + rid.getEntries()[0].bHeight = (short)(icon.Height / 2); + rid.getEntries()[0].bColorCount = (short)(1 << icon.BitsPerPixel); + rid.getEntries()[0].wBitCount = icon.BitsPerPixel; + rid.getEntries()[0].dwBytesInRes = icon.getData().remaining(); + + iconentry.Data = icon.getData(); + iconentry.Size = iconentry.Data.remaining(); + + entry.setData(rid.getData()); + } + +} diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEHeader.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEHeader.java new file mode 100644 index 00000000..da96141b --- /dev/null +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEHeader.java @@ -0,0 +1,482 @@ +/* + JSmooth: a VM wrapper toolkit for Windows + Copyright (C) 2003 Rodrigo Reyes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +/* + * PEHeader.java + * + * Created on 28 juillet 2003, 21:38 + */ + +package net.charabia.jsmoothgen.pe; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.util.Vector; + +/** + * @author Rodrigo Reyes + */ +public class PEHeader implements Cloneable { + private int PeMagic; // 0 + public int Machine; // 4 + public int NumberOfSections; // 6 + public long TimeDateStamp; // 8 + public long PointerToSymbolTable; // C + public long NumberOfSymbols; // 10 + public int SizeOfOptionalHeader; // 14 + public int Characteristics; // 16 + + // Optional Header + public int Magic; // 18 + public short MajorLinkerVersion; // 1a + public short MinorLinkerVersion; // 1b + public long SizeOfCode; // 1c + public long SizeOfInitializedData; // 20 + public long SizeOfUninitializedData; // 24 + public long AddressOfEntryPoint; // 28 + public long BaseOfCode; // 2c + public long BaseOfData; // NT additional fields. 30 + public long ImageBase; // 34 + public long SectionAlignment; // 38 + public long FileAlignment; // 3c + public int MajorOperatingSystemVersion; // 40 + public int MinorOperatingSystemVersion; // 42 + public int MajorImageVersion; // 44 + public int MinorImageVersion; // 46 + public int MajorSubsystemVersion; // 48 + public int MinorSubsystemVersion; // 4a + public long Reserved1; // 4c + public long SizeOfImage; // 50 + public long SizeOfHeaders; // 54 + public long CheckSum; // 58 + public int Subsystem; // 5c + public int DllCharacteristics; // 5e + public long SizeOfStackReserve; // 60 + public long SizeOfStackCommit; // 64 + public long SizeOfHeapReserve; // 68 + public long SizeOfHeapCommit; // 6c + public long LoaderFlags; // 70 + public long NumberOfRvaAndSizes; // 74 + + public long ExportDirectory_VA; // 78 + public long ExportDirectory_Size; // 7c + public long ImportDirectory_VA; // 80 + public long ImportDirectory_Size; // 84 + public long ResourceDirectory_VA; // 88 + public long ResourceDirectory_Size; // 8c + public long ExceptionDirectory_VA; // 90 + public long ExceptionDirectory_Size; // 94 + public long SecurityDirectory_VA; // 98 + public long SecurityDirectory_Size; // 9c + public long BaseRelocationTable_VA; // a0 + public long BaseRelocationTable_Size; // a4 + public long DebugDirectory_VA; // a8 + public long DebugDirectory_Size; // ac + public long ArchitectureSpecificData_VA; // b0 + public long ArchitectureSpecificData_Size; // b4 + public long RVAofGP_VA; // b8 + public long RVAofGP_Size; // bc + public long TLSDirectory_VA; // c0 + public long TLSDirectory_Size; // c4 + public long LoadConfigurationDirectory_VA; // c8 + public long LoadConfigurationDirectory_Size; // cc + public long BoundImportDirectoryinheaders_VA; // d0 + public long BoundImportDirectoryinheaders_Size; // d4 + public long ImportAddressTable_VA; // d8 + public long ImportAddressTable_Size; // dc + public long DelayLoadImportDescriptors_VA; // e0 + public long DelayLoadImportDescriptors_Size; // e4 + public long COMRuntimedescriptor_VA; // e8 + public long COMRuntimedescriptor_Size; // ec + + private long m_baseoffset; + private PEFile m_pe; + + /** + * Creates a new instance of PEHeader + */ + public PEHeader(PEFile pef, long baseoffset) { + m_pe = pef; + m_baseoffset = baseoffset; + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public void read() throws IOException { + FileChannel ch = m_pe.getChannel(); + ByteBuffer head = ByteBuffer.allocate(350); + head.order(ByteOrder.LITTLE_ENDIAN); + ch.position(m_baseoffset); + ch.read(head); + head.position(0); + + PeMagic = head.getInt(); + // System.out.println("MAGIC::: " + pemagic); + Machine = head.getShort(); // 4 + NumberOfSections = head.getShort(); // 6 + TimeDateStamp = head.getInt(); // 8 + PointerToSymbolTable = head.getInt(); // C + NumberOfSymbols = head.getInt(); // 10 + SizeOfOptionalHeader = head.getShort(); // 14 + Characteristics = head.getShort(); // 16 + // Optional Header + + Magic = head.getShort(); // 18 + MajorLinkerVersion = head.get(); // 1a + MinorLinkerVersion = head.get(); // 1b + SizeOfCode = head.getInt(); // 1c + SizeOfInitializedData = head.getInt(); // 20 + SizeOfUninitializedData = head.getInt(); // 24 + AddressOfEntryPoint = head.getInt(); // 28 + BaseOfCode = head.getInt(); // 2c + if (isPe32Plus()) { + ImageBase = head.getLong(); // 34 + } else { + BaseOfData = head.getInt(); // // NT additional fields. // 30 + ImageBase = head.getInt(); // 34 + } + SectionAlignment = head.getInt(); // 38 + FileAlignment = head.getInt(); // 3c + MajorOperatingSystemVersion = head.getShort(); // 40 + MinorOperatingSystemVersion = head.getShort(); // 42 + MajorImageVersion = head.getShort(); // 44 + MinorImageVersion = head.getShort(); // 46 + MajorSubsystemVersion = head.getShort(); // 48 + MinorSubsystemVersion = head.getShort(); // 4a + Reserved1 = head.getInt(); // 4c + SizeOfImage = head.getInt(); // 50 + SizeOfHeaders = head.getInt(); // 54 + CheckSum = head.getInt(); // 58 + Subsystem = head.getShort(); // 5c + DllCharacteristics = head.getShort(); // 5e + if (isPe32Plus()) { + SizeOfStackReserve = head.getLong(); // 60 + SizeOfStackCommit = head.getLong(); // 64 + SizeOfHeapReserve = head.getLong(); // 68 + SizeOfHeapCommit = head.getLong(); // 6c + } else { + SizeOfStackReserve = head.getInt(); // 60 + SizeOfStackCommit = head.getInt(); // 64 + SizeOfHeapReserve = head.getInt(); // 68 + SizeOfHeapCommit = head.getInt(); // 6c + } + LoaderFlags = head.getInt(); // 70 + NumberOfRvaAndSizes = head.getInt(); // 74 + + ExportDirectory_VA = head.getInt(); // 78 + ExportDirectory_Size = head.getInt(); // 7c + ImportDirectory_VA = head.getInt(); // 80 + ImportDirectory_Size = head.getInt(); // 84 + ResourceDirectory_VA = head.getInt(); // 88 + ResourceDirectory_Size = head.getInt(); // 8c + ExceptionDirectory_VA = head.getInt(); // 90 + ExceptionDirectory_Size = head.getInt(); // 94 + SecurityDirectory_VA = head.getInt(); // 98 + SecurityDirectory_Size = head.getInt(); // 9c + BaseRelocationTable_VA = head.getInt(); // a0 + BaseRelocationTable_Size = head.getInt(); // a4 + DebugDirectory_VA = head.getInt(); // a8 + DebugDirectory_Size = head.getInt(); // ac + ArchitectureSpecificData_VA = head.getInt(); // b0 + ArchitectureSpecificData_Size = head.getInt(); // b4 + RVAofGP_VA = head.getInt(); // b8 + RVAofGP_Size = head.getInt(); // bc + TLSDirectory_VA = head.getInt(); // c0 + TLSDirectory_Size = head.getInt(); // c4 + LoadConfigurationDirectory_VA = head.getInt(); // c8 + LoadConfigurationDirectory_Size = head.getInt(); // cc + BoundImportDirectoryinheaders_VA = head.getInt(); // d0 + BoundImportDirectoryinheaders_Size = head.getInt(); // d4 + ImportAddressTable_VA = head.getInt(); // d8 + ImportAddressTable_Size = head.getInt(); // dc + DelayLoadImportDescriptors_VA = head.getInt(); // e0 + DelayLoadImportDescriptors_Size = head.getInt(); // e4 + COMRuntimedescriptor_VA = head.getInt(); // e8 + COMRuntimedescriptor_Size = head.getInt(); // ec + } + + public void dump(PrintStream out) { + out.println("HEADER:"); + out.println("int Machine=" + Machine + " // 4"); + out.println("int NumberOfSections=" + NumberOfSections + " // 6"); + out.println("long TimeDateStamp=" + TimeDateStamp + " // 8"); + out.println("long PointerToSymbolTable=" + PointerToSymbolTable + " // C"); + out.println("long NumberOfSymbols=" + NumberOfSymbols + " // 10"); + out.println("int SizeOfOptionalHeader=" + SizeOfOptionalHeader + " // 14"); + out.println("int Characteristics=" + Characteristics + " // 16"); + // Optional Header + + out.println("int Magic=" + Magic + " // 18"); + out.println("short MajorLinkerVersion=" + MajorLinkerVersion + " // 1a"); + out.println("short MinorLinkerVersion=" + MinorLinkerVersion + " // 1b"); + out.println("long SizeOfCode=" + SizeOfCode + " // 1c"); + out.println("long SizeOfInitializedData=" + SizeOfInitializedData + " // 20"); + out.println("long SizeOfUninitializedData=" + SizeOfUninitializedData + " // 24"); + out.println("long AddressOfEntryPoint=" + AddressOfEntryPoint + " // 28"); + out.println("long BaseOfCode=" + BaseOfCode + " // 2c"); + out.println("long BaseOfData=" + BaseOfData + " // // NT additional fields. // 30"); + // + out.println("long ImageBase=" + ImageBase + " // 34"); + out.println("long SectionAlignment=" + SectionAlignment + " // 38"); + out.println("long FileAlignment=" + FileAlignment + " // 3c"); + out.println("int MajorOperatingSystemVersion=" + MajorOperatingSystemVersion + " // 40"); + out.println("int MinorOperatingSystemVersion=" + MinorOperatingSystemVersion + " // 42"); + out.println("int MajorImageVersion=" + MajorImageVersion + " // 44"); + out.println("int MinorImageVersion=" + MinorImageVersion + " // 46"); + out.println("int MajorSubsystemVersion=" + MajorSubsystemVersion + " // 48"); + out.println("int MinorSubsystemVersion=" + MinorSubsystemVersion + " // 4a"); + out.println("long Reserved1=" + Reserved1 + " // 4c"); + out.println("long SizeOfImage=" + SizeOfImage + " // 50"); + out.println("long SizeOfHeaders=" + SizeOfHeaders + " // 54"); + out.println("long CheckSum=" + CheckSum + " // 58"); + out.println("int Subsystem=" + Subsystem + " // 5c"); + out.println("int DllCharacteristics=" + DllCharacteristics + " // 5e"); + out.println("long SizeOfStackReserve=" + SizeOfStackReserve + " // 60"); + out.println("long SizeOfStackCommit=" + SizeOfStackCommit + " // 64"); + out.println("long SizeOfHeapReserve=" + SizeOfHeapReserve + " // 68"); + out.println("long SizeOfHeapCommit=" + SizeOfHeapCommit + " // 6c"); + out.println("long LoaderFlags=" + LoaderFlags + " // 70"); + out.println("long NumberOfRvaAndSizes=" + NumberOfRvaAndSizes + " // 74"); + + out.println("long ExportDirectory_VA=" + ExportDirectory_VA + " // 78"); + out.println("long ExportDirectory_Size=" + ExportDirectory_Size + " // 7c"); + out.println("long ImportDirectory_VA=" + ImportDirectory_VA + " // 80"); + out.println("long ImportDirectory_Size=" + ImportDirectory_Size + " // 84"); + out.println("long ResourceDirectory_VA=" + ResourceDirectory_VA + " // 88"); + out.println("long ResourceDirectory_Size=" + ResourceDirectory_Size + " // 8c"); + out.println("long ExceptionDirectory_VA=" + ExceptionDirectory_VA + " // 90"); + out.println("long ExceptionDirectory_Size=" + ExceptionDirectory_Size + " // 94"); + out.println("long SecurityDirectory_VA=" + SecurityDirectory_VA + " // 98"); + out.println("long SecurityDirectory_Size=" + SecurityDirectory_Size + " // 9c"); + out.println("long BaseRelocationTable_VA=" + BaseRelocationTable_VA + " // a0"); + out.println("long BaseRelocationTable_Size=" + BaseRelocationTable_Size + " // a4"); + out.println("long DebugDirectory_VA=" + DebugDirectory_VA + " // a8"); + out.println("long DebugDirectory_Size=" + DebugDirectory_Size + " // ac"); + out.println("long ArchitectureSpecificData_VA=" + ArchitectureSpecificData_VA + " // b0"); + out.println("long ArchitectureSpecificData_Size=" + ArchitectureSpecificData_Size + " // b4"); + out.println("long RVAofGP_VA=" + RVAofGP_VA + " // b8"); + out.println("long RVAofGP_Size=" + RVAofGP_Size + " // bc"); + out.println("long TLSDirectory_VA=" + TLSDirectory_VA + " // c0"); + out.println("long TLSDirectory_Size=" + TLSDirectory_Size + " // c4"); + out.println("long LoadConfigurationDirectory_VA=" + LoadConfigurationDirectory_VA + " // c8"); + out.println("long LoadConfigurationDirectory_Size=" + LoadConfigurationDirectory_Size + " // cc"); + out.println("long BoundImportDirectoryinheaders_VA=" + BoundImportDirectoryinheaders_VA + " // d0"); + out.println("long BoundImportDirectoryinheaders_Size=" + BoundImportDirectoryinheaders_Size + " // d4"); + out.println("long ImportAddressTable_VA=" + ImportAddressTable_VA + " // d8"); + out.println("long ImportAddressTable_Size=" + ImportAddressTable_Size + " // dc"); + out.println("long DelayLoadImportDescriptors_VA=" + DelayLoadImportDescriptors_VA + " // e0"); + out.println("long DelayLoadImportDescriptors_Size=" + DelayLoadImportDescriptors_Size + " // e4"); + out.println("long COMRuntimedescriptor_VA=" + COMRuntimedescriptor_VA + " // e8"); + out.println("long COMRuntimedescriptor_Size=" + COMRuntimedescriptor_Size + " // ec"); + } + + public ByteBuffer get() { + ByteBuffer head = ByteBuffer.allocate(16 + this.SizeOfOptionalHeader); + head.order(ByteOrder.LITTLE_ENDIAN); + head.position(0); + + head.putInt(PeMagic); + + head.putShort((short)Machine); // 4 + head.putShort((short)NumberOfSections); // 6 + head.putInt((int)TimeDateStamp); // 8 + head.putInt((int)PointerToSymbolTable); // C + head.putInt((int)NumberOfSymbols); // 10 + head.putShort((short)SizeOfOptionalHeader); // 14 + head.putShort((short)Characteristics); // 16 + // Optional Header + + head.putShort((short)Magic); // 18 + head.put((byte)MajorLinkerVersion); // 1a + head.put((byte)MinorLinkerVersion); // 1b + head.putInt((int)SizeOfCode); // 1c + head.putInt((int)SizeOfInitializedData); // 20 + head.putInt((int)SizeOfUninitializedData); // 24 + head.putInt((int)AddressOfEntryPoint); // 28 + head.putInt((int)BaseOfCode); // 2c + if (isPe32Plus()) { + head.putLong(ImageBase); // 34 + } else { + head.putInt((int)BaseOfData); // // NT additional fields. // 30 + head.putInt((int)ImageBase); // 34 + } + head.putInt((int)SectionAlignment); // 38 + head.putInt((int)FileAlignment); // 3c + head.putShort((short)MajorOperatingSystemVersion); // 40 + head.putShort((short)MinorOperatingSystemVersion); // 42 + head.putShort((short)MajorImageVersion); // 44 + head.putShort((short)MinorImageVersion); // 46 + head.putShort((short)MajorSubsystemVersion); // 48 + head.putShort((short)MinorSubsystemVersion); // 4a + head.putInt((int)Reserved1); // 4c + head.putInt((int)SizeOfImage); // 50 + head.putInt((int)SizeOfHeaders); // 54 + head.putInt((int)CheckSum); // 58 + head.putShort((short)Subsystem); // 5c + head.putShort((short)DllCharacteristics); // 5e + if (isPe32Plus()) { + head.putLong(SizeOfStackReserve); // 60 + head.putLong(SizeOfStackCommit); // 64 + head.putLong(SizeOfHeapReserve); // 68 + head.putLong(SizeOfHeapCommit); // 6c + } else { + head.putInt((int)SizeOfStackReserve); // 60 + head.putInt((int)SizeOfStackCommit); // 64 + head.putInt((int)SizeOfHeapReserve); // 68 + head.putInt((int)SizeOfHeapCommit); // 6c + } + head.putInt((int)LoaderFlags); // 70 + head.putInt((int)NumberOfRvaAndSizes); // 74 + + head.putInt((int)ExportDirectory_VA); // 78 + head.putInt((int)ExportDirectory_Size); // 7c + head.putInt((int)ImportDirectory_VA); // 80 + head.putInt((int)ImportDirectory_Size); // 84 + head.putInt((int)ResourceDirectory_VA); // 88 + head.putInt((int)ResourceDirectory_Size); // 8c + head.putInt((int)ExceptionDirectory_VA); // 90 + head.putInt((int)ExceptionDirectory_Size); // 94 + head.putInt((int)SecurityDirectory_VA); // 98 + head.putInt((int)SecurityDirectory_Size); // 9c + head.putInt((int)BaseRelocationTable_VA); // a0 + head.putInt((int)BaseRelocationTable_Size); // a4 + head.putInt((int)DebugDirectory_VA); // a8 + head.putInt((int)DebugDirectory_Size); // ac + head.putInt((int)ArchitectureSpecificData_VA); // b0 + head.putInt((int)ArchitectureSpecificData_Size); // b4 + head.putInt((int)RVAofGP_VA); // b8 + head.putInt((int)RVAofGP_Size); // bc + head.putInt((int)TLSDirectory_VA); // c0 + head.putInt((int)TLSDirectory_Size); // c4 + head.putInt((int)LoadConfigurationDirectory_VA); // c8 + head.putInt((int)LoadConfigurationDirectory_Size); // cc + head.putInt((int)BoundImportDirectoryinheaders_VA); // d0 + head.putInt((int)BoundImportDirectoryinheaders_Size); // d4 + head.putInt((int)ImportAddressTable_VA); // d8 + head.putInt((int)ImportAddressTable_Size); // dc + head.putInt((int)DelayLoadImportDescriptors_VA); // e0 + head.putInt((int)DelayLoadImportDescriptors_Size); // e4 + head.putInt((int)COMRuntimedescriptor_VA); // e8 + head.putInt((int)COMRuntimedescriptor_Size); // ec + + head.position(0); + return head; + } + + public void updateVAAndSize(Vector oldsections, Vector newsections) { + long codebase = findNewVA(this.BaseOfCode, oldsections, newsections); + long codesize = findNewSize(this.BaseOfCode, oldsections, newsections); + // System.out.println("New BaseOfCode=" + codebase + " (size=" + codesize + ")"); + this.BaseOfCode = codebase; + this.SizeOfCode = codesize; + + this.AddressOfEntryPoint = findNewVA(this.AddressOfEntryPoint, oldsections, newsections); + + long database = findNewVA(this.BaseOfData, oldsections, newsections); + long datasize = findNewSize(this.BaseOfData, oldsections, newsections); + // System.out.println("New BaseOfData=" + database + " (size=" + datasize + ")"); + this.BaseOfData = database; + + long imagesize = 0; + for (int i = 0; i < newsections.size(); i++) { + PESection sect = (PESection)newsections.get(i); + long curmax = sect.VirtualAddress + sect.VirtualSize; + if (curmax > imagesize) + imagesize = curmax; + } + this.SizeOfImage = imagesize; + + // this.SizeOfInitializedData = datasize; + + ExportDirectory_Size = findNewSize(ExportDirectory_VA, oldsections, newsections); + ExportDirectory_VA = findNewVA(ExportDirectory_VA, oldsections, newsections); + ImportDirectory_Size = findNewSize(ImportDirectory_VA, oldsections, newsections); + ImportDirectory_VA = findNewVA(ImportDirectory_VA, oldsections, newsections); + ResourceDirectory_Size = findNewSize(ResourceDirectory_VA, oldsections, newsections); + ResourceDirectory_VA = findNewVA(ResourceDirectory_VA, oldsections, newsections); + ExceptionDirectory_Size = findNewSize(ExceptionDirectory_VA, oldsections, newsections); + ExceptionDirectory_VA = findNewVA(ExceptionDirectory_VA, oldsections, newsections); + SecurityDirectory_Size = findNewSize(SecurityDirectory_VA, oldsections, newsections); + SecurityDirectory_VA = findNewVA(SecurityDirectory_VA, oldsections, newsections); + BaseRelocationTable_Size = findNewSize(BaseRelocationTable_VA, oldsections, newsections); + BaseRelocationTable_VA = findNewVA(BaseRelocationTable_VA, oldsections, newsections); + DebugDirectory_Size = findNewSize(DebugDirectory_VA, oldsections, newsections); + DebugDirectory_VA = findNewVA(DebugDirectory_VA, oldsections, newsections); + ArchitectureSpecificData_Size = findNewSize(ArchitectureSpecificData_VA, oldsections, newsections); + ArchitectureSpecificData_VA = findNewVA(ArchitectureSpecificData_VA, oldsections, newsections); + RVAofGP_Size = findNewSize(RVAofGP_VA, oldsections, newsections); + RVAofGP_VA = findNewVA(RVAofGP_VA, oldsections, newsections); + TLSDirectory_Size = findNewSize(TLSDirectory_VA, oldsections, newsections); + TLSDirectory_VA = findNewVA(TLSDirectory_VA, oldsections, newsections); + LoadConfigurationDirectory_Size = findNewSize(LoadConfigurationDirectory_VA, oldsections, newsections); + LoadConfigurationDirectory_VA = findNewVA(LoadConfigurationDirectory_VA, oldsections, newsections); + BoundImportDirectoryinheaders_Size = findNewSize(BoundImportDirectoryinheaders_VA, oldsections, newsections); + BoundImportDirectoryinheaders_VA = findNewVA(BoundImportDirectoryinheaders_VA, oldsections, newsections); + ImportAddressTable_Size = findNewSize(ImportAddressTable_VA, oldsections, newsections); + ImportAddressTable_VA = findNewVA(ImportAddressTable_VA, oldsections, newsections); + DelayLoadImportDescriptors_Size = findNewSize(DelayLoadImportDescriptors_VA, oldsections, newsections); + DelayLoadImportDescriptors_VA = findNewVA(DelayLoadImportDescriptors_VA, oldsections, newsections); + COMRuntimedescriptor_Size = findNewSize(COMRuntimedescriptor_VA, oldsections, newsections); + COMRuntimedescriptor_VA = findNewVA(COMRuntimedescriptor_VA, oldsections, newsections); + } + + public boolean isPe32Plus() { + return Magic == 523; + } + + private long findNewVA(long current, Vector oldsections, Vector newsections) { + for (int i = 0; i < oldsections.size(); i++) { + PESection sect = (PESection)oldsections.get(i); + if (sect.VirtualAddress == current) { + PESection newsect = (PESection)newsections.get(i); + + // System.out.println("Translation VA found for " + current + " = " + i + " (" +newsect.VirtualAddress + ")=" + newsect.getName()); + return newsect.VirtualAddress; + } else if ((current > sect.VirtualAddress) && (current < (sect.VirtualAddress + sect.VirtualSize))) { + long diff = current - sect.VirtualAddress; + PESection newsect = (PESection)newsections.get(i); + // System.out.println("Translation VA found INSIDE " + current + " = " + i + " (" +newsect.VirtualAddress + ")=" + newsect.getName()); + return newsect.VirtualAddress + diff; + } + } + + + return 0; + } + + private long findNewSize(long current, Vector oldsections, Vector newsections) { + for (int i = 0; i < oldsections.size(); i++) { + PESection sect = (PESection)oldsections.get(i); + if (sect.VirtualAddress == current) { + PESection newsect = (PESection)newsections.get(i); + // System.out.println("Translation Size found for " + current + " = " + i + " (" +newsect.VirtualAddress + ")=" + newsect.getName()); + // System.out.println(" Old size " + sect.VirtualSize + " vs new size " + newsect.VirtualSize); + return newsect.VirtualSize; + } + } + return 0; + } + +} diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEResourceDirectory.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEResourceDirectory.java new file mode 100644 index 00000000..09676ad6 --- /dev/null +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEResourceDirectory.java @@ -0,0 +1,625 @@ +/* + JSmooth: a VM wrapper toolkit for Windows + Copyright (C) 2003 Rodrigo Reyes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +/* + * PEResourceDirectory.java + * + * Created on 2 aout 2003, 01:28 + */ + +package net.charabia.jsmoothgen.pe; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.util.Iterator; +import java.util.Vector; + +/** + * @author Rodrigo + */ +public class PEResourceDirectory { + + /* + typedef struct IMAGE_RESOURCE_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint16_t NumberOfNamedEntries; + uint16_t NumberOfIdEntries; + } + */ + + public class DataEntry { + long OffsetToData; // To update at each change + long Size; + long CodePage; // never changed + long Reserved; // never changed + ByteBuffer Data; + + public DataEntry(ByteBuffer data) { + this.Data = data; + this.Size = data.capacity(); + } + + public DataEntry(FileChannel chan, long offset) throws IOException { + long orgpos = chan.position(); + chan.position(PEResourceDirectory.this.m_offsetBase + offset); + ByteBuffer buf = ByteBuffer.allocate(16); + buf.order(ByteOrder.LITTLE_ENDIAN); + chan.read(buf); + buf.position(0); + + OffsetToData = buf.getInt(); + Size = buf.getInt(); + CodePage = buf.getInt(); + Reserved = buf.getInt(); + + long datapos = PEResourceDirectory.this.m_master.PointerToRawData + (OffsetToData - PEResourceDirectory.this.m_master.VirtualAddress); + Data = ByteBuffer.allocate((int)Size); + Data.order(ByteOrder.LITTLE_ENDIAN); + chan.position(datapos); + chan.read(Data); + Data.position(0); + + chan.position(orgpos); + } + + public int diskSize() { + int size = 16 + (int)this.Size; + if ((size % 4) > 0) + size += 4 - (size % 4); + return size; + } + + public void dump(PrintStream out, int level) { + indent(level, out); + out.println("OffsetToData=" + OffsetToData); + indent(level, out); + out.println("Size=" + Size); + indent(level, out); + out.println("CodePage=" + CodePage); + indent(level, out); + out.println("Reserved=" + Reserved); + indent(level, out); + out.print("Data={ "); + for (int i = 0; i < this.Data.capacity(); i++) { + out.print("" + Integer.toHexString((byte)Data.get()) + ","); + } + out.println(" }"); + + } + + private void indent(int level, PrintStream out) { + for (int i = 0; i < level; i++) + out.print(" "); + } + + public int buildBuffer(ByteBuffer buffer, long virtualBaseOffset, int dataOffset) { + // System.out.println("Building Data Entry buffer @ " + buffer.position() + " (" + dataOffset + ")"); + + dataOffset = buffer.position() + 16; + + buffer.putInt((int)(dataOffset + virtualBaseOffset)); + buffer.putInt((int)Size); + buffer.putInt((int)CodePage); + buffer.putInt((int)Reserved); + + Data.position(0); + buffer.put(Data); + + dataOffset += Size; + if ((dataOffset % 4) > 0) + dataOffset += (4 - (dataOffset % 4)); + + return dataOffset; + } + + public void setData(ByteBuffer data) { + Data = data; + Size = data.capacity(); + } + } + + public class ResourceEntry { + int Id; + String Name; + + ImageResourceDirectory Directory; + DataEntry Data; + + public ResourceEntry(int id, DataEntry data) { + this.Id = id; + this.Data = data; + } + + public ResourceEntry(String name, DataEntry data) { + this.Name = name; + this.Data = data; + } + + public ResourceEntry(int id, ImageResourceDirectory dir) { + this.Id = id; + this.Directory = dir; + } + + public ResourceEntry(String name, ImageResourceDirectory dir) { + this.Name = name; + this.Directory = dir; + } + + public ResourceEntry(FileChannel chan) throws IOException { + // System.out.println("Resource Entry Offset: " + chan.position()); + ByteBuffer buf = ByteBuffer.allocate(8); + buf.order(ByteOrder.LITTLE_ENDIAN); + chan.read(buf); + buf.position(0); + long orgchanpos = chan.position(); + int val = buf.getInt(); + long offsetToData = buf.getInt(); + // System.out.println("Entry: Val=" + val); + // System.out.println(" Off=" + offsetToData); + + if (val < 0) { + val &= 0x7FFFFFFF; + Name = extractStringAt(chan, val); + Id = -1; + // System.out.println(" String at " + val + " = " + Name); + } else { + Id = val; + } + + if (offsetToData < 0) { + offsetToData &= 0x7FFFFFFF; + long orgpos = chan.position(); + chan.position(PEResourceDirectory.this.m_offsetBase + offsetToData); + Directory = new PEResourceDirectory.ImageResourceDirectory(chan); + chan.position(orgpos); + } else { + Data = new DataEntry(chan, offsetToData); + } + } + + public String extractStringAt(FileChannel chan, int offset) throws IOException { + long orgchanpos = chan.position(); + chan.position(PEResourceDirectory.this.m_offsetBase + offset); + + ByteBuffer sizebuf = ByteBuffer.allocate(2); + sizebuf.order(ByteOrder.LITTLE_ENDIAN); + chan.read(sizebuf); + sizebuf.position(0); + + int size = sizebuf.getShort(); + ByteBuffer buffer = ByteBuffer.allocate(size * 2); + buffer.order(ByteOrder.LITTLE_ENDIAN); + chan.read(buffer); + buffer.position(0); + + StringBuffer buf = new StringBuffer(size); + for (int i = 0; i < size; i++) { + int c = buffer.getShort(); + buf.append((char)c); + } + + chan.position(orgchanpos); + return buf.toString(); + } + + public int diskSize() { + int size = 8; + if (Name != null) + size += (Name.length() * 2) + 2; + + if (Directory != null) + size += Directory.diskSize(); + else if (Data != null) + size += Data.diskSize(); + + if ((size % 4) > 0) + size += 4 - (size % 4); + return size; + } + + public void dump(PrintStream out, int level) { + indent(level, out); + if (this.Name != null) + out.println("Name=" + Name); + else + out.println("Id=#" + Id); + + indent(level, out); + if (this.Directory != null) { + out.println("ENTRY: DIRECTORY POINTER"); + this.Directory.dump(out, level + 1); + } else { + out.println("ENTRY: DATA ENTRY"); + Data.dump(out, level + 1); + } + } + + private void indent(int level, PrintStream out) { + for (int i = 0; i < level; i++) + out.print(" "); + } + + public int buildBuffer(ByteBuffer buffer, long virtualBaseOffset, int dataOffset) { + // System.out.println("Building Resource Entry buffer " + Name + "/" + Id + " @ " + buffer.position() + " (" + dataOffset + ")"); + if (Name != null) { + buffer.putInt((int)(dataOffset | 0x80000000)); + + int stringoffset = dataOffset; + ByteBuffer strbuf = ByteBuffer.allocate(Name.length() * 2 + 2); + strbuf.order(ByteOrder.LITTLE_ENDIAN); + + strbuf.putShort((short)Name.length()); + for (int i = 0; i < Name.length(); i++) { + strbuf.putShort((short)Name.charAt(i)); + } + strbuf.position(0); + + long oldpos = buffer.position(); + buffer.position(dataOffset); + buffer.put(strbuf); + dataOffset += Name.length() * 2 + 2; + if ((dataOffset % 4) != 0) + dataOffset += 4 - (dataOffset % 4); + buffer.position((int) oldpos); + } else { + buffer.putInt(Id); + } + + if (Directory != null) { + buffer.putInt((int)(dataOffset | 0x80000000)); + + int oldpos = buffer.position(); + buffer.position(dataOffset); + int dirsize = Directory.buildBuffer(buffer, virtualBaseOffset); + dataOffset = dirsize; + buffer.position(oldpos); + + } else if (Data != null) { + buffer.putInt(dataOffset); + int oldpos = buffer.position(); + buffer.position(dataOffset); + dataOffset = Data.buildBuffer(buffer, virtualBaseOffset, dataOffset); + buffer.position(oldpos); + } else { + throw new RuntimeException("Directory and Data are both null!"); + } + + return dataOffset; + } + } + + public class ImageResourceDirectory { + long Characteristics; // uint32_t + long TimeDateStamp; // uint32_t + int MajorVersion; // uint16_t + int MinorVersion; // uint16_t + int NumberOfNamedEntries; // uint16_t + int NumberOfIdEntries; // uint16_t + Vector NamedEntries = new Vector(); + Vector IdEntries = new Vector(); + + public ImageResourceDirectory() { + } + + public ImageResourceDirectory(FileChannel chan) throws IOException { + ByteBuffer header = ByteBuffer.allocate(16); + header.order(ByteOrder.LITTLE_ENDIAN); + chan.read(header); + header.position(0); + + Characteristics = header.getInt(); + TimeDateStamp = header.getInt(); + MajorVersion = header.getShort(); + MinorVersion = header.getShort(); + NumberOfNamedEntries = header.getShort(); + NumberOfIdEntries = header.getShort(); + + for (int i = 0; i < NumberOfNamedEntries; i++) { + ResourceEntry re = new ResourceEntry(chan); + NamedEntries.add(re); + } + for (int i = 0; i < NumberOfIdEntries; i++) { + ResourceEntry re = new ResourceEntry(chan); + IdEntries.add(re); + } + } + + public void addNamedEntry(ResourceEntry entry) { + this.NamedEntries.add(entry); + } + + public void addIdEntry(ResourceEntry entry) { + this.IdEntries.add(entry); + } + + public void addEntry(ResourceEntry entry) { + if (entry.Name != null) + addNamedEntry(entry); + else + addIdEntry(entry); + } + + public void dump(PrintStream out, int level) { + indent(level, out); + out.println("Directory: "); + indent(level, out); + out.println("Characteristics=" + this.Characteristics); + indent(level, out); + out.println("TimeDateStamp=" + this.TimeDateStamp); + indent(level, out); + out.println("MajorVersion=" + this.MajorVersion); + indent(level, out); + out.println("MinorVersion=" + this.MinorVersion); + indent(level, out); + out.println("NumberOfNamedEntries=" + this.NumberOfNamedEntries); + indent(level, out); + out.println("NumberOfIdEntries=" + this.NumberOfIdEntries); + indent(level, out); + out.println("Named Entries:"); + for (int i = 0; i < NumberOfNamedEntries; i++) { + ResourceEntry re = (ResourceEntry)NamedEntries.get(i); + re.dump(out, level + 1); + } + indent(level, out); + out.println("Id Entries:"); + for (int i = 0; i < NumberOfIdEntries; i++) { + ResourceEntry re = (ResourceEntry)IdEntries.get(i); + re.dump(out, level + 1); + } + } + + private void indent(int level, PrintStream out) { + for (int i = 0; i < level; i++) + out.print(" "); + } + + public int diskSize() { + int size = 16; + for (int i = 0; i < this.NamedEntries.size(); i++) { + ResourceEntry re = (ResourceEntry)NamedEntries.get(i); + size += re.diskSize(); + } + for (int i = 0; i < this.IdEntries.size(); i++) { + ResourceEntry re = (ResourceEntry)IdEntries.get(i); + size += re.diskSize(); + } + + if ((size % 4) > 0) + size += 4 - (size % 4); + + return size; + } + + public int buildBuffer(ByteBuffer buffer, long virtualBaseOffset) { + // System.out.println("Building Directory Entry buffer @ " + buffer.position()); + + buffer.putInt((int)this.Characteristics); + buffer.putInt((int)this.TimeDateStamp); + buffer.putShort((short)this.MajorVersion); + buffer.putShort((short)this.MinorVersion); + buffer.putShort((short)this.NamedEntries.size()); + buffer.putShort((short)this.IdEntries.size()); + + int dataOffset = buffer.position() + (NamedEntries.size() * 8) + (IdEntries.size() * 8); + + for (int i = 0; i < this.NamedEntries.size(); i++) { + ResourceEntry re = (ResourceEntry)this.NamedEntries.get(i); + dataOffset = re.buildBuffer(buffer, virtualBaseOffset, dataOffset); + } + + for (int i = 0; i < this.IdEntries.size(); i++) { + ResourceEntry re = (ResourceEntry)this.IdEntries.get(i); + dataOffset = re.buildBuffer(buffer, virtualBaseOffset, dataOffset); + } + + buffer.position(dataOffset); + return dataOffset; + } + + public ResourceEntry getResourceEntry(String name) { + // If name == null, get the first entry in lexical + // order. If no entry in lexical order, choose the + // lowest integer id entry. + if (name == null) { + if (NamedEntries.size() > 0) { + return (PEResourceDirectory.ResourceEntry)NamedEntries.get(0); + } + if (IdEntries.size() > 0) { + return (PEResourceDirectory.ResourceEntry)IdEntries.get(0); + } + return null; + } + + if ((name.length() > 0) && (name.charAt(0) == '#')) { + try { + String nb = name.substring(1); + int i = Integer.parseInt(nb); + return getResourceEntry(i); + } catch (Exception exc) { + exc.printStackTrace(); + } + } + + for (Iterator i = this.NamedEntries.iterator(); i.hasNext();) { + ResourceEntry re = (ResourceEntry)i.next(); + if (name.equals(re.Name)) { + return re; + } + } + return null; + } + + public ResourceEntry getResourceEntry(int id) { + for (Iterator i = this.IdEntries.iterator(); i.hasNext();) { + ResourceEntry re = (ResourceEntry)i.next(); + if (id == re.Id) { + return re; + } + } + return null; + } + + } + + PESection m_master; + PEFile m_file; + long m_offsetBase; + + PEResourceDirectory.ImageResourceDirectory m_root; + + /** + * Creates a new instance of PEResourceDirectory + */ + public PEResourceDirectory(PEFile file, PESection sect) throws IOException { + m_master = sect; + m_file = file; + m_offsetBase = sect.PointerToRawData; + init(); + + // System.out.println("--------\nTOTAL SIZE: " + m_root.diskSize()); + + // System.out.println("\n\n"); + } + + public void init() throws IOException { + // / System.out.println("RESOURCE INIT"); + // System.out.println(" Offset: " + m_master.PointerToRawData); + FileChannel chan = m_file.getChannel(); + chan.position(m_master.PointerToRawData); + PEResourceDirectory.ImageResourceDirectory dir = new PEResourceDirectory.ImageResourceDirectory(chan); + // System.out.println("-----------------\nDUMP\n---------------"); + m_root = dir; + + // dir.dump(System.out, 0); + } + + public void dump(PrintStream out) { + m_root.dump(out, 0); + } + + public int size() { + return m_root.diskSize(); + } + + public ByteBuffer buildResource(long virtualBaseOffset) { + // System.out.println("BUILDING RESOURCE / VIRTUAL: " + virtualBaseOffset); + int resourceSize = m_root.diskSize(); + ByteBuffer resbuf = ByteBuffer.allocate(resourceSize); + resbuf.order(ByteOrder.LITTLE_ENDIAN); + resbuf.position(0); + m_root.buildBuffer(resbuf, virtualBaseOffset); + return resbuf; + } + + public PEResourceDirectory.ImageResourceDirectory getRoot() { + return m_root; + } + + public boolean replaceManifest(int resourceId, int langId, ByteBuffer data) { + ResourceEntry catEntry = m_root.getResourceEntry(24); + if ((catEntry != null) && (catEntry.Directory != null)) { + ResourceEntry identEntry = catEntry.Directory.getResourceEntry(resourceId); + if ((identEntry != null) && (identEntry.Directory != null)) { + ResourceEntry langEntry = identEntry.Directory.getResourceEntry(langId); + if ((langEntry != null) && (langEntry.Data != null)) { + DataEntry dataslot = langEntry.Data; + dataslot.setData(data); + return true; + } + } + } + return false; + } + + public boolean replaceResource(String catId, int resourceId, int langId, ByteBuffer data) { + ResourceEntry catEntry = m_root.getResourceEntry(catId); + if ((catEntry != null) && (catEntry.Directory != null)) { + ResourceEntry identEntry = catEntry.Directory.getResourceEntry(resourceId); + if ((identEntry != null) && (identEntry.Directory != null)) { + ResourceEntry langEntry = identEntry.Directory.getResourceEntry(langId); + if ((langEntry != null) && (langEntry.Data != null)) { + DataEntry dataslot = langEntry.Data; + dataslot.setData(data); + return true; + } + } + } + return false; + } + + public void addNewResource(String catId, String resourceId, String languageId, ByteBuffer data) { + DataEntry dataEntry = new DataEntry(data); + ResourceEntry languageEntry = buildResourceEntry(languageId, dataEntry); + ImageResourceDirectory languageDir = new ImageResourceDirectory(); + + languageDir.TimeDateStamp = 0x3F2CCF64; + languageDir.addEntry(languageEntry); + + ResourceEntry identEntry = buildResourceEntry(resourceId, languageDir); + + ImageResourceDirectory identDir = new ImageResourceDirectory(); + identDir.TimeDateStamp = 0x3F2CCF64; + identDir.addEntry(identEntry); + + ResourceEntry catEntry = buildResourceEntry(catId, identDir); + m_root.addEntry(catEntry); + } + + public DataEntry getData(String catId, String resourceId, String langId) { + ResourceEntry catEntry = m_root.getResourceEntry(catId); + if ((catEntry != null) && (catEntry.Directory != null)) { + ResourceEntry identEntry = catEntry.Directory.getResourceEntry(resourceId); + if ((identEntry != null) && (identEntry.Directory != null)) { + ResourceEntry langEntry = identEntry.Directory.getResourceEntry(langId); + if ((langEntry != null) && (langEntry.Data != null)) { + DataEntry dataslot = langEntry.Data; + return dataslot; + } + } + } + return null; + } + + public ResourceEntry buildResourceEntry(String id, DataEntry data) { + if ((id.length() > 1) && (id.charAt(0) == '#')) { + int intid = Integer.parseInt(id.substring(1)); + return new ResourceEntry(intid, data); + } + + return new ResourceEntry(id, data); + } + + + public ResourceEntry buildResourceEntry(String id, ImageResourceDirectory dir) { + if ((id.length() > 1) && (id.charAt(0) == '#')) { + int intid = Integer.parseInt(id.substring(1)); + return new ResourceEntry(intid, dir); + } + + return new ResourceEntry(id, dir); + } + +} diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PESection.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PESection.java new file mode 100644 index 00000000..bbe857be --- /dev/null +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PESection.java @@ -0,0 +1,133 @@ +/* + JSmooth: a VM wrapper toolkit for Windows + Copyright (C) 2003 Rodrigo Reyes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* + * PESection.java + * + * Created on 29 juillet 2003, 21:34 + */ + +package net.charabia.jsmoothgen.pe; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; + +/** + * @author Rodrigo + */ +public class PESection implements Cloneable { + byte[] ANSI_Name; // Name of the Section. Can be anything (0)(8BYTES) + long VirtualSize; // The size of the section when it is mapped to memory. Must be a multiple of 4096. (8)(DWORD) + long VirtualAddress; // An rva to where it should be mapped in memory. (12)(DWORD) + long SizeOfRawData; // The size of the section in the PE file. Must be a multiple of 512 (16)(DWORD) + long PointerToRawData; // A file based offset which points to the location of this sections data (20)(DWORD) + long PointerToRelocations; // In EXE's this field is meaningless, and is set 0 (24)(DWORD) + long PointerToLinenumbers; // This is the file-based offset of the line number table. This field is only used for debug purposes, and is usualy set to 0 (28)(DWORD) + int NumberOfRelocations; // In EXE's this field is meaningless, and is set 0 (32)(WORD) + int NumberOfLinenumbers; // The number of line numbers in the line number table for this section. This field is only used for debug purposes, and is usualy set to 0 (34)(WORD) + long Characteristics; // The kind of data stored in this section ie. Code, Data, Import data, Relocation data (36)(DWORD) + + private long m_baseoffset; + private PEFile m_pe; + + /** + * Creates a new instance of PESection + */ + public PESection(PEFile pef, long baseoffset) { + m_pe = pef; + m_baseoffset = baseoffset; + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public String getName() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < 8; i++) + buffer.append((char) ANSI_Name[i]); + return buffer.toString(); + } + + public void read() throws IOException { + FileChannel ch = m_pe.getChannel(); + ByteBuffer head = ByteBuffer.allocate(40); + head.order(ByteOrder.LITTLE_ENDIAN); + ch.position(m_baseoffset); + ch.read(head); + head.position(0); + + ANSI_Name = new byte[8]; + for (int i = 0; i < 8; i++) + ANSI_Name[i] = head.get(); + + VirtualSize = head.getInt(); + VirtualAddress = head.getInt(); + SizeOfRawData = head.getInt(); + PointerToRawData = head.getInt(); + PointerToRelocations = head.getInt(); + PointerToLinenumbers = head.getInt(); + NumberOfRelocations = head.getShort(); + NumberOfLinenumbers = head.getShort(); + Characteristics = head.getInt(); + } + + public void dump(PrintStream out) { + out.println("SECTION:"); + out.println(" Name= "+getName()); + out.println(" VirtualSize= " + VirtualSize + " // The size of the section when it is mapped to memory. Must be a multiple of 4096. (8)(DWORD)"); + out.println(" VirtualAddress= " + VirtualAddress + " // An rva to where it should be mapped in memory. (12)(DWORD)"); + out.println(" SizeOfRawData= " + SizeOfRawData + " // The size of the section in the PE file. Must be a multiple of 512 (16)(DWORD)"); + out.println(" PointerToRawData= " + PointerToRawData + " // A file based offset which points to the location of this sections data (20)(DWORD)"); + out.println(" PointerToRelocations= " + PointerToRelocations + " // In EXE's this field is meaningless, and is set 0 (24)(DWORD)"); + out.println(" PointerToLinenumbers= " + PointerToLinenumbers + " // This is the file-based offset of the line number table. This field is only used for debug purposes, and is usualy set to 0 (28)(DWORD)"); + out.println(" NumberOfRelocations= " + NumberOfRelocations + " // In EXE's this field is meaningless, and is set 0 (32)(WORD)"); + out.println(" NumberOfLinenumbers= " + NumberOfLinenumbers + " // The number of line numbers in the line number table for this section. This field is only used for debug purposes, and is usualy set to 0 (34)(WORD)"); + out.println(" Characteristics= " + Characteristics + " // The kind of data stored in this section ie. Code, Data, Import data, Relocation data (36)(DWORD)"); + + } + + + public ByteBuffer get() { + ByteBuffer head = ByteBuffer.allocate(40); + head.order(ByteOrder.LITTLE_ENDIAN); + head.position(0); + + for (int i = 0; i < 8; i++) + head.put((byte)ANSI_Name[i]); + + head.putInt((int)VirtualSize); + head.putInt((int)VirtualAddress); + head.putInt((int)SizeOfRawData); + head.putInt((int)PointerToRawData); + head.putInt((int)PointerToRelocations); + head.putInt((int)PointerToLinenumbers); + head.putShort((short)NumberOfRelocations); + head.putShort((short)NumberOfLinenumbers); + head.putInt((int)Characteristics); + + head.position(0); + return head; + } + +}