add ret, call, stack

v1 let's go !
This commit is contained in:
2023-05-31 08:48:15 +02:00
parent bc36d7f896
commit 66a49c9d1a
10 changed files with 113 additions and 28 deletions

View File

@@ -9,11 +9,11 @@ PASM is meant for being used in C2 agents as its interpreter is small.
PASM is not a language that you daily use, it is not meant for big projects but rather for scripting using existing API (here the Windows API's but it can get extended).
# Current state
At the moment i'm trying to get everything working before refactoring (there are bad practices and redundant code) and getting rid of the CRT, here is what is left to do :
- make control flow work (ret is gonna be a pain) (i need to fix the char_read counter, strlen doing its things ig)
- add the API
- think of a more clever way of going through the labels and later the API (currently done in get_instruction.c and instructions.c)
- make the stack work
PASM is in a working state, the [keylogger example](#code-examples) works like a charm.
TODO :
- code refactor (still bad practices)
- get rid of the CRT (so we can get a smaller PE)
- write the docs
# Usage

View File

@@ -1,2 +1,2 @@
# keylogger
This is a POC, i don't even know if it works as the interpreter and scripts are in very early stages
Will output the pressed key. Works for keys from A-Z and 0-9.

View File

@@ -19,10 +19,10 @@
; note about returns : you can directly call ret from a je/jne/ja/jna/jb/jnb with "jb return".
; so return cannot be used as a label.
check:
cmp a1, 58
cmp a1, 57
jb return ; if <
cmp a1, 64
cmp a1, 63
ja return ; if >
mov eax, 1
@@ -48,12 +48,11 @@ add a1, 1 ; i++
push a1 ; arg 1 (vKey)
call GetAsyncKeyState
and eax, 32768 ; 0x8000 but i haven't implemented hex yet
and eax, 1
cmp eax, 0
je numbers ; if GetAsyncKeyState was false, jump to numbers
mov a2, a1 ; necessary ?
push "%c" ; push format
push a2 ; push char
call printf
call put
jmp numbers

View File

@@ -1 +1,12 @@
#include "api.h"
#include "api.h"
#include "main.h"
#include <Windows.h>
void api_put() {
printf("%c\n", stack[top--]);
}
void api_getasynckeystate() {
eax = GetAsyncKeyState(stack[top--]);
}

View File

@@ -1,3 +1,12 @@
#pragma once
#include "instructions.h"
void api_put();
void api_getasynckeystate();
static const command_t api_map[] = {
{.command = "put", .fptr = api_put},
{.command = "GetAsyncKeyState", .fptr = api_getasynckeystate},
{.command = NULL, .fptr = NULL}
};

View File

@@ -1,5 +1,6 @@
#include "instructions.h"
#include "main.h"
#include "api.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -64,13 +65,13 @@ int get_value(char* arg) {
return ret;
}
const command_t *find_command(char *your_var)
const command_t *find_command(char *your_var, const command_t* func_map)
{
if (your_var == NULL)
return NULL;
for (int index = 0; command_map[index].fptr != NULL; index += 1) {
if (strcmp(your_var, command_map[index].command) == 0) {
return &command_map[index];
for (int index = 0; func_map[index].fptr != NULL; index += 1) {
if (strcmp(your_var, func_map[index].command) == 0) {
return &func_map[index];
}
}
return NULL;
@@ -92,11 +93,30 @@ void cmp() {
return;
}
int line_should_ret = -1;
void ret() {
if (line_should_ret == -1) {
exit_code = 1;
return;
}
fseek(fptr, line_should_ret, SEEK_SET);
}
void jmp() {
if (strcmp(args->arg1, "return") == 0) {
ret();
return;
}
eax = 0;
for (int i = 0; i < MAX_LABEL; i++) {
if (labels[i] == NULL) break;
if (strcmp(args->arg1, labels[i]) == 0) {
line_should_ret = (int)char_read;
fseek(fptr, labels_lines[i], SEEK_SET);
(int)char_read = labels_lines[i];
return;
}
}
@@ -153,20 +173,37 @@ void mov() {
*get_reg(args->arg1) = get_value(args->arg2);
}
void ret() {
}
void call() {
const command_t* com = find_command(args->arg1, api_map);
if (com != NULL) {
com->fptr();
}
else {
last_jmp_code = 1;
}
}
void push() {
if (!((is_num(args->arg1) || (is_reg(args->arg1))))) {
last_check_args_code = ARG1_WRONG;
return;
}
if (top == STACK_SIZE) { //stack overflow
last_stack_code = OVERFLOW;
return;
}
stack[++top] = get_value(args->arg1);
}
void pop() {
if (top == -1) { //stack underflow
last_stack_code = UNDERFLOW;
return;
}
--top;
}
void and() {

View File

@@ -18,13 +18,20 @@ typedef enum check_args_codes {
} check_args_codes ;
extern check_args_codes last_check_args_code;
typedef enum stack_codes {
OVERFLOW,
UNDERFLOW,
STACK_OK
} stack_codes;
extern stack_codes last_stack_code;
//pasted from https://github.com/Sakutaroo/Templates/blob/main/C/FunctionPointer/function_pointer.h
typedef struct command_s {
char *command;
void (*fptr)();
} command_t;
const command_t *find_command(char *your_var);
const command_t* find_command(char* your_var, const command_t* func_map);
bool check_args(int num_in_first);

View File

@@ -10,15 +10,19 @@ void show_help() {
}
arguments* args = NULL;
int stack[9] = {0*9};
int stack[STACK_SIZE] = {0*STACK_SIZE};
int top = -1;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, eax = 0;
char* labels[256] = {0*256};
int labels_lines[256] = {0*256};
int num_labels = 0;
FILE* fptr = NULL;
last_jmp_code = 0;
stack_codes last_stack_code = STACK_OK;
cmp_return_codes last_cmp_code = CMP_EQUAL;
last_check_args_code = OK; //init error code
size_t char_read = 0;
int exit_code = 0;
int main(int argc, char** argv) {
if (argc != 2) {
printf("Bad arguments.\n");
@@ -41,10 +45,9 @@ int main(int argc, char** argv) {
args = (arguments*)calloc(1, sizeof(arguments));
char line[256];
int line_number = 1;
size_t char_read = 0;
const command_t* com = NULL;
int main_hit = 0;
int line_number = 1;
while (fgets(line, sizeof(line), fptr)) {
char_read += strlen(line) + 1;
@@ -74,7 +77,7 @@ int main(int argc, char** argv) {
continue;
}
com = find_command(ins);
com = find_command(ins, command_map);
if (com != NULL) {
get_args(line, args_pos);
}
@@ -132,6 +135,21 @@ int main(int argc, char** argv) {
return 1;
}
if (last_stack_code != STACK_OK) {
printf("%s ^\n |\nstack %s on line %d", line, last_stack_code == OVERFLOW ? "overflow" : "underflow", line_number);
free(args->arg1);
free(args->arg2);
free(args);
return 1;
}
if (exit_code) {
free(args->arg1);
free(args->arg2);
free(args);
return 0;
}
++line_number;
}

View File

@@ -2,8 +2,10 @@
#include "instructions.h"
#include <stdio.h>
#define MAX_LABEL 256
#define STACK_SIZE 9
extern int stack[9];
extern int top;
extern int stack[STACK_SIZE];
extern int a1, a2, a3, a4, a5, a6, a7, a8, a9, eax; //registers
extern char* labels[MAX_LABEL]; //max 256 labels
extern int labels_lines[MAX_LABEL]; //line numbers for the labels
@@ -11,6 +13,8 @@ extern int num_labels; //number of labels already in use
extern cmp_return_codes last_cmp_code;
extern int last_jmp_code; //easier when global
extern FILE* fptr; //file pointer
extern int exit_code;
extern size_t char_read;
typedef struct arguments{
char* arg1;

View File

@@ -48,7 +48,7 @@ void get_args(char* line, int args_start_pos) {
int write_to_first = 1; //ugly hack but whatever
int j = 0;
for (int i = args_start_pos; i < (int)strlen(line); i++) {
for (int i = args_start_pos; i < (int)strlen(line)+1; i++) {
if (line[i] == '\n' || line[i] == '\0' || line[i] == ';') {
second_arg[j] = '\0';
args->arg2 = (char*)calloc(1, strlen(second_arg) + 1);