• R/O
  • SSH
  • HTTPS

exewrap: Commit


Commit MetaInfo

Revision24 (tree)
Time2015-07-21 12:55:31
Authorhirukawa_ryo

Log Message

v1.1.0 *コミット漏れ。

Change Summary

Incremental Difference

--- exewrap/trunk/exewrap/src/java/exewrap/util/ConsoleOutputStream.java (revision 0)
+++ exewrap/trunk/exewrap/src/java/exewrap/util/ConsoleOutputStream.java (revision 24)
@@ -0,0 +1,32 @@
1+package exewrap.util;
2+
3+import java.io.IOException;
4+import java.io.OutputStream;
5+import java.io.PrintStream;
6+
7+import exewrap.core.ExewrapClassLoader;
8+
9+public class ConsoleOutputStream extends OutputStream {
10+ static {
11+ System.setOut(new PrintStream(new ConsoleOutputStream()));
12+ }
13+
14+ @Override
15+ public void write(int b) throws IOException {
16+ ExewrapClassLoader.WriteConsole(new byte[] { (byte)(b & 0xFF) }, 0, 1);
17+ }
18+
19+ @Override
20+ public void write(byte[] b) throws IOException {
21+ if(b != null) {
22+ ExewrapClassLoader.WriteConsole(b, 0, b.length);
23+ }
24+ }
25+
26+ @Override
27+ public void write(byte[] b, int off, int len) throws IOException {
28+ if(b != null) {
29+ ExewrapClassLoader.WriteConsole(b, off, len);
30+ }
31+ }
32+}
--- exewrap/trunk/exewrap/src/java/jremin/JreMin.java (revision 0)
+++ exewrap/trunk/exewrap/src/java/jremin/JreMin.java (revision 24)
@@ -0,0 +1,345 @@
1+package jremin;
2+
3+import java.io.BufferedReader;
4+import java.io.BufferedWriter;
5+import java.io.ByteArrayOutputStream;
6+import java.io.File;
7+import java.io.FileInputStream;
8+import java.io.FileNotFoundException;
9+import java.io.FileOutputStream;
10+import java.io.IOException;
11+import java.io.InputStream;
12+import java.io.InputStreamReader;
13+import java.io.OutputStreamWriter;
14+import java.io.Writer;
15+import java.nio.channels.FileChannel;
16+import java.nio.charset.Charset;
17+import java.util.ArrayList;
18+import java.util.Arrays;
19+import java.util.Collections;
20+import java.util.HashMap;
21+import java.util.HashSet;
22+import java.util.List;
23+import java.util.Map;
24+import java.util.Set;
25+import java.util.jar.JarEntry;
26+import java.util.jar.JarInputStream;
27+import java.util.jar.JarOutputStream;
28+
29+public class JreMin {
30+
31+ private static Set<String> excluded = new HashSet<String>(Arrays.asList(new String[] {
32+ "classes.jsa",
33+ "meta-index"
34+ }));
35+
36+ private static Set<String> requiredFiles = new HashSet<String>(Arrays.asList(new String[] {
37+ "copyright",
38+ "license",
39+ "readme.txt",
40+ "thirdpartylicensereadme.txt",
41+ "thirdpartylicensereadme-javafx.txt",
42+ "welcome.html"
43+ }));
44+
45+ private static Set<String> fonts = new HashSet<String>(Arrays.asList(new String[] {
46+ "lucidabrightdemibold.ttf",
47+ "lucidabrightdemiitalic.ttf",
48+ "lucidabrightitalic.ttf",
49+ "lucidabrightregular.ttf",
50+ "lucidasansdemibold.ttf",
51+ "lucidasansregular.ttf",
52+ "lucidatypewriterbold.ttf",
53+ "lucidatypewriterregular.ttf"
54+ }));
55+
56+ private static Map<String, Set<String>> map = new HashMap<String, Set<String>>();
57+
58+ private static Set<String> requiredPackages = new HashSet<String>(Arrays.asList(new String[] {
59+ "java/lang/*"
60+ }));
61+
62+ public static void main(String[] args) throws Exception {
63+ if(args.length == 0) {
64+ showUsage();
65+ return;
66+ }
67+
68+ map.put("awt", new HashSet<String>(Arrays.asList(new String[] {
69+ "com/sun/awt/*",
70+ "java/text/*",
71+ "java/awt/*",
72+ "sun/awt/*",
73+ "sun/dc/*",
74+ "sun/font/*",
75+ "sun/util/locale/*",
76+ //--------
77+ "java/util",
78+ "sun/util",
79+ "sun/util/calendar"
80+ })));
81+
82+ map.put("swing", new HashSet<String>(Arrays.asList(new String[] {
83+ "com/sun/beans/util/*",
84+ "com/sun/java/swing/*",
85+ "com/sun/media/*",
86+ "com/sun/swing/*",
87+ "java/applet/*",
88+ "java/awt/*",
89+ "java/beans/*",
90+ "java/io/*",
91+ "java/math/*",
92+ "java/net/*",
93+ "java/nio/*",
94+ "java/security/*",
95+ "java/text/*",
96+ "java/util/*",
97+ "javax/accessibility/*",
98+ "javax/print/*",
99+ "javax/sound/*",
100+ "javax/swing/*",
101+ "jdk/internal/org/objectweb/asm/*",
102+ "sun/awt/*",
103+ "sun/dc/*",
104+ "sun/font/*",
105+ "sun/invoke/*",
106+ "sun/io/*",
107+ "sun/java2d/*",
108+ "sun/misc/*",
109+ "sun/net/*",
110+ "sun/nio/*",
111+ "sun/print/*",
112+ "sun/reflect/*",
113+ "sun/security/*",
114+ "sun/swing/*",
115+ "sun/text/*",
116+ "sun/util/*"
117+ })));
118+
119+ String filename = args[0];
120+
121+ boolean debug = false;
122+ if(args.length >= 2 && args[0].equals("-d")) {
123+ debug = true;
124+ filename = args[1];
125+ }
126+
127+ if(!new File(filename).exists()) {
128+ System.out.println();
129+ }
130+
131+ Trace trace = new Trace(new File(filename));
132+ if(debug) {
133+ debugOut(trace);
134+ }
135+
136+ File jre = trace.getJRE();
137+ if(jre == null) {
138+ System.out.println("JRE not found.");
139+ return;
140+ }
141+ File target = new File(jre.getName());
142+
143+ Set<String> appends = new HashSet<String>();
144+
145+ if(trace.useAwt()) {
146+ for(String pkg : map.get("awt")) {
147+ requiredPackages.add(pkg);
148+ }
149+ appends.addAll(fonts);
150+ }
151+ if(trace.useSwing()) {
152+ for(String pkg : map.get("swing")) {
153+ requiredPackages.add(pkg);
154+ }
155+ appends.addAll(fonts);
156+ }
157+
158+ Set<File> files = new HashSet<File>();
159+ for(File file : getRequiredFiles(jre, appends)) {
160+ files.add(file);
161+ }
162+ for(String s : trace.getFiles()) {
163+ File file = new File(s).getCanonicalFile();
164+ files.add(file);
165+ }
166+ for(String s : trace.getUsedJars()) {
167+ File file = new File(s).getCanonicalFile();
168+ files.add(file);
169+ }
170+
171+ Set<String> requiredClassEntryNames = getRequiredClassEntryNames();
172+ for(String name : trace.getRequiredClassEntryNames()) {
173+ requiredClassEntryNames.add(name);
174+ }
175+
176+ for(File file : files) {
177+ if(!file.exists()) {
178+ continue;
179+ }
180+ if(!file.getPath().toLowerCase().startsWith(jre.getPath().toLowerCase())) {
181+ continue;
182+ }
183+ if(excluded.contains(file.getName().toLowerCase())) {
184+ continue;
185+ }
186+ File dst = new File(target, file.getPath().substring(jre.getPath().length()));
187+ File dir = dst.getParentFile();
188+ if(!dir.exists()) {
189+ dir.mkdirs();
190+ }
191+ System.out.println(dst.getPath());
192+ if(file.getPath().toLowerCase().endsWith(".jar")) {
193+ copyJAR(file, dst, requiredClassEntryNames, requiredPackages);
194+ } else {
195+ copy(file, dst);
196+ }
197+ }
198+ }
199+
200+ public static void showUsage() {
201+ System.out.println(
202+ "jremin 1.1.0\r\n" +
203+ "Java Runtime Environment (JRE) minimizer.\r\n" +
204+ "Copyright (C) 2015 HIRUKAWA Ryo. All rights reserved.\r\n" +
205+ "\r\n" +
206+ "Usage: jremin.exe <trace-file>\r\n"
207+ );
208+ }
209+
210+ public static void copy(File src, File dst) throws IOException {
211+ FileChannel sc = null;
212+ FileChannel dc = null;
213+ try {
214+ sc = new FileInputStream(src).getChannel();
215+ dc = new FileOutputStream(dst).getChannel();
216+ dc.transferFrom(sc, 0, sc.size());
217+ } finally {
218+ if (dc != null) try { dc.close(); } catch (Exception e) {}
219+ if (sc != null) try { sc.close(); } catch (Exception e) {}
220+ }
221+ }
222+
223+ public static void copyJAR(File src, File dst, Set<String> requiredClassEntryNames, Set<String> requirePackages) throws FileNotFoundException, IOException {
224+ JarInputStream jarIn = new JarInputStream(new FileInputStream(src));
225+ JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(dst), jarIn.getManifest());
226+ JarEntry entryIn;
227+ while((entryIn = jarIn.getNextJarEntry()) != null) {
228+ String name = entryIn.getName();
229+ String pkg = null;
230+ int i = name.lastIndexOf('/');
231+ if(i > 0) {
232+ pkg = name.substring(0, i);
233+ }
234+ boolean required = false;;
235+ for(String p : requirePackages) {
236+ if(p.endsWith("/*")) {
237+ p = p.substring(0, p.length() - 2);
238+ if(pkg.startsWith(p)) {
239+ required = true;
240+ break;
241+ }
242+ } else if(p.equals(pkg)) {
243+ required = true;
244+ break;
245+ }
246+ }
247+
248+ if(!required && name.endsWith(".class") && !requiredClassEntryNames.contains(name)) {
249+ continue;
250+ }
251+ JarEntry entryOut = new JarEntry(name);
252+ entryOut.setMethod(JarEntry.DEFLATED);
253+ jarOut.putNextEntry(entryOut);
254+ byte[] data = getBytes(jarIn);
255+ jarIn.closeEntry();
256+ jarOut.write(data);
257+ jarOut.flush();
258+ jarOut.closeEntry();
259+ }
260+ jarIn.close();
261+ jarOut.flush();
262+ jarOut.finish();
263+ jarOut.close();
264+ }
265+
266+ private static byte[] getBytes(InputStream in) throws IOException {
267+ ByteArrayOutputStream out = new ByteArrayOutputStream();
268+ byte[] buf = new byte[65536];
269+ int size;
270+ while((size = in.read(buf)) != -1) {
271+ out.write(buf, 0, size);
272+ }
273+ return out.toByteArray();
274+ }
275+
276+ public static List<File> getRequiredFiles(File jre, Set<String> appends) {
277+ List<File> list = new ArrayList<File>();
278+ traverseRequiredFiles(list, jre, appends);
279+ return list;
280+ }
281+
282+ private static void traverseRequiredFiles(List<File> list, File dir, Set<String> appends) {
283+ for(File file : dir.listFiles()) {
284+ if(file.isDirectory()) {
285+ traverseRequiredFiles(list, file, appends);
286+ } else {
287+ if(appends != null && appends.contains(file.getName().toLowerCase())) {
288+ list.add(file);
289+ continue;
290+ }
291+ if(requiredFiles.contains(file.getName().toLowerCase())) {
292+ list.add(file);
293+ continue;
294+ }
295+ }
296+ }
297+ }
298+
299+ public static Set<String> getRequiredClassEntryNames() throws IOException {
300+ Set<String> set = new HashSet<String>();
301+ InputStream in = JreMin.class.getResourceAsStream("classes.txt");
302+ if(in != null) {
303+ BufferedReader r = new BufferedReader(new InputStreamReader(in, Charset.forName("UTF-8")));
304+ String line;
305+ while((line = r.readLine()) != null) {
306+ String name = line.replace('.', '/') + ".class";
307+ set.add(name);
308+ }
309+ r.close();
310+ }
311+ in.close();
312+ return set;
313+ }
314+
315+ public static void debugOut(Trace trace) throws Exception {
316+ Writer w;
317+ List<String> list;
318+
319+ w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("classes.txt"), Charset.forName("UTF-8")));
320+ list = new ArrayList<String>();
321+ for(String s : trace.getRequiredClassEntryNames()) {
322+ if(s.endsWith(".class")) {
323+ list.add(s.substring(0, s.length() - 6).replace('/', '.'));
324+ }
325+ };
326+ Collections.sort(list);
327+ for(String line : list) {
328+ w.write(line);
329+ w.write("\r\n");
330+ }
331+ w.close();
332+
333+ w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("packages.txt"), Charset.forName("UTF-8")));
334+ list = new ArrayList<String>();
335+ for(String s : trace.getPackages()) {
336+ list.add(s.replace('/', '.'));
337+ };
338+ Collections.sort(list);
339+ for(String line : list) {
340+ w.write(line);
341+ w.write("\r\n");
342+ }
343+ w.close();
344+ }
345+}
--- exewrap/trunk/exewrap/src/java/jremin/Trace.java (revision 0)
+++ exewrap/trunk/exewrap/src/java/jremin/Trace.java (revision 24)
@@ -0,0 +1,163 @@
1+package jremin;
2+
3+import java.io.BufferedReader;
4+import java.io.File;
5+import java.io.FileInputStream;
6+import java.io.FilenameFilter;
7+import java.io.IOException;
8+import java.io.InputStreamReader;
9+import java.nio.charset.Charset;
10+import java.util.ArrayList;
11+import java.util.HashSet;
12+import java.util.List;
13+import java.util.Set;
14+import java.util.jar.JarEntry;
15+import java.util.jar.JarInputStream;
16+import java.util.regex.Matcher;
17+import java.util.regex.Pattern;
18+
19+public class Trace {
20+
21+ private static Pattern LOADED_CLASS = Pattern.compile("Loaded (\\S+)", Pattern.CASE_INSENSITIVE);
22+ private static Pattern LOAD_LIBRARY = Pattern.compile("\\[LoadLibrary (.+)\\]", Pattern.CASE_INSENSITIVE);
23+ private static Pattern CREATE_FILE = Pattern.compile("\\[CreateFile (.+)\\]", Pattern.CASE_INSENSITIVE);
24+
25+ private File jre = null;
26+ private Set<String> jars = null;
27+ private Set<String> files = new HashSet<String>();
28+ private Set<String> packages = new HashSet<String>();
29+ private Set<String> requiredClassEntryNames = new HashSet<String>();
30+ private boolean useAwt;
31+ private boolean useSwing;
32+
33+ public Trace(File file) throws IOException {
34+ file = file.getCanonicalFile();
35+ String s = file.getName();
36+ int i = s.toUpperCase().indexOf(".TRACE");
37+ if(i >= 0) {
38+ s = s.substring(0, i);
39+ }
40+ final String basename = s;
41+ File dir = file.getParentFile();
42+ File[] files = dir.listFiles(new FilenameFilter() {
43+ @Override
44+ public boolean accept(File dir, String name) {
45+ return name.startsWith(basename) && name.toUpperCase().contains(".TRACE") && name.toLowerCase().endsWith(".log");
46+ }
47+ });
48+ for(File f : files) {
49+ BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), Charset.forName("MS932")));
50+ String line;
51+ while((line = r.readLine()) != null) {
52+ Matcher m;
53+ m = LOADED_CLASS.matcher(line);
54+ if(m.find()) {
55+ String cls = m.group(1);
56+ if(!this.useAwt && (cls.startsWith("com.sun.awt.") || cls.startsWith("java.awt."))) {
57+ this.useAwt = true;
58+ }
59+ if(!this.useSwing && (cls.startsWith("com.sun.swing.") || cls.startsWith("javax.swing."))) {
60+ this.useSwing = true;
61+ }
62+ if(cls.startsWith("exewrap.")) {
63+ continue;
64+ }
65+ this.requiredClassEntryNames.add(cls.replace('.', '/') + ".class");
66+ continue;
67+ }
68+ m = LOAD_LIBRARY.matcher(line);
69+ if(m.find()) {
70+ this.files.add(m.group(1));
71+ continue;
72+ }
73+ m = CREATE_FILE.matcher(line);
74+ if(m.find()) {
75+ this.files.add(m.group(1));
76+ continue;
77+ }
78+ }
79+ r.close();
80+ }
81+ for(String cls : this.requiredClassEntryNames) {
82+ int j = cls.lastIndexOf('/');
83+ if(j >= 0) {
84+ this.packages.add(cls.substring(0, j));
85+ }
86+ }
87+ }
88+
89+ public File getJRE() {
90+ if(jre == null) {
91+ for(String s : files) {
92+ File f = new File(s);
93+ if(f.exists() && (f.getName().equalsIgnoreCase("jvm.dll") || f.getName().equalsIgnoreCase("rt.jar"))) {
94+ File dir = f.getParentFile();
95+ while(dir != null) {
96+ if(dir.getName().equalsIgnoreCase("bin") || dir.getName().equalsIgnoreCase("lib")) {
97+ jre = dir.getParentFile();
98+ return jre;
99+ }
100+ dir = dir.getParentFile();
101+ }
102+ }
103+ }
104+ }
105+ return jre;
106+ }
107+
108+ public Set<String> getUsedJars() throws IOException {
109+ if(jars == null) {
110+ jars = new HashSet<String>();
111+ List<File> list = new ArrayList<File>();
112+ traverseJars(list, getJRE());
113+ for(File jar : list) {
114+ boolean used = false;
115+ JarInputStream jarIn = new JarInputStream(new FileInputStream(jar));
116+ JarEntry entry;
117+ while((entry = jarIn.getNextJarEntry()) != null) {
118+ if(requiredClassEntryNames.contains(entry.getName())) {
119+ used = true;
120+ break;
121+ }
122+ }
123+ jarIn.close();
124+ if(used) {
125+ jars.add(jar.getCanonicalPath());
126+ }
127+ }
128+ }
129+ return jars;
130+ }
131+
132+ private void traverseJars(List<File> list, File dir) throws IOException {
133+ for(File file : dir.listFiles()) {
134+ if(file.isDirectory()) {
135+ traverseJars(list, file);
136+ } else {
137+ if(file.getName().toLowerCase().endsWith(".jar")) {
138+ list.add(file);
139+ };
140+ }
141+ }
142+ }
143+
144+ public Set<String> getRequiredClassEntryNames() {
145+ return this.requiredClassEntryNames;
146+ }
147+
148+ public Set<String> getPackages() {
149+ return this.packages;
150+ }
151+
152+ public Set<String> getFiles() {
153+ return this.files;
154+ }
155+
156+ public boolean useAwt() {
157+ return this.useAwt;
158+ }
159+
160+ public boolean useSwing() {
161+ return this.useSwing;
162+ }
163+}
\ No newline at end of file
--- exewrap/trunk/exewrap/src/java/jremin/agent/manifest.txt (revision 0)
+++ exewrap/trunk/exewrap/src/java/jremin/agent/manifest.txt (revision 24)
@@ -0,0 +1,2 @@
1+Premain-Class: jremin.agent.Agent
2+Main-Class: jremin.agent.Agent
--- exewrap/trunk/exewrap/src/java/jremin/agent/Agent.java (revision 0)
+++ exewrap/trunk/exewrap/src/java/jremin/agent/Agent.java (revision 24)
@@ -0,0 +1,18 @@
1+package jremin.agent;
2+
3+import java.lang.instrument.Instrumentation;
4+
5+public class Agent {
6+ public static void premain(String agentArgs, Instrumentation instrumentation) {
7+ Class<?>[] classes = instrumentation.getAllLoadedClasses();
8+ for (Class<?> cls : classes) {
9+ String name = cls.getName();
10+ if(name.length() >= 1 && name.charAt(0) != '[' && !name.startsWith("jremin.")) {
11+ System.out.println(name);
12+ }
13+ }
14+ }
15+
16+ public static void main(String[] args) {
17+ }
18+}
--- exewrap/trunk/exewrap/license.txt (revision 0)
+++ exewrap/trunk/exewrap/license.txt (revision 24)
@@ -0,0 +1,104 @@
1+Copyright (C) 2005-2014 HIRUKAWA Ryo. All rights reserved.
2+
3+ソースコード形式であれバイナリ形式であれ、変更の有無に関わらず、
4+以下の条件を満たす限りにおいて、再配布および使用を許可します:
5+
6+ 1. ソースコード形式で再配布する場合、上記著作権表示、
7+ 本条件書および下記責任限定規定を必ず含めてください。
8+
9+ 2. バイナリ形式で再配布する場合、上記著作権表示、本条件書および下記責任限定規定を、
10+ 配布物とともに提供される文書 および/または 他の資料に必ず含めてください。
11+
12+本ソフトウェアの実行により生成されたファイルの利用および配布について一切の制限を行いません。上記著作権表示、本状条件書、下記責任限定規定を含まずに、本ソフトウェアの実行により生成されたファイルを完全に自由に利用および配布することができます。
13+
14+本ソフトウェアは HIRUKAWA Ryo によって、"現状のまま" 提供されるものとします。本ソフトウェアについては、明示黙示を問わず、商用品として通常そなえるべき品質をそなえているとの保証も、特定の目的に適合するとの保証を含め、何の保証もなされません。事由のいかんを問わず、損害発生の原因いかんを問わず、且つ、責任の根拠が契約であるか厳格責任であるか (過失その他) 不法行為であるかを問わず、HIRUKAWA Ryo も寄与者も、仮にそのような損害が発生する可能性を知らされていたとしても、本ソフトウェアの使用から発生した直接損害、間接損害、偶発的な損害、 特別損害、懲罰的損害または結果損害のいずれに対しても (代替品または サービスの提供; 使用機会、データまたは利益の損失の補償;または、業務の中断に対する補償を含め) 責任をいっさい負いません。
15+
16+
17+#
18+# MinHook
19+#
20+exewrapにオプション -T を指定して出力したトレース用バイナリは Tsuda Kageyu さんの作成した MinHook を含んでいます。(通常出力のバイナリには MinHook のコードは含まれません。)
21+
22+MinHook - The Minimalistic API Hooking Library for x64/x86
23+Copyright (C) 2009-2015 Tsuda Kageyu.
24+All rights reserved.
25+
26+Redistribution and use in source and binary forms, with or without
27+modification, are permitted provided that the following conditions
28+are met:
29+
30+ 1. Redistributions of source code must retain the above copyright
31+ notice, this list of conditions and the following disclaimer.
32+ 2. Redistributions in binary form must reproduce the above copyright
33+ notice, this list of conditions and the following disclaimer in the
34+ documentation and/or other materials provided with the distribution.
35+
36+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
38+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
40+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
44+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47+
48+================================================================================
49+Portions of this software are Copyright (c) 2008-2009, Vyacheslav Patkov.
50+================================================================================
51+Hacker Disassembler Engine 32 C
52+Copyright (c) 2008-2009, Vyacheslav Patkov.
53+All rights reserved.
54+
55+Redistribution and use in source and binary forms, with or without
56+modification, are permitted provided that the following conditions
57+are met:
58+
59+ 1. Redistributions of source code must retain the above copyright
60+ notice, this list of conditions and the following disclaimer.
61+ 2. Redistributions in binary form must reproduce the above copyright
62+ notice, this list of conditions and the following disclaimer in the
63+ documentation and/or other materials provided with the distribution.
64+
65+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
66+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
67+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
68+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
69+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
70+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
71+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
72+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
73+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
74+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76+
77+-------------------------------------------------------------------------------
78+Hacker Disassembler Engine 64 C
79+Copyright (c) 2008-2009, Vyacheslav Patkov.
80+All rights reserved.
81+
82+Redistribution and use in source and binary forms, with or without
83+modification, are permitted provided that the following conditions
84+are met:
85+
86+ 1. Redistributions of source code must retain the above copyright
87+ notice, this list of conditions and the following disclaimer.
88+ 2. Redistributions in binary form must reproduce the above copyright
89+ notice, this list of conditions and the following disclaimer in the
90+ documentation and/or other materials provided with the distribution.
91+
92+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
93+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
94+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
95+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
96+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
97+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
98+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
99+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
100+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
101+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103+
104+
Show on old repository browser