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