1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
package pw.cloudef.rpg;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.net.Uri;
import android.system.Os;
import android.util.Log;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
public class Rtp extends Activity {
protected String rtpDir() {
return getApplicationContext().getFilesDir().toPath().toString() + "/rtp";
}
protected String workDir() {
return getApplicationContext().getCacheDir().toPath().toString() + "/temp";
}
protected String zipPath() {
return workDir() + "/rtp.zip";
}
protected void shell(String cmd) {
try { Runtime.getRuntime().exec(cmd); } catch (Exception e) {}
}
protected void rm(String path) {
shell("rm -rf '" + path + "'");
}
protected void run(String cmd, String args, String input) {
shell("'" + getApplicationContext().getApplicationInfo().nativeLibraryDir + "/" + cmd + "' " + args + " '" + workDir() + "/" + input + "'");
}
protected boolean matches(String name, String[] wants) {
for (int i = 0; i < wants.length; ++i) if (name.equals(wants[i])) return true;
return false;
}
protected void unzip(File file, String[] wants, String dest) {
ZipFile zipFile;
try {
zipFile = new ZipFile(file, java.util.zip.ZipFile.OPEN_READ, Charset.forName("Windows-31J"));
} catch (Exception e) {
Log.d("pw.cloudef.rpg", e.toString());
return;
}
try {
Enumeration zipEntries = zipFile.entries();
while (zipEntries.hasMoreElements()) {
final ZipEntry entry = (ZipEntry)zipEntries.nextElement();
if (!matches(entry.getName(), wants)) continue;
InputStream input = zipFile.getInputStream(entry);
String base = entry.getName().split(".+?/(?=[^/]+$)")[1];
File out = new File(dest, base);
if (!out.getCanonicalPath().startsWith(dest))
throw new Exception("Zip path traversal detected");
out.mkdirs();
OutputStream output = new FileOutputStream(out);
byte[] buf = new byte[8 * 1024];
for (int read = 0; (read = input.read(buf)) != -1;) output.write(buf, 0, read);
output.close(); input.close();
break;
}
} catch (Exception e) {
Log.d("pw.cloudef.rpg", e.toString());
}
try { zipFile.close(); } catch (Exception e) {}
}
protected String rtpId() {
return getIntent().getExtras().getString("id");
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
InputStream input = getContentResolver().openInputStream(getIntent().getData());
File file = new File(zipPath());
file.mkdirs();
OutputStream output = new FileOutputStream(file);
byte[] buf = new byte[8 * 1024];
for (int read = 0; (read = input.read(buf)) != -1;) output.write(buf, 0, read);
output.close(); input.close();
if (rtpId().equals("2000") || rtpId().equals("2003")) {
String prefix = (rtpId().equals("2003") ? "2003" : "");
unzip(file, new String[]{prefix + "RTPセットアップ/" + rtpId() + "RTP.exe"}, workDir());
run("libcabextract.so", "-d '" + workDir() + "' -e CP932 ", rtpId() + "RTP.exe");
run("libunshield.so", "-d '" + workDir() + "' -e CP932 x", "data1.cab");
run("libunshield.so", "-d '" + workDir() + "' -e CP932 x", "data2.cab");
} else if (rtpId().equals("XP")) {
unzip(file, new String[]{"RPGXP_RTP103/Setup.exe"}, workDir());
run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "Setup.exe");
shell("mv '" + workDir() + "/app' '" + rtpDir() + "/XP'");
} else if (rtpId().equals("VX")) {
unzip(file, new String[]{"RPGVX_RTP202/setup.exe"}, workDir());
run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "setup.exe");
shell("mv '" + workDir() + "/app' '" + rtpDir() + "/VX'");
} else if (rtpId().equals("VXAce")) {
unzip(file, new String[]{"RPGVXAce_RTP100/Setup.exe", "RPGVXAce_RTP100/Setup-1.bin"}, workDir());
run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "Setup.exe");
shell("mv '" + workDir() + "/app' '" + rtpDir() + "/VXAce'");
} else {
throw new Exception("Unknown RTP");
}
} catch (Exception e) {
Log.d("pw.cloudef.rpg", e.toString());
}
finishAndRemoveTask();
}
}
|