mirror of
https://github.com/Noratrieb/jompiler.git
synced 2026-01-14 14:05:01 +01:00
ASLR in action
This commit is contained in:
parent
96f2dcf8af
commit
741b1000b3
2 changed files with 49 additions and 10 deletions
51
index.js
51
index.js
|
|
@ -105,6 +105,7 @@ function lex(input) {
|
||||||
case ",":
|
case ",":
|
||||||
case ";":
|
case ";":
|
||||||
case "+":
|
case "+":
|
||||||
|
case "-":
|
||||||
case "=": {
|
case "=": {
|
||||||
tokens.push({
|
tokens.push({
|
||||||
kind: head,
|
kind: head,
|
||||||
|
|
@ -362,6 +363,9 @@ function parse(tokens) {
|
||||||
const params = [];
|
const params = [];
|
||||||
|
|
||||||
while (tok.peek()?.kind !== ")") {
|
while (tok.peek()?.kind !== ")") {
|
||||||
|
if (params.length > 0) {
|
||||||
|
tok.expect(",", "function parameter separator");
|
||||||
|
}
|
||||||
const type = parseType(tok, "function parameter");
|
const type = parseType(tok, "function parameter");
|
||||||
const name = tok.next("function name");
|
const name = tok.next("function name");
|
||||||
if (name.kind !== "ident") {
|
if (name.kind !== "ident") {
|
||||||
|
|
@ -382,8 +386,9 @@ function parse(tokens) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
kind: "function",
|
kind: "function",
|
||||||
ret,
|
|
||||||
name,
|
name,
|
||||||
|
params,
|
||||||
|
ret,
|
||||||
body,
|
body,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -481,6 +486,8 @@ function lower(ast) {
|
||||||
const REG_SI = RM_SI;
|
const REG_SI = RM_SI;
|
||||||
const REG_DI = RM_DI;
|
const REG_DI = RM_DI;
|
||||||
|
|
||||||
|
const PARAM_CALLCONV_REGISTERS = [REG_DI, REG_SI, REG_D, REG_C];
|
||||||
|
|
||||||
const REG_IGNORED = 0;
|
const REG_IGNORED = 0;
|
||||||
function modRm(mod, reg, rm) {
|
function modRm(mod, reg, rm) {
|
||||||
assert(mod <= 0b11);
|
assert(mod <= 0b11);
|
||||||
|
|
@ -564,6 +571,15 @@ function lower(ast) {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subRegs(reg1, reg2) {
|
||||||
|
// REX.W + 03 /r | ADD r64, r/m64 ; Add r/m64 to r64
|
||||||
|
this.#append([
|
||||||
|
rex(REX.W_64_BIT_OPERAND_SIZE, 0, 0, 0),
|
||||||
|
0x2b,
|
||||||
|
modRm(MOD_REG, reg1, reg2),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
movRegToStackOffset(offset, reg) {
|
movRegToStackOffset(offset, reg) {
|
||||||
// mov [rsp+{offset}], reg
|
// mov [rsp+{offset}], reg
|
||||||
// 89 /r, MOV r/m64, r64
|
// 89 /r, MOV r/m64, r64
|
||||||
|
|
@ -656,6 +672,7 @@ function lower(ast) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function codegenExpr(ctx, expr) {
|
function codegenExpr(ctx, expr) {
|
||||||
|
assert(!Number.isNaN(ctx.offset));
|
||||||
const { ib, variables } = ctx;
|
const { ib, variables } = ctx;
|
||||||
switch (expr.kind) {
|
switch (expr.kind) {
|
||||||
case "call": {
|
case "call": {
|
||||||
|
|
@ -683,7 +700,7 @@ function lower(ast) {
|
||||||
.reverse()
|
.reverse()
|
||||||
.find((v) => v.name === expr.string);
|
.find((v) => v.name === expr.string);
|
||||||
assert(offset);
|
assert(offset);
|
||||||
ib.movStackOffsetToReg(offset.stackOffset, REG_A);
|
ib.movStackOffsetToReg(offset.stackOffset + ctx.offset, REG_A);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "+": {
|
case "+": {
|
||||||
|
|
@ -691,12 +708,21 @@ function lower(ast) {
|
||||||
// evaluate the RHS, then restore the LHS and perform the operation.
|
// evaluate the RHS, then restore the LHS and perform the operation.
|
||||||
codegenExpr(ctx, expr.lhs);
|
codegenExpr(ctx, expr.lhs);
|
||||||
ib.pushReg64(REG_A); // push rax
|
ib.pushReg64(REG_A); // push rax
|
||||||
codegenExpr(ctx, expr.rhs);
|
codegenExpr({ ...ctx, offset: ctx.offset + 8 }, expr.rhs);
|
||||||
ib.popReg64(REG_C); // pop rcx
|
ib.popReg64(REG_C); // pop rcx
|
||||||
|
|
||||||
ib.addRegs(REG_A, REG_C);
|
ib.addRegs(REG_A, REG_C);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "-": {
|
||||||
|
codegenExpr(ctx, expr.rhs);
|
||||||
|
ib.pushReg64(REG_A); // push rax
|
||||||
|
codegenExpr({ ...ctx, offset: ctx.offset + 8 }, expr.lhs);
|
||||||
|
ib.popReg64(REG_C); // pop rcx
|
||||||
|
|
||||||
|
ib.subRegs(REG_A, REG_C);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`unsupported expr: ${expr.kind}`);
|
throw new Error(`unsupported expr: ${expr.kind}`);
|
||||||
}
|
}
|
||||||
|
|
@ -707,15 +733,28 @@ function lower(ast) {
|
||||||
const ib = new InstBuilder();
|
const ib = new InstBuilder();
|
||||||
const variables = [];
|
const variables = [];
|
||||||
|
|
||||||
|
assert(func.params.length <= 4);
|
||||||
|
|
||||||
|
func.params.forEach((param, i) => {
|
||||||
|
assert(param.type.kind === "int");
|
||||||
|
const offset = ib.reserveStack(4);
|
||||||
|
ib.movRegToStackOffset(offset, PARAM_CALLCONV_REGISTERS[i]);
|
||||||
|
variables.push({
|
||||||
|
name: param.name,
|
||||||
|
stackOffset: offset,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
for (const stmt of func.body) {
|
for (const stmt of func.body) {
|
||||||
|
const ctx = { ib, variables, offset: 0 };
|
||||||
switch (stmt.kind) {
|
switch (stmt.kind) {
|
||||||
case "expr": {
|
case "expr": {
|
||||||
codegenExpr({ ib, variables }, stmt.expr);
|
codegenExpr(ctx, stmt.expr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "return": {
|
case "return": {
|
||||||
if (stmt.rhs) {
|
if (stmt.rhs) {
|
||||||
codegenExpr({ ib, variables }, stmt.rhs);
|
codegenExpr(ctx, stmt.rhs);
|
||||||
}
|
}
|
||||||
ib.finish();
|
ib.finish();
|
||||||
ib.ret();
|
ib.ret();
|
||||||
|
|
@ -724,7 +763,7 @@ function lower(ast) {
|
||||||
case "declaration": {
|
case "declaration": {
|
||||||
assert(stmt.type === "int");
|
assert(stmt.type === "int");
|
||||||
if (stmt.init) {
|
if (stmt.init) {
|
||||||
codegenExpr({ ib, variables }, stmt.init);
|
codegenExpr(ctx, stmt.init);
|
||||||
}
|
}
|
||||||
const slot = ib.reserveStack(4);
|
const slot = ib.reserveStack(4);
|
||||||
variables.push({
|
variables.push({
|
||||||
|
|
|
||||||
6
input.c
6
input.c
|
|
@ -1,10 +1,10 @@
|
||||||
// #include<elf.h>
|
// #include<elf.h>
|
||||||
|
|
||||||
int main(int argc)
|
int main(int argc, int argv)
|
||||||
{
|
{
|
||||||
int x = 100;
|
int x = 100;
|
||||||
int x = 200;
|
thisismyfakeconstantbecauseidonthaveconstant(x - 1);
|
||||||
return x;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thisismyfakeconstantbecauseidonthaveconstant(int x)
|
int thisismyfakeconstantbecauseidonthaveconstant(int x)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue