mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-13 11:12:22 -05:00
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
This commit is contained in:
parent
3a058507c9
commit
b35b3db630
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,408 @@
|
||||
/*
|
||||
JSmooth: a VM wrapper toolkit for Windows
|
||||
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
|
||||
|
||||
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<props.length; i++)
|
||||
// System.out.println("SET PROPERTY: " + props[i].getIdName() + "=" + props[i].getValue());
|
||||
|
||||
m_skelproperties = props;
|
||||
fireChanged();
|
||||
}
|
||||
|
||||
public JSmoothModelBean.Property[] getSkeletonProperties() {
|
||||
return m_skelproperties;
|
||||
}
|
||||
|
||||
public void setNoJvmMessage(String msg) {
|
||||
m_noJvmMessage = msg;
|
||||
fireChanged();
|
||||
}
|
||||
|
||||
public String getNoJvmMessage() {
|
||||
return m_noJvmMessage;
|
||||
}
|
||||
|
||||
public void setNoJvmURL(String url) {
|
||||
m_noJvmURL = url;
|
||||
fireChanged();
|
||||
}
|
||||
|
||||
public String getNoJvmURL() {
|
||||
return m_noJvmURL;
|
||||
}
|
||||
|
||||
public String getBundledJVMPath() {
|
||||
return m_bundledJVM;
|
||||
}
|
||||
|
||||
public void setBundledJVMPath(String path) {
|
||||
m_bundledJVM = path;
|
||||
fireChanged();
|
||||
}
|
||||
|
||||
public void setJavaProperties(JavaPropertyPair[] pairs) {
|
||||
m_javaprops = pairs;
|
||||
}
|
||||
|
||||
public JavaPropertyPair[] getJavaProperties() {
|
||||
return m_javaprops;
|
||||
}
|
||||
|
||||
public void setMaximumMemoryHeap(int size) {
|
||||
m_maxHeap = size;
|
||||
}
|
||||
|
||||
public int getMaximumMemoryHeap() {
|
||||
return m_maxHeap;
|
||||
}
|
||||
|
||||
public void setInitialMemoryHeap(int size) {
|
||||
m_initialHeap = size;
|
||||
}
|
||||
|
||||
public int getInitialMemoryHeap() {
|
||||
return m_initialHeap;
|
||||
}
|
||||
|
||||
public void setVmParameter(String parameter) {
|
||||
m_vmParamter = parameter;
|
||||
}
|
||||
|
||||
public String getVmParameter() {
|
||||
return m_vmParamter;
|
||||
}
|
||||
|
||||
public void setUacRequireAdministrator(int parameter) {
|
||||
m_uacRequireAdmin = parameter;
|
||||
}
|
||||
|
||||
public int getUacRequireAdministrator() {
|
||||
return m_uacRequireAdmin;
|
||||
}
|
||||
|
||||
public boolean isUacRequireAdmin() {
|
||||
return m_uacRequireAdmin > 0;
|
||||
}
|
||||
|
||||
public String[] normalizePaths(java.io.File filebase) {
|
||||
return normalizePaths(filebase, true);
|
||||
}
|
||||
|
||||
public String[] normalizePaths(java.io.File filebase, boolean toRelativePath) {
|
||||
// System.out.println("Normalize Path " + filebase + " / " + toRelativePath);
|
||||
Vector result = new Vector();
|
||||
|
||||
m_iconLocation = checkRelativePath(filebase, m_iconLocation, result, "Icon location", toRelativePath);
|
||||
m_jarLocation = checkRelativePath(filebase, m_jarLocation, result, "Jar location", toRelativePath);
|
||||
m_bundledJVM = checkRelativePath(filebase, m_bundledJVM, result, "Bundle JVM location", toRelativePath);
|
||||
m_executableName = checkRelativePath(filebase, m_executableName, result, "Executable location", toRelativePath);
|
||||
|
||||
if (m_executableName != null) {
|
||||
File exebase = new File(m_executableName);
|
||||
if (exebase.isAbsolute() == false)
|
||||
exebase = new File(filebase, exebase.toString()).getParentFile();
|
||||
|
||||
// System.out.println("EXE FILEBASE: " + exebase.toString());
|
||||
if ((m_currentDirectory != null) && (m_currentDirectory.indexOf("${") >= 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
/*
|
||||
JSmooth: a VM wrapper toolkit for Windows
|
||||
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
|
||||
|
||||
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".
|
||||
* <p/>
|
||||
* <p/>
|
||||
* 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("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>").append("\n");
|
||||
retVal.append("<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">").append("\n");
|
||||
retVal.append(" <assemblyIdentity type=\"win32\"").append("\n");
|
||||
retVal.append(" name=\"").append(shortName).append("\"").append("\n");
|
||||
retVal.append(" version=\"1.0.0.0\"").append("\n");
|
||||
retVal.append(" processorArchitecture=\"").append(platform).append("\"").append("\n");
|
||||
retVal.append(" />").append("\n");
|
||||
retVal.append(" <dependency>").append("\n");
|
||||
retVal.append(" <dependentAssembly>").append("\n");
|
||||
retVal
|
||||
.append(
|
||||
" <assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.Common-Controls\" version=\"6.0.0.0\" processorArchitecture=\"*\" publicKeyToken=\"6595b64144ccf1df\" language=\"*\"/>")
|
||||
.append("\n");
|
||||
retVal.append(" </dependentAssembly>").append("\n");
|
||||
retVal.append(" </dependency>").append("\n");
|
||||
if (data.isUacRequireAdmin()) {
|
||||
retVal.append(" <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v2\">").append("\n");
|
||||
retVal.append(" <security>").append("\n");
|
||||
retVal.append(" <requestedPrivileges>").append("\n");
|
||||
retVal.append(" <requestedExecutionLevel level=\"requireAdministrator\"/>").append("\n");
|
||||
retVal.append(" </requestedPrivileges>").append("\n");
|
||||
retVal.append(" </security>").append("\n");
|
||||
retVal.append(" </trustInfo>").append("\n");
|
||||
}
|
||||
retVal.append("</assembly>");
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
JSmooth: a VM wrapper toolkit for Windows
|
||||
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
|
||||
|
||||
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","<html></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);
|
||||
}
|
||||
|
||||
|
||||
}
|
478
jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEFile.java
Normal file
478
jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/PEFile.java
Normal file
@ -0,0 +1,478 @@
|
||||
/*
|
||||
JSmooth: a VM wrapper toolkit for Windows
|
||||
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
|
||||
|
||||
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 <<newicon.BitsPerPixel);
|
||||
// rid.getEntries()[0].wBitCount = newicon.BitsPerPixel;
|
||||
// rid.getEntries()[0].dwBytesInRes = newicon.getData().remaining();
|
||||
//
|
||||
// iconentry.Data = newicon.getData();
|
||||
// iconentry.Size = iconentry.Data.remaining();
|
||||
//
|
||||
// entry.setData(rid.getData());
|
||||
// System.out.println("POST CHANGE ResIconDir :");
|
||||
// System.out.println(rid.toString());
|
||||
|
||||
// ResIcon test = new ResIcon(icon.getData());
|
||||
// System.out.println("PROOF-TEST:\n" + test.toString());
|
||||
|
||||
// / BACK
|
||||
//
|
||||
// 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;
|
||||
// iconentry.Data = icon.getData();
|
||||
// iconentry.Size = iconentry.Data.remaining();
|
||||
|
||||
// resdir.addNewResource("POUET", "A666", "#1033", data);
|
||||
|
||||
// resdir.dump(System.out);
|
||||
|
||||
// System.out.println("New size = " + resdir.size());
|
||||
File out = new File("c:/scratch/COPIE.exe");
|
||||
pe.dumpTo(out);
|
||||
|
||||
}
|
||||
|
||||
public PEResourceDirectory getResourceDirectory() throws IOException {
|
||||
if (m_resourceDir != null)
|
||||
return m_resourceDir;
|
||||
|
||||
long resourceoffset = m_header.ResourceDirectory_VA;
|
||||
for (int i = 0; i < m_sections.size(); i++) {
|
||||
PESection sect = (PESection)m_sections.get(i);
|
||||
if (sect.VirtualAddress == resourceoffset) {
|
||||
m_resourceDir = new PEResourceDirectory(this, sect);
|
||||
return m_resourceDir;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dumpTo(File destination) throws IOException, CloneNotSupportedException {
|
||||
int outputcount = 0;
|
||||
FileOutputStream fos = new FileOutputStream(destination);
|
||||
FileChannel out = fos.getChannel();
|
||||
|
||||
//
|
||||
// Make a copy of the Header, for safe modifications
|
||||
//
|
||||
PEOldMSHeader oldmsheader = (PEOldMSHeader)this.m_oldmsheader.clone();
|
||||
PEHeader peheader = (PEHeader)m_header.clone();
|
||||
Vector sections = new Vector();
|
||||
for (int i = 0; i < m_sections.size(); i++) {
|
||||
PESection sect = (PESection)m_sections.get(i);
|
||||
PESection cs = (PESection)sect.clone();
|
||||
sections.add(cs);
|
||||
}
|
||||
|
||||
//
|
||||
// First, write the old MS Header, the one starting
|
||||
// with "MZ"...
|
||||
//
|
||||
long newexeoffset = oldmsheader.e_lfanew;
|
||||
ByteBuffer msheadbuffer = oldmsheader.get();
|
||||
outputcount = out.write(msheadbuffer);
|
||||
this.m_channel.position(64);
|
||||
out.transferFrom(this.m_channel, 64, newexeoffset - 64);
|
||||
|
||||
|
||||
//
|
||||
// Then Write the new Header...
|
||||
//
|
||||
ByteBuffer headbuffer = peheader.get();
|
||||
out.position(newexeoffset);
|
||||
outputcount = out.write(headbuffer);
|
||||
|
||||
//
|
||||
// After the header, there are all the section
|
||||
// headers...
|
||||
//
|
||||
long 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);
|
||||
|
||||
ByteBuffer buf = sect.get();
|
||||
outputcount = out.write(buf);
|
||||
}
|
||||
|
||||
//
|
||||
// Now, we write the real data: each of the section
|
||||
// and their data...
|
||||
//
|
||||
|
||||
// Not sure why it's always at 1024... ?
|
||||
offset = 1024;
|
||||
|
||||
//
|
||||
// Dump each section data
|
||||
//
|
||||
|
||||
long virtualAddress = offset;
|
||||
if ((virtualAddress % peheader.SectionAlignment) > 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());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,482 @@
|
||||
/*
|
||||
JSmooth: a VM wrapper toolkit for Windows
|
||||
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,625 @@
|
||||
/*
|
||||
JSmooth: a VM wrapper toolkit for Windows
|
||||
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
JSmooth: a VM wrapper toolkit for Windows
|
||||
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user