Compare commits
11 Commits
fff046f860
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
311c42fad7
|
|||
|
7c8ca9a583
|
|||
|
d0cfbe9b6a
|
|||
|
57aa7b3e13
|
|||
|
2adaa9773a
|
|||
|
a60307609f
|
|||
|
ce612f16f1
|
|||
|
0d5b736a82
|
|||
|
346aaf0bf5
|
|||
|
c4f5222672
|
|||
|
8771e68391
|
34
Makefile_Windows
Normal file
34
Makefile_Windows
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
SRC = src/pasm.c \
|
||||||
|
src/file_utils.c \
|
||||||
|
src/interpreter_states.c \
|
||||||
|
src/instructions.c \
|
||||||
|
src/api.c \
|
||||||
|
src/debug.c \
|
||||||
|
src/libc.c
|
||||||
|
OBJ = $(SRC:.c=.o)
|
||||||
|
NAME = pasm
|
||||||
|
CC = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin\clang
|
||||||
|
CFLAGS = -Os -Iinclude -fno-asynchronous-unwind-tables -DUNICODE -D_UNICODE -m32 -fwritable-strings -DLAIKA -nostdlib -D_WIN32_WINNT=0x0501
|
||||||
|
AR = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin\llvm-ar
|
||||||
|
RANLIB = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin\llvm-ranlib
|
||||||
|
|
||||||
|
all: $(NAME)
|
||||||
|
|
||||||
|
lib: $(OBJ)
|
||||||
|
@if not exist bin (mkdir bin)
|
||||||
|
$(AR) rc bin/$(NAME).lib $(OBJ)
|
||||||
|
$(RANLIB) bin/$(NAME).lib
|
||||||
|
|
||||||
|
$(NAME): lib
|
||||||
|
$(CC) $(CFLAGS) -o bin/$(NAME) tests/interpreter.c -Lbin -lpasm
|
||||||
|
|
||||||
|
interpreter: $(NAME)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist bin (del /q bin\*.*)
|
||||||
|
@if exist src\*.o (del /q src\*.o)
|
||||||
|
|
||||||
|
fclean: clean
|
||||||
|
@if exist bin (rmdir bin)
|
||||||
|
|
||||||
|
.PHONY: all $(NAME) interpreter lib clean fclean
|
||||||
@@ -36,6 +36,7 @@ make lib
|
|||||||
Then link the library to your program, see [this example](tests/lib_use.c).<br>
|
Then link the library to your program, see [this example](tests/lib_use.c).<br>
|
||||||
|
|
||||||
# Code examples
|
# Code examples
|
||||||
|
- [a few functions of libc recoded in PASM](examples/minilibc/)
|
||||||
- [hello world and arrays tests](examples/array.pasm)
|
- [hello world and arrays tests](examples/array.pasm)
|
||||||
- [xor decryption of hello world](examples/xored_hello.pasm)
|
- [xor decryption of hello world](examples/xored_hello.pasm)
|
||||||
- [keylogger](examples/keylogger.pasm)
|
- [keylogger](examples/keylogger.pasm)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ The syntax is very close to x86 Intel Assembly. Here is a list of the operands a
|
|||||||
| **jna** foo | Jumps to `foo` if `cmp` didn't return `CMP_ABOVE` | no |
|
| **jna** foo | Jumps to `foo` if `cmp` didn't return `CMP_ABOVE` | no |
|
||||||
| **jmp** foo | Jumps to `foo` | no |
|
| **jmp** foo | Jumps to `foo` | no |
|
||||||
| **ret** | Returns from the callee to the caller | no |
|
| **ret** | Returns from the callee to the caller | no |
|
||||||
| **end** | Ends the program | no |
|
| **end** | Ends the program, exit code is EAX | no |
|
||||||
| **pop** a1 | Pops the first element of the stack into a1 | no |
|
| **pop** a1 | Pops the first element of the stack into a1 | no |
|
||||||
| **push** 69 | Pushes the value 69 to the top of the stack | no |
|
| **push** 69 | Pushes the value 69 to the top of the stack | no |
|
||||||
| **call** put | Calls the `put` API | yes/no |
|
| **call** put | Calls the `put` API | yes/no |
|
||||||
@@ -92,7 +92,8 @@ The syntax is very close to x86 Intel Assembly. Here is a list of the operands a
|
|||||||
All the `jmp`-related operands (`je`, `jna`, ...) can have a number as argument, this way the program will jump to `x` lines (ex: `jmp 3` will jump 3 lines down).<br>
|
All the `jmp`-related operands (`je`, `jna`, ...) can have a number as argument, this way the program will jump to `x` lines (ex: `jmp 3` will jump 3 lines down).<br>
|
||||||
All the operands are case-sensitive, meaning that `ADD` will be an invalid operand.<br>
|
All the operands are case-sensitive, meaning that `ADD` will be an invalid operand.<br>
|
||||||
Please note that additional operands will be added in the future.<br>
|
Please note that additional operands will be added in the future.<br>
|
||||||
You can use the `&` and the `*` keywords just like in C to get the address and/or dereference and address. Example : `mov a1, &eax`
|
You can use the `&` and the `*` keywords just like in C to get the address and/or dereference and address. Example : `mov a1, &eax`<br>
|
||||||
|
You can also cast registers to `int` or `char` using the C style syntax: `cmp a1, (char)*a2`.<br>
|
||||||
|
|
||||||
## Arrays
|
## Arrays
|
||||||
You can define an array using the keyword `set` like so :
|
You can define an array using the keyword `set` like so :
|
||||||
@@ -120,7 +121,7 @@ Here is a list of all the errors you can encounter and how to fix them :
|
|||||||
* `stack underflow on line X` : you poped to many times without pushing.
|
* `stack underflow on line X` : you poped to many times without pushing.
|
||||||
|
|
||||||
## Running a script
|
## Running a script
|
||||||
Usage : `pasm.exe script.pasm`.
|
Usage : `pasm.exe script.pasm [-d/--debug]`.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
Please message me over on discord at `_.patate` if you want me to add anything to the docs.<br>
|
Please message me over on discord at `_.patate` if you want me to add anything to the docs.<br>
|
||||||
|
|||||||
40
examples/minilibc/memcpy.pasm
Normal file
40
examples/minilibc/memcpy.pasm
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
; memcpy
|
||||||
|
|
||||||
|
end_:
|
||||||
|
push a1
|
||||||
|
call free
|
||||||
|
push a2
|
||||||
|
call free
|
||||||
|
mov eax, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
memcpy:
|
||||||
|
; a1 -> buffer1
|
||||||
|
; a2 -> buffer2
|
||||||
|
; a3 -> n
|
||||||
|
|
||||||
|
mov a5, a1
|
||||||
|
mov a6, a2
|
||||||
|
mov a4, 0
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp a4, a3
|
||||||
|
je end_
|
||||||
|
mov (char)*a5, (char)*a6
|
||||||
|
add a5, 1
|
||||||
|
add a6, 1
|
||||||
|
add a4, 1
|
||||||
|
jmp loop
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a3, 5
|
||||||
|
|
||||||
|
push 10
|
||||||
|
call malloc
|
||||||
|
mov a1, eax ;save the ptr
|
||||||
|
|
||||||
|
push 10
|
||||||
|
call malloc
|
||||||
|
mov a2, eax ;save the ptr
|
||||||
|
|
||||||
|
jmp memcpy
|
||||||
34
examples/minilibc/memset.pasm
Normal file
34
examples/minilibc/memset.pasm
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
; memset
|
||||||
|
|
||||||
|
end_:
|
||||||
|
push a1
|
||||||
|
call free
|
||||||
|
mov eax, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
memset:
|
||||||
|
; a1 -> buffer
|
||||||
|
; a2 -> size
|
||||||
|
; a3 -> value
|
||||||
|
|
||||||
|
sub a2, 1
|
||||||
|
mov a5, 0
|
||||||
|
mov a4, a1
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp a5, a2
|
||||||
|
je end_
|
||||||
|
mov (char)*a4, (char)a3
|
||||||
|
add a4, 1
|
||||||
|
add a5, 1
|
||||||
|
jmp loop
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a2, 10
|
||||||
|
mov a3, 97 ; 'a'
|
||||||
|
|
||||||
|
push a2
|
||||||
|
call malloc
|
||||||
|
mov a1, eax ;save the ptr
|
||||||
|
|
||||||
|
jmp memset
|
||||||
44
examples/minilibc/strcasecmp.pasm
Normal file
44
examples/minilibc/strcasecmp.pasm
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
; strcasecmp
|
||||||
|
|
||||||
|
set str1 "hello, world !\0"
|
||||||
|
set str2 "hello, world !\0"
|
||||||
|
|
||||||
|
end_:
|
||||||
|
mov eax, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
fail:
|
||||||
|
mov eax, a4
|
||||||
|
sub eax, a5
|
||||||
|
end
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a1, str1
|
||||||
|
mov a2, str2
|
||||||
|
mov a3, 0
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp (char)*a1, 0
|
||||||
|
jne 2
|
||||||
|
cmp (char)*a2, 0
|
||||||
|
je end_
|
||||||
|
|
||||||
|
mov a4, (char)*a1
|
||||||
|
cmp a4, 64
|
||||||
|
jna 2
|
||||||
|
cmp a4, 90
|
||||||
|
ja 2
|
||||||
|
add a4, 32
|
||||||
|
|
||||||
|
mov a5, (char)*a2
|
||||||
|
cmp a5, 64
|
||||||
|
jna 2
|
||||||
|
cmp a5, 90
|
||||||
|
ja 2
|
||||||
|
add a5, 32
|
||||||
|
|
||||||
|
cmp a4, a5
|
||||||
|
jne fail
|
||||||
|
add a1, 1
|
||||||
|
add a2, 1
|
||||||
|
jmp loop
|
||||||
25
examples/minilibc/strchr.pasm
Normal file
25
examples/minilibc/strchr.pasm
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
; strchr
|
||||||
|
|
||||||
|
set str "hello, world !\0"
|
||||||
|
|
||||||
|
found:
|
||||||
|
mov a2, a1
|
||||||
|
push a2
|
||||||
|
call print
|
||||||
|
|
||||||
|
end_:
|
||||||
|
mov eax, a2
|
||||||
|
end
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a1, str
|
||||||
|
mov a2, 0
|
||||||
|
mov a3, 111 ; 'o'
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp *a1, 0
|
||||||
|
je end_
|
||||||
|
cmp a3, (char)*a1
|
||||||
|
je found
|
||||||
|
add a1, 1
|
||||||
|
jmp loop
|
||||||
29
examples/minilibc/strcmp.pasm
Normal file
29
examples/minilibc/strcmp.pasm
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
; strcmp
|
||||||
|
|
||||||
|
set str1 "hello, world !\0"
|
||||||
|
set str2 "hello, world !\0"
|
||||||
|
|
||||||
|
end_:
|
||||||
|
mov eax, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
fail:
|
||||||
|
mov eax, (char)*a1
|
||||||
|
sub eax, (char)*a2
|
||||||
|
end
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a1, str1
|
||||||
|
mov a2, str2
|
||||||
|
mov a3, 0
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp (char)*a1, 0
|
||||||
|
jne 2
|
||||||
|
cmp (char)*a2, 0
|
||||||
|
je end_
|
||||||
|
cmp (char)*a1, (char)*a2
|
||||||
|
jne fail
|
||||||
|
add a1, 1
|
||||||
|
add a2, 1
|
||||||
|
jmp loop
|
||||||
18
examples/minilibc/strlen.pasm
Normal file
18
examples/minilibc/strlen.pasm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
; strlen
|
||||||
|
|
||||||
|
set str "hello, world !\0"
|
||||||
|
|
||||||
|
end_:
|
||||||
|
mov eax, a2
|
||||||
|
end
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a1, str
|
||||||
|
mov a2, 0
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp (char)*a1, 0
|
||||||
|
je end_
|
||||||
|
add a2, 1
|
||||||
|
add a1, 1
|
||||||
|
jmp loop
|
||||||
34
examples/minilibc/strncmp.pasm
Normal file
34
examples/minilibc/strncmp.pasm
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
; strncmp
|
||||||
|
|
||||||
|
set str1 "hello, world !\0"
|
||||||
|
set str2 "hella, world !\0"
|
||||||
|
|
||||||
|
end_:
|
||||||
|
mov eax, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
fail:
|
||||||
|
mov eax, (char)*a1
|
||||||
|
sub eax, (char)*a2
|
||||||
|
end
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a1, str1
|
||||||
|
mov a2, str2
|
||||||
|
mov a4, 6 ;n
|
||||||
|
mov a5, 1
|
||||||
|
mov a3, 0
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp a5, a4
|
||||||
|
je end_
|
||||||
|
cmp (char)*a1, 0
|
||||||
|
jne 2
|
||||||
|
cmp (char)*a2, 0
|
||||||
|
je end_
|
||||||
|
cmp (char)*a1, (char)*a2
|
||||||
|
jne fail
|
||||||
|
add a1, 1
|
||||||
|
add a2, 1
|
||||||
|
add a5, 1
|
||||||
|
jmp loop
|
||||||
26
examples/minilibc/strrchr.pasm
Normal file
26
examples/minilibc/strrchr.pasm
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
; strrchr
|
||||||
|
|
||||||
|
set str "hello, world !\0"
|
||||||
|
|
||||||
|
found:
|
||||||
|
mov a2, a1
|
||||||
|
ret
|
||||||
|
|
||||||
|
end_:
|
||||||
|
push a2
|
||||||
|
call print
|
||||||
|
mov eax, a2
|
||||||
|
end
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a1, str
|
||||||
|
mov a2, 0
|
||||||
|
mov a3, 111 ; 'o'
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp (char)*a1, 0
|
||||||
|
je end_
|
||||||
|
cmp (char)a3, (char)*a1
|
||||||
|
je found
|
||||||
|
add a1, 1
|
||||||
|
jmp loop
|
||||||
26
examples/minilibc/strstr.pasm
Normal file
26
examples/minilibc/strstr.pasm
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
; strstr
|
||||||
|
|
||||||
|
set str1 "hello, world !\0"
|
||||||
|
set str2 "hello\0"
|
||||||
|
|
||||||
|
end_:
|
||||||
|
mov eax, a1
|
||||||
|
end
|
||||||
|
|
||||||
|
fail:
|
||||||
|
mov eax, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
main:
|
||||||
|
mov a1, str1
|
||||||
|
mov a2, str2
|
||||||
|
mov a3, 0
|
||||||
|
|
||||||
|
loop:
|
||||||
|
cmp (char)*a2, 0
|
||||||
|
je end_
|
||||||
|
cmp (char)*a1, (char)*a2
|
||||||
|
jne fail
|
||||||
|
add a1, 1
|
||||||
|
add a2, 1
|
||||||
|
jmp loop
|
||||||
@@ -29,26 +29,27 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>ClangCL</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>ClangCL</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>ClangCL</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>ClangCL</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -100,20 +101,24 @@
|
|||||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
<ExceptionHandling>false</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
<Lib>
|
<Lib>
|
||||||
<ExportNamedFunctions>pasm_run_script</ExportNamedFunctions>
|
<ExportNamedFunctions>
|
||||||
|
</ExportNamedFunctions>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(LaikaBuild)' != ''">
|
<ItemDefinitionGroup Condition="'$(LaikaBuild)' != ''">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalOptions>/DLAIKA %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/DLAIKA %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
@@ -137,7 +142,8 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
<Lib>
|
<Lib>
|
||||||
<ExportNamedFunctions>pasm_run_script</ExportNamedFunctions>
|
<ExportNamedFunctions>
|
||||||
|
</ExportNamedFunctions>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -156,7 +162,8 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
<Lib>
|
<Lib>
|
||||||
<ExportNamedFunctions>pasm_run_script</ExportNamedFunctions>
|
<ExportNamedFunctions>
|
||||||
|
</ExportNamedFunctions>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -182,7 +189,8 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
<Lib>
|
<Lib>
|
||||||
<ExportNamedFunctions>pasm_run_script</ExportNamedFunctions>
|
<ExportNamedFunctions>
|
||||||
|
</ExportNamedFunctions>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
24
src/api.c
24
src/api.c
@@ -53,6 +53,21 @@ void api_print() {
|
|||||||
dprintf(f, "%s", address);
|
dprintf(f, "%s", address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void api_free() {
|
||||||
|
void *addr = (void *)state->STACK[state->STACK_IDX--];
|
||||||
|
free_(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_malloc() {
|
||||||
|
long size = state->STACK[state->STACK_IDX--];
|
||||||
|
#ifdef _WIN32
|
||||||
|
state->registers->eax = 0;
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
state->registers->eax = (long long)malloc(size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void api_callrawaddr() {
|
void api_callrawaddr() {
|
||||||
long long address = state->STACK[state->STACK_IDX--];
|
long long address = state->STACK[state->STACK_IDX--];
|
||||||
|
|
||||||
@@ -66,8 +81,7 @@ void api_callrawaddr() {
|
|||||||
#endif
|
#endif
|
||||||
void api_VirtualAlloc(void) {
|
void api_VirtualAlloc(void) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char api[] = "[nwyzfqFqqth";
|
fVirtualAlloc pVirtualAlloc = GetApi(L"kernel32.dll", "[nwyzfqFqqth");
|
||||||
fVirtualAlloc pVirtualAlloc = GetApi(L"kernel32.dll", PCAESAR_DECRYPT(api));
|
|
||||||
if (pVirtualAlloc == NULL) {
|
if (pVirtualAlloc == NULL) {
|
||||||
state->STACK_IDX -= 4;
|
state->STACK_IDX -= 4;
|
||||||
state->registers->eax = 1;
|
state->registers->eax = 1;
|
||||||
@@ -90,8 +104,7 @@ void api_VirtualAlloc(void) {
|
|||||||
#endif
|
#endif
|
||||||
void api_VirtualFree(void) {
|
void api_VirtualFree(void) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char api[] = "[nwyzfqKwjj";
|
fVirtualFree pVirtualFree = GetApi(L"kernel32.dll", "[nwyzfqKwjj");
|
||||||
fVirtualFree pVirtualFree = GetApi(L"kernel32.dll", PCAESAR_DECRYPT(api));
|
|
||||||
if (pVirtualFree == NULL) {
|
if (pVirtualFree == NULL) {
|
||||||
state->STACK_IDX -= 3;
|
state->STACK_IDX -= 3;
|
||||||
state->registers->eax = 1;
|
state->registers->eax = 1;
|
||||||
@@ -113,8 +126,7 @@ void api_VirtualFree(void) {
|
|||||||
#endif
|
#endif
|
||||||
void api_GetAsyncKeyState(void) {
|
void api_GetAsyncKeyState(void) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char api[] = "LjyFx~shPj~Xyfyj";
|
fGetAsyncKeyState pGetAsyncKeyState = GetApi(L"user32.dll", "LjyFx~shPj~Xyfyj");
|
||||||
fGetAsyncKeyState pGetAsyncKeyState = GetApi(L"user32.dll", PCAESAR_DECRYPT(api));
|
|
||||||
if (pGetAsyncKeyState == NULL) {
|
if (pGetAsyncKeyState == NULL) {
|
||||||
state->STACK_IDX -= 1;
|
state->STACK_IDX -= 1;
|
||||||
state->registers->eax = 1;
|
state->registers->eax = 1;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
void api_put();
|
void api_put();
|
||||||
void api_print();
|
void api_print();
|
||||||
|
void api_free();
|
||||||
|
void api_malloc();
|
||||||
void api_callrawaddr();
|
void api_callrawaddr();
|
||||||
|
|
||||||
// generated APIs here
|
// generated APIs here
|
||||||
@@ -15,6 +17,8 @@ void api_GetAsyncKeyState();
|
|||||||
static const command_t api_map[] = {
|
static const command_t api_map[] = {
|
||||||
{.command = "put", .fptr = api_put},
|
{.command = "put", .fptr = api_put},
|
||||||
{.command = "print", .fptr = api_print},
|
{.command = "print", .fptr = api_print},
|
||||||
|
{.command = "malloc", .fptr = api_malloc},
|
||||||
|
{.command = "free", .fptr = api_free},
|
||||||
{.command = "CallRawAddress", .fptr = api_callrawaddr},
|
{.command = "CallRawAddress", .fptr = api_callrawaddr},
|
||||||
|
|
||||||
// generated APIs here
|
// generated APIs here
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ int add_breakpoint(char *in, int *bp) {
|
|||||||
return 1;
|
return 1;
|
||||||
bp_add(bp, line - 1);
|
bp_add(bp, line - 1);
|
||||||
printf("breakpoint added at line %d.\n", line);
|
printf("breakpoint added at line %d.\n", line);
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rem_breakpoint(char *in, int *bp) {
|
int rem_breakpoint(char *in, int *bp) {
|
||||||
@@ -127,8 +127,8 @@ int rem_breakpoint(char *in, int *bp) {
|
|||||||
return 1;
|
return 1;
|
||||||
bp_rem(bp, line - 1);
|
bp_rem(bp, line - 1);
|
||||||
printf("breakpoint at line %d deleted.\n", line);
|
printf("breakpoint at line %d deleted.\n", line);
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_input(char *line) {
|
void debug_input(char *line) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -14,16 +15,29 @@ bool is_array(char* arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool is_reg(char* arg) {
|
bool is_reg(char* arg) {
|
||||||
if (arg[0] == '&' || arg[0] == '*')
|
char *arg2 = strdup_(arg);
|
||||||
++arg;
|
char *s = arg2;
|
||||||
if (is_array(arg))
|
strtok_(arg2, ")");
|
||||||
|
arg2 = strtok_(NULL, ")");
|
||||||
|
if (arg2 == NULL) {
|
||||||
|
arg2 = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg2[0] == '&' || arg2[0] == '*')
|
||||||
|
++arg2;
|
||||||
|
if (is_array(arg2)) {
|
||||||
|
free_(s);
|
||||||
return true;
|
return true;
|
||||||
return (strcmp__(arg, "eax") == 0) || (((arg[0] == 'a' &&
|
}
|
||||||
('1' <= arg[1] && arg[1] <= '9'))) && strlen(arg) == 2);
|
int r = (strcmp__(arg2, "eax") == 0) || (((arg2[0] == 'a' &&
|
||||||
|
('1' <= arg2[1] && arg2[1] <= '9'))) && strlen__(arg2) == 2);
|
||||||
|
|
||||||
|
free_(s);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_num(char* arg) {
|
bool is_num(char* arg) {
|
||||||
return (strtol_(arg, NULL, 10) != 0 || (arg[0] == '0' && strlen(arg) == 1));
|
return (strtol_(arg, NULL, 10) != 0 || (arg[0] == '0' && strlen__(arg) == 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_args(s_arguments *args, int num_in_first, int num_args) {
|
bool check_args(s_arguments *args, int num_in_first, int num_args) {
|
||||||
@@ -45,15 +59,48 @@ bool check_args(s_arguments *args, int num_in_first, int num_args) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long* get_reg(char* reg_char) {
|
long long apply_cast(long long val, char *arg) {
|
||||||
|
long long v = val;
|
||||||
|
long long r = v;
|
||||||
|
int c = parse_argument_cast(arg);
|
||||||
|
|
||||||
|
if (c == -1) return val;
|
||||||
|
switch (c) {
|
||||||
|
case 1:
|
||||||
|
r = (long long)((char)v);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
r = (long long)((int)v);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long* get_reg(char* arg, int dontderef) {
|
||||||
|
char *reg_char = strdup_(arg);
|
||||||
|
char *s = reg_char;
|
||||||
|
strtok_(reg_char, ")");
|
||||||
|
reg_char = strtok_(NULL, ")");
|
||||||
|
if (reg_char == NULL) {
|
||||||
|
reg_char = arg;
|
||||||
|
}
|
||||||
|
|
||||||
int deref = reg_char[0] == '*';
|
int deref = reg_char[0] == '*';
|
||||||
|
|
||||||
if (reg_char[0] == '&' || reg_char[0] == '*')
|
if (reg_char[0] == '&' || reg_char[0] == '*')
|
||||||
++reg_char;
|
++reg_char;
|
||||||
for (int i = 0; i < state->num_arrays; i++)
|
for (int i = 0; i < state->num_arrays; i++) {
|
||||||
if (strcmp__(state->ARRAYS_NAME[i], reg_char) == 0)
|
if (strcmp__(state->ARRAYS_NAME[i], reg_char) == 0) {
|
||||||
|
free_(s);
|
||||||
return (long long *)&state->ARRAYS_VALUES[i];
|
return (long long *)&state->ARRAYS_VALUES[i];
|
||||||
switch (reg_char[1]) {
|
}
|
||||||
|
}
|
||||||
|
char c = reg_char[1];
|
||||||
|
free_(s);
|
||||||
|
if (dontderef) deref = 1;
|
||||||
|
switch (c) {
|
||||||
case '1' :
|
case '1' :
|
||||||
return deref ? (long long*)state->registers->a1 : &state->registers->a1;
|
return deref ? (long long*)state->registers->a1 : &state->registers->a1;
|
||||||
case '2' :
|
case '2' :
|
||||||
@@ -79,19 +126,23 @@ long long* get_reg(char* reg_char) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long long get_value(char* arg) {
|
long long get_value(char* arg, int size) {
|
||||||
long long ret = 0;
|
long long ret = 0;
|
||||||
|
|
||||||
if (is_reg(arg)) {
|
if (is_reg(arg)) {
|
||||||
if (arg[0] == '&') {
|
if (arg[0] == '&') {
|
||||||
ret = (long long)get_reg(arg);
|
return (long long)get_reg(arg, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = *get_reg(arg);
|
if (size == 1)
|
||||||
|
return *((char *)get_reg(arg, 0));
|
||||||
|
if (size == 4)
|
||||||
|
return *((int *)get_reg(arg, 0));
|
||||||
|
return *get_reg(arg, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (strlen(arg) > 2 && arg[0] == '0' && arg[1] == 'x') {
|
if (strlen__(arg) > 2 && arg[0] == '0' && arg[1] == 'x') {
|
||||||
ret = strtol_(arg, NULL, 16);
|
ret = strtol_(arg, NULL, 16);
|
||||||
}
|
}
|
||||||
ret = strtol_(arg, NULL, 10);
|
ret = strtol_(arg, NULL, 10);
|
||||||
@@ -117,8 +168,9 @@ void cmp() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long a1_ = get_value(state->args->arg1);
|
long long a1_ = get_value(state->args->arg1, parse_argument_cast(state->args->arg1));
|
||||||
long long a2_ = get_value(state->args->arg2);
|
long long a2_ = get_value(state->args->arg2, parse_argument_cast(state->args->arg2));
|
||||||
|
a2_ = apply_cast(a2_, state->args->arg2);
|
||||||
|
|
||||||
if (a1_ == a2_) state->last_cmp_code = CMP_EQUAL;
|
if (a1_ == a2_) state->last_cmp_code = CMP_EQUAL;
|
||||||
else if (a1_ > a2_) state->last_cmp_code = CMP_ABOVE;
|
else if (a1_ > a2_) state->last_cmp_code = CMP_ABOVE;
|
||||||
@@ -160,9 +212,9 @@ void jmp() {
|
|||||||
state->registers->eax = 0;
|
state->registers->eax = 0;
|
||||||
for (int i = 0; i < state->num_labels; i++) {
|
for (int i = 0; i < state->num_labels; i++) {
|
||||||
if (state->labels[i] == NULL) break;
|
if (state->labels[i] == NULL) break;
|
||||||
if (strlen(state->labels[i]) - 1 != strlen(state->args->arg1))
|
if (strlen__(state->labels[i]) - 1 != strlen__(state->args->arg1))
|
||||||
continue;
|
continue;
|
||||||
if (strncmp__(state->args->arg1, state->labels[i], strlen(state->labels[i]) - 1) == 0) {
|
if (strncmp__(state->args->arg1, state->labels[i], strlen__(state->labels[i]) - 1) == 0) {
|
||||||
state->RET_STACK[++state->RET_STACK_IDX] = state->curr_line;
|
state->RET_STACK[++state->RET_STACK_IDX] = state->curr_line;
|
||||||
state->curr_line = state->labels_values[i];
|
state->curr_line = state->labels_values[i];
|
||||||
return;
|
return;
|
||||||
@@ -206,7 +258,7 @@ void sub() {
|
|||||||
if (!check_args(state->args, 0, 2)) {
|
if (!check_args(state->args, 0, 2)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*get_reg(state->args->arg1) -= get_value(state->args->arg2);
|
*get_reg(state->args->arg1, 0) -= apply_cast(get_value(state->args->arg2, 0), state->args->arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add() {
|
void add() {
|
||||||
@@ -214,7 +266,7 @@ void add() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*get_reg(state->args->arg1) += get_value(state->args->arg2);
|
*get_reg(state->args->arg1 ,0) += apply_cast(get_value(state->args->arg2, 0), state->args->arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -224,7 +276,7 @@ void _sqrt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef LAIKA //Realistically Laika won't ever need sqrt, + that creates linker errors with the CRT
|
#ifndef LAIKA //Realistically Laika won't ever need sqrt, + that creates linker errors with the CRT
|
||||||
*get_reg(state->args->arg1) = (long long)sqrt(get_value(state->args->arg1));
|
*get_reg(state->args->arg1, 0) = apply_cast((long long)sqrt(get_value(state->args->arg1, 0)), state->args->arg1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +285,7 @@ void neg() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*get_reg(state->args->arg1) = -get_value(state->args->arg1);
|
*get_reg(state->args->arg1, 0) = -apply_cast(get_value(state->args->arg1, 0), state->args->arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mul() {
|
void mul() {
|
||||||
@@ -244,8 +296,8 @@ void mul() {
|
|||||||
#ifdef LAIKA
|
#ifdef LAIKA
|
||||||
//MSVC wants to link __allmul, but a mul is just a lot of add, isn't it ?
|
//MSVC wants to link __allmul, but a mul is just a lot of add, isn't it ?
|
||||||
|
|
||||||
long long v1 = *get_reg(state->args->arg1);
|
long long v1 = *get_reg(state->args->arg1, 0);
|
||||||
long long v2 = get_value(state->args->arg2);
|
long long v2 = apply_cast(get_value(state->args->arg2, 0), state->args->arg2);
|
||||||
long long result = 0;
|
long long result = 0;
|
||||||
int isNegative = 0;
|
int isNegative = 0;
|
||||||
|
|
||||||
@@ -263,7 +315,7 @@ void mul() {
|
|||||||
}
|
}
|
||||||
v1 = isNegative ? -result : result;
|
v1 = isNegative ? -result : result;
|
||||||
#else
|
#else
|
||||||
*get_reg(state->args->arg1) *= get_value(state->args->arg2);
|
*get_reg(state->args->arg1, 0) *= apply_cast(get_value(state->args->arg2, 0), state->args->arg2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,8 +327,8 @@ void _div() {
|
|||||||
#ifdef LAIKA
|
#ifdef LAIKA
|
||||||
//MSVC wants to link __alldiv, but a div is just a lot of sub, isn't it ?
|
//MSVC wants to link __alldiv, but a div is just a lot of sub, isn't it ?
|
||||||
|
|
||||||
long long dividend = *get_reg(state->args->arg1);
|
long long dividend = *get_reg(state->args->arg1, 0);
|
||||||
long long divisor = get_value(state->args->arg2);
|
long long divisor = apply_cast(get_value(state->args->arg2, 0), state->args->arg2);
|
||||||
|
|
||||||
long long quotient = 0;
|
long long quotient = 0;
|
||||||
long long sign = 1;
|
long long sign = 1;
|
||||||
@@ -296,7 +348,7 @@ void _div() {
|
|||||||
|
|
||||||
dividend = sign * quotient;
|
dividend = sign * quotient;
|
||||||
#else
|
#else
|
||||||
*get_reg(state->args->arg1) /= get_value(state->args->arg2);
|
*get_reg(state->args->arg1, 0) /= apply_cast(get_value(state->args->arg2, 0), state->args->arg2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,8 +356,19 @@ void mov() {
|
|||||||
if (!check_args(state->args, 0, 2)) {
|
if (!check_args(state->args, 0, 2)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int c = parse_argument_cast(state->args->arg1);
|
||||||
*get_reg(state->args->arg1) = get_value(state->args->arg2);
|
|
||||||
|
if (c == -1) *get_reg(state->args->arg1, 0) = get_value(state->args->arg2, 0);
|
||||||
|
switch (c) {
|
||||||
|
case 1:
|
||||||
|
*((char *)get_reg(state->args->arg1, 1)) = (char)apply_cast(get_value(state->args->arg2, parse_argument_cast(state->args->arg2)), state->args->arg2);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*((int *)get_reg(state->args->arg1, 1)) = (int)apply_cast(get_value(state->args->arg2, parse_argument_cast(state->args->arg2)), state->args->arg2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void call() {
|
void call() {
|
||||||
@@ -324,7 +387,7 @@ void push() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long value = get_value(state->args->arg1);
|
long long value = apply_cast(get_value(state->args->arg1, 0), state->args->arg1);
|
||||||
if (value == 0 && !is_reg(state->args->arg1)) {
|
if (value == 0 && !is_reg(state->args->arg1)) {
|
||||||
if (state->args->arg1[0] == '\\') {
|
if (state->args->arg1[0] == '\\') {
|
||||||
switch (state->args->arg1[1]) {
|
switch (state->args->arg1[1]) {
|
||||||
@@ -361,7 +424,7 @@ void pop() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*get_reg(state->args->arg1) = state->STACK[state->STACK_IDX--];
|
*get_reg(state->args->arg1, 0) = state->STACK[state->STACK_IDX--];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _and() {
|
void _and() {
|
||||||
@@ -369,7 +432,7 @@ void _and() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->registers->eax = get_value(state->args->arg1) & get_value(state->args->arg2);
|
state->registers->eax = get_value(state->args->arg1, 0) & get_value(state->args->arg2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _xor() {
|
void _xor() {
|
||||||
@@ -377,9 +440,9 @@ void _xor() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->registers->eax = get_value(state->args->arg1) ^ get_value(state->args->arg2);
|
state->registers->eax = get_value(state->args->arg1, 0) ^ get_value(state->args->arg2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void end() {
|
void end() {
|
||||||
state->should_exit = 0; //could use EAX for return code but i don't think i care
|
state->should_exit = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ typedef struct command_s {
|
|||||||
|
|
||||||
bool is_reg(char* arg);
|
bool is_reg(char* arg);
|
||||||
bool check_args(s_arguments *args, int num_in_first, int num_args);
|
bool check_args(s_arguments *args, int num_in_first, int num_args);
|
||||||
long long* get_reg(char* arg);
|
long long* get_reg(char* arg, int dontderef);
|
||||||
long long* get_reg(char* reg_char);
|
|
||||||
|
|
||||||
void add();
|
void add();
|
||||||
void sub();
|
void sub();
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ void free__state() {
|
|||||||
free_(state->labels_values);
|
free_(state->labels_values);
|
||||||
|
|
||||||
for (int j = 0; j < state->num_arrays; j++) {
|
for (int j = 0; j < state->num_arrays; j++) {
|
||||||
if (state->ARRAYS_NAME[j])
|
if (state->ARRAYS_NAME[j])
|
||||||
free_(state->ARRAYS_NAME[j]);
|
free_(state->ARRAYS_NAME[j]);
|
||||||
if (state->ARRAYS_VALUES[j])
|
if (state->ARRAYS_VALUES[j])
|
||||||
free_(state->ARRAYS_VALUES[j]);
|
free_(state->ARRAYS_VALUES[j]);
|
||||||
}
|
}
|
||||||
@@ -87,6 +87,10 @@ int get_exit_state() {
|
|||||||
return state->should_exit;
|
return state->should_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_exit_code() {
|
||||||
|
return state->registers->eax;
|
||||||
|
}
|
||||||
|
|
||||||
LABEL_ERR add_label(char *label, int line) {
|
LABEL_ERR add_label(char *label, int line) {
|
||||||
if (label == NULL)
|
if (label == NULL)
|
||||||
return LABEL_INVALID;
|
return LABEL_INVALID;
|
||||||
@@ -129,7 +133,7 @@ ARRAY_ERR add_array(char* line) {
|
|||||||
}
|
}
|
||||||
char *ptr = strtok_(line_copy, " "); //set
|
char *ptr = strtok_(line_copy, " "); //set
|
||||||
ptr = strtok_(NULL, " "); //array name
|
ptr = strtok_(NULL, " "); //array name
|
||||||
if (ptr == NULL || strlen(line) <= (4 + strlen(ptr))) {
|
if (ptr == NULL || strlen__(line) <= (4 + strlen__(ptr))) {
|
||||||
free_(line_copy);
|
free_(line_copy);
|
||||||
return ARRAY_ERROR;
|
return ARRAY_ERROR;
|
||||||
}
|
}
|
||||||
@@ -145,7 +149,7 @@ ARRAY_ERR add_array(char* line) {
|
|||||||
#else
|
#else
|
||||||
state->ARRAYS_NAME[state->num_arrays] = strdup(ptr);
|
state->ARRAYS_NAME[state->num_arrays] = strdup(ptr);
|
||||||
#endif
|
#endif
|
||||||
ptr += strlen(ptr) + 1; //getting the data in the array, data is data after all
|
ptr += strlen__(ptr) + 1; //getting the data in the array, data is data after all
|
||||||
if (ptr == NULL || ptr[0] == ' ' || ptr[0] == '\0') {
|
if (ptr == NULL || ptr[0] == ' ' || ptr[0] == '\0') {
|
||||||
free_(line_copy);
|
free_(line_copy);
|
||||||
return ARRAY_ERROR;
|
return ARRAY_ERROR;
|
||||||
@@ -191,7 +195,8 @@ ARRAY_ERR add_array(char* line) {
|
|||||||
}
|
}
|
||||||
arr_char[i++] = (long long)* ptr++;
|
arr_char[i++] = (long long)* ptr++;
|
||||||
}
|
}
|
||||||
state->ARRAYS_VALUES[state->num_arrays++] = arr_char;
|
state->ARRAYS_VALUES[state->num_arrays++] = (long long *)arr_char;
|
||||||
|
free_(line_copy);
|
||||||
return ARRAY_OK;
|
return ARRAY_OK;
|
||||||
}
|
}
|
||||||
ptr = strtok_(ptr, ",");
|
ptr = strtok_(ptr, ",");
|
||||||
@@ -212,13 +217,13 @@ ARRAY_ERR add_array(char* line) {
|
|||||||
return ARRAY_ERROR;
|
return ARRAY_ERROR;
|
||||||
}
|
}
|
||||||
state->ARRAYS_VALUES = temp2;
|
state->ARRAYS_VALUES = temp2;
|
||||||
ptr = line + 4 + strlen(state->ARRAYS_NAME[state->num_arrays]) + 1; //leave me alone i'm tired
|
ptr = line + 4 + strlen__(state->ARRAYS_NAME[state->num_arrays]) + 1; //leave me alone i'm tired
|
||||||
ptr = strtok_(ptr, ",");
|
ptr = strtok_(ptr, ",");
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while (ptr != NULL && j < array_size) {
|
while (ptr != NULL && j < array_size) {
|
||||||
if (ptr[0] == ' ')
|
if (ptr[0] == ' ')
|
||||||
++ptr;
|
++ptr;
|
||||||
if (strlen(ptr) > 2 && ptr[0] == '0' && ptr[1] == 'x') {
|
if (strlen__(ptr) > 2 && ptr[0] == '0' && ptr[1] == 'x') {
|
||||||
arr[j++] = strtol_(ptr, NULL, 16);
|
arr[j++] = strtol_(ptr, NULL, 16);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -264,9 +269,19 @@ void sanitize_arguments() { //removes trailing spaces
|
|||||||
state->args->arg2[i] = '\0';
|
state->args->arg2[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_argument_cast(char *arg) {
|
||||||
|
//possible casts : int, char
|
||||||
|
|
||||||
|
if (strncmp__(arg, "(char", 5) == 0)
|
||||||
|
return 1;
|
||||||
|
if (strncmp__(arg, "(int", 4) == 0)
|
||||||
|
return 4;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int parse_arguments(char *line) {
|
int parse_arguments(char *line) {
|
||||||
strcpy(state->args->arg1, "");
|
strcpy__(state->args->arg1, "");
|
||||||
strcpy(state->args->arg2, "");
|
strcpy__(state->args->arg2, "");
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *line_cpy = strdup_(line);
|
char *line_cpy = strdup_(line);
|
||||||
@@ -283,12 +298,12 @@ int parse_arguments(char *line) {
|
|||||||
free_(line_cpy);
|
free_(line_cpy);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
strcpy(state->args->arg1, arg);
|
strcpy__(state->args->arg1, arg);
|
||||||
if ((arg = extract_arg(ptr, 1)) == NULL) {
|
if ((arg = extract_arg(ptr, 1)) == NULL) {
|
||||||
free_(line_cpy);
|
free_(line_cpy);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
strcpy(state->args->arg2, arg);
|
strcpy__(state->args->arg2, arg);
|
||||||
free_(line_cpy);
|
free_(line_cpy);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ int init_state();
|
|||||||
void free__state();
|
void free__state();
|
||||||
void set_exit_state(int exit_state);
|
void set_exit_state(int exit_state);
|
||||||
int get_exit_state();
|
int get_exit_state();
|
||||||
|
int get_exit_code();
|
||||||
|
int parse_argument_cast(char *arg);
|
||||||
LABEL_ERR add_label(char *label, int line);
|
LABEL_ERR add_label(char *label, int line);
|
||||||
ARRAY_ERR add_array(char *line);
|
ARRAY_ERR add_array(char *line);
|
||||||
void sanitize_arguments();
|
void sanitize_arguments();
|
||||||
|
|||||||
63
src/libc.c
63
src/libc.c
@@ -3,11 +3,40 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE _crt_heap_ = 0;
|
HANDLE _crt_heap_ = 0;
|
||||||
|
|
||||||
#include <winternl.h>
|
_ACRTIMP int __cdecl __stdio_common_vsprintf(
|
||||||
|
_In_ unsigned __int64 _Options,
|
||||||
|
_Out_writes_opt_z_(_BufferCount) char* _Buffer,
|
||||||
|
_In_ size_t _BufferCount,
|
||||||
|
_In_z_ _Printf_format_string_params_(2) char const* _Format,
|
||||||
|
_In_opt_ _locale_t _Locale,
|
||||||
|
va_list _ArgList
|
||||||
|
) {
|
||||||
|
return 0; //clang linker errors
|
||||||
|
}
|
||||||
|
|
||||||
|
//#include <winternl.h>
|
||||||
|
#ifndef _MSC_VER
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
#define GetTEB() ((PTEB)__readgsqword(FIELD_OFFSET(NT_TIB, Self)))
|
unsigned long long __readgsqword(unsigned long long offset) {
|
||||||
|
unsigned long long value;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"movq %%gs:%1, %0"
|
||||||
|
: "=r" (value)
|
||||||
|
: "m" (*(unsigned long long*)(offset))
|
||||||
|
);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#define GetTEB() ((PTEB)__readfsdword(FIELD_OFFSET(NT_TIB, Self)))
|
unsigned long __readfsdword(unsigned long offset) {
|
||||||
|
unsigned long value;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"movl %%fs:%1, %0"
|
||||||
|
: "=r" (value)
|
||||||
|
: "m" (*(unsigned long*)(offset))
|
||||||
|
);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef LPVOID(WINAPI* fHeapAlloc)(HANDLE, DWORD, SIZE_T);
|
typedef LPVOID(WINAPI* fHeapAlloc)(HANDLE, DWORD, SIZE_T);
|
||||||
@@ -67,15 +96,13 @@ void* malloc_(size_t _Size) {
|
|||||||
#else
|
#else
|
||||||
if (_crt_heap_ == 0) {
|
if (_crt_heap_ == 0) {
|
||||||
if (pHeapCreate == NULL) {
|
if (pHeapCreate == NULL) {
|
||||||
char api[] = "MjfuHwjfyj";
|
pHeapCreate = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("MjfuHwjfyj"));
|
||||||
pHeapCreate = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
_crt_heap_ = pHeapCreate(0, 0, 0);
|
_crt_heap_ = pHeapCreate(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pHeapAlloc == NULL) {
|
if (pHeapAlloc == NULL) {
|
||||||
char api[] = "MjfuFqqth";
|
pHeapAlloc = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("MjfuFqqth"));
|
||||||
pHeapAlloc = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
return pHeapAlloc(_crt_heap_, HEAP_ZERO_MEMORY, _Size);
|
return pHeapAlloc(_crt_heap_, HEAP_ZERO_MEMORY, _Size);
|
||||||
#endif
|
#endif
|
||||||
@@ -87,8 +114,7 @@ void free_(void* _Block) {
|
|||||||
return;
|
return;
|
||||||
#else
|
#else
|
||||||
if (pHeapFree == NULL) {
|
if (pHeapFree == NULL) {
|
||||||
char api[] = "MjfuKwjj";
|
pHeapFree = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("MjfuKwjj"));
|
||||||
pHeapFree = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
pHeapFree(_crt_heap_, 0, _Block);
|
pHeapFree(_crt_heap_, 0, _Block);
|
||||||
return;
|
return;
|
||||||
@@ -101,21 +127,18 @@ void* realloc_(void* _Block, size_t _Size) {
|
|||||||
#else
|
#else
|
||||||
if (_crt_heap_ == 0) {
|
if (_crt_heap_ == 0) {
|
||||||
if (pHeapCreate == NULL) {
|
if (pHeapCreate == NULL) {
|
||||||
char api[] = "MjfuHwjfyj";
|
pHeapCreate = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("MjfuHwjfyj"));
|
||||||
pHeapCreate = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
_crt_heap_ = pHeapCreate(0, 0, 0);
|
_crt_heap_ = pHeapCreate(0, 0, 0);
|
||||||
}
|
}
|
||||||
if (_Block == NULL) {
|
if (_Block == NULL) {
|
||||||
if (pHeapAlloc == NULL) {
|
if (pHeapAlloc == NULL) {
|
||||||
char api[] = "MjfuFqqth";
|
pHeapAlloc = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("MjfuFqqth"));
|
||||||
pHeapAlloc = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
return pHeapAlloc(_crt_heap_, HEAP_ZERO_MEMORY, _Size);
|
return pHeapAlloc(_crt_heap_, HEAP_ZERO_MEMORY, _Size);
|
||||||
}
|
}
|
||||||
if (pHeapReAlloc == NULL) {
|
if (pHeapReAlloc == NULL) {
|
||||||
char api[] = "MjfuWjFqqth";
|
pHeapReAlloc = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("MjfuWjFqqth"));
|
||||||
pHeapReAlloc = GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
return pHeapReAlloc(_crt_heap_, HEAP_ZERO_MEMORY, _Block, _Size);
|
return pHeapReAlloc(_crt_heap_, HEAP_ZERO_MEMORY, _Block, _Size);
|
||||||
#endif
|
#endif
|
||||||
@@ -340,10 +363,10 @@ cont:
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _MSC_VER
|
||||||
#pragma optimize("", off)
|
#pragma optimize("", off)
|
||||||
#endif
|
#endif
|
||||||
void* memset__(void* a, int val, size_t size) {
|
PASM_NOOPT void* memset__(void* a, int val, size_t size) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return memset(a, val, size);
|
return memset(a, val, size);
|
||||||
#endif
|
#endif
|
||||||
@@ -353,7 +376,7 @@ void* memset__(void* a, int val, size_t size) {
|
|||||||
((char*)a)[i] = (char)val;
|
((char*)a)[i] = (char)val;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _MSC_VER
|
||||||
#pragma optimize("", on)
|
#pragma optimize("", on)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -384,7 +407,7 @@ wchar_t* wcsstr__(const wchar_t* haystack, const wchar_t* needle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HMODULE get_module(const wchar_t* mod) {
|
HMODULE get_module(const wchar_t* mod) {
|
||||||
PTEB tebPtr = GetTEB();
|
PTEB_ tebPtr = GetTEB();
|
||||||
|
|
||||||
PPEB_LDR_DATA ldrData = tebPtr->ProcessEnvironmentBlock->Ldr;
|
PPEB_LDR_DATA ldrData = tebPtr->ProcessEnvironmentBlock->Ldr;
|
||||||
PLIST_ENTRY moduleList = &(ldrData->InMemoryOrderModuleList);
|
PLIST_ENTRY moduleList = &(ldrData->InMemoryOrderModuleList);
|
||||||
@@ -419,7 +442,7 @@ void* GetProcAddress_(HMODULE hModule, LPCSTR lpProcName) {
|
|||||||
|
|
||||||
for (DWORD i = 0; i < exportDir->NumberOfNames; i++) {
|
for (DWORD i = 0; i < exportDir->NumberOfNames; i++) {
|
||||||
const char* functionName = (const char*)((BYTE*)hModule + nameRVAs[i]);
|
const char* functionName = (const char*)((BYTE*)hModule + nameRVAs[i]);
|
||||||
if (strcmp(functionName, lpProcName) == 0) {
|
if (strcmp__(functionName, lpProcName) == 0) {
|
||||||
DWORD funcRVA = addrRVAs[ordinals[i]];
|
DWORD funcRVA = addrRVAs[ordinals[i]];
|
||||||
void* funcPtr = (void*)((BYTE*)hModule + funcRVA);
|
void* funcPtr = (void*)((BYTE*)hModule + funcRVA);
|
||||||
return funcPtr;
|
return funcPtr;
|
||||||
|
|||||||
114
src/libc.h
114
src/libc.h
@@ -1,10 +1,122 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define PASM_NOOPT __attribute__((optimize("O0")))
|
||||||
|
#else
|
||||||
|
#define PASM_NOOPT
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define PASM_NOOPT
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
//#include <winternl.h>
|
||||||
|
|
||||||
extern HANDLE _crt_heap_;
|
extern HANDLE _crt_heap_;
|
||||||
|
|
||||||
|
typedef long NTSTATUS;
|
||||||
|
|
||||||
|
#define FD_SET_(fd, set) do { \
|
||||||
|
if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \
|
||||||
|
((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=(fd);\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
typedef struct _UNICODE_STRING {
|
||||||
|
USHORT Length;
|
||||||
|
USHORT MaximumLength;
|
||||||
|
PWSTR Buffer;
|
||||||
|
} UNICODE_STRING;
|
||||||
|
typedef UNICODE_STRING* PUNICODE_STRING;
|
||||||
|
typedef const UNICODE_STRING* PCUNICODE_STRING;
|
||||||
|
|
||||||
|
typedef struct _PEB_LDR_DATA {
|
||||||
|
BYTE Reserved1[8];
|
||||||
|
PVOID Reserved2[3];
|
||||||
|
LIST_ENTRY InMemoryOrderModuleList;
|
||||||
|
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
||||||
|
|
||||||
|
typedef struct _LDR_DATA_TABLE_ENTRY {
|
||||||
|
PVOID Reserved1[2];
|
||||||
|
LIST_ENTRY InMemoryOrderLinks;
|
||||||
|
PVOID Reserved2[2];
|
||||||
|
PVOID DllBase;
|
||||||
|
PVOID Reserved3[2];
|
||||||
|
UNICODE_STRING FullDllName;
|
||||||
|
BYTE Reserved4[8];
|
||||||
|
PVOID Reserved5[3];
|
||||||
|
union {
|
||||||
|
ULONG CheckSum;
|
||||||
|
PVOID Reserved6;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
ULONG TimeDateStamp;
|
||||||
|
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _RTL_USER_PROCESS_PARAMETERS {
|
||||||
|
BYTE Reserved1[16];
|
||||||
|
PVOID Reserved2[10];
|
||||||
|
UNICODE_STRING ImagePathName;
|
||||||
|
UNICODE_STRING CommandLine;
|
||||||
|
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
VOID
|
||||||
|
(NTAPI* PPS_POST_PROCESS_INIT_ROUTINE) (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PEB {
|
||||||
|
BYTE Reserved1[2];
|
||||||
|
BYTE BeingDebugged;
|
||||||
|
BYTE Reserved2[1];
|
||||||
|
PVOID Reserved3[2];
|
||||||
|
PPEB_LDR_DATA Ldr;
|
||||||
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
||||||
|
PVOID Reserved4[3];
|
||||||
|
PVOID AtlThunkSListPtr;
|
||||||
|
PVOID Reserved5;
|
||||||
|
ULONG Reserved6;
|
||||||
|
PVOID Reserved7;
|
||||||
|
ULONG Reserved8;
|
||||||
|
ULONG AtlThunkSListPtr32;
|
||||||
|
PVOID Reserved9[45];
|
||||||
|
BYTE Reserved10[96];
|
||||||
|
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
|
||||||
|
BYTE Reserved11[128];
|
||||||
|
PVOID Reserved12[1];
|
||||||
|
ULONG SessionId;
|
||||||
|
} PEB, * PPEB;
|
||||||
|
|
||||||
|
typedef struct __TEB {
|
||||||
|
PVOID Reserved1[12];
|
||||||
|
PPEB ProcessEnvironmentBlock;
|
||||||
|
PVOID Reserved2[399];
|
||||||
|
BYTE Reserved3[1952];
|
||||||
|
PVOID TlsSlots[64];
|
||||||
|
BYTE Reserved4[8];
|
||||||
|
PVOID Reserved5[26];
|
||||||
|
PVOID ReservedForOle;
|
||||||
|
PVOID Reserved6[4];
|
||||||
|
PVOID TlsExpansionSlots;
|
||||||
|
} TEB_, * PTEB_;
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#ifdef _M_X64
|
||||||
|
unsigned long long __readgsqword(unsigned long long offset);
|
||||||
|
#else
|
||||||
|
unsigned long __readfsdword(unsigned long offset);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _M_X64
|
||||||
|
#define GetTEB() ((PTEB_)__readgsqword(FIELD_OFFSET(NT_TIB, Self)))
|
||||||
|
#else
|
||||||
|
#define GetTEB() ((PTEB_)__readfsdword(FIELD_OFFSET(NT_TIB, Self)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define LAIKA
|
||||||
#define KEY 5
|
#define KEY 5
|
||||||
|
|
||||||
char* PCAESAR_DECRYPT(char* in);
|
char* PCAESAR_DECRYPT(char* in);
|
||||||
@@ -15,8 +127,10 @@ void free_(void* _Block);
|
|||||||
void* realloc_(void* _Block, size_t _Size);
|
void* realloc_(void* _Block, size_t _Size);
|
||||||
char* strdup_(char const* src);
|
char* strdup_(char const* src);
|
||||||
int strncmp__(char const* s1, char const* s2, int n);
|
int strncmp__(char const* s1, char const* s2, int n);
|
||||||
|
int strlen__(char const* src);
|
||||||
int strcmp__(char const* s1, char const* s2);
|
int strcmp__(char const* s1, char const* s2);
|
||||||
char* strstr__(char* str, char const* to_find);
|
char* strstr__(char* str, char const* to_find);
|
||||||
|
char* strcpy__(char* dest, char const* src);
|
||||||
long strtol_(const char* nptr, char** endptr, register int base);
|
long strtol_(const char* nptr, char** endptr, register int base);
|
||||||
char* strtok_(register char* s, register const char* delim);
|
char* strtok_(register char* s, register const char* delim);
|
||||||
void* memset__(void* a, int val, size_t size);
|
void* memset__(void* a, int val, size_t size);
|
||||||
|
|||||||
22
src/pasm.c
22
src/pasm.c
@@ -31,16 +31,13 @@ int dprintf(int stream, const char * format, ...) {
|
|||||||
HANDLE h;
|
HANDLE h;
|
||||||
|
|
||||||
if (pGetStdHandle == NULL) {
|
if (pGetStdHandle == NULL) {
|
||||||
char api[] = "LjyXyiMfsiqj";
|
pGetStdHandle = (fGetStdHandle)GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("LjyXyiMfsiqj"));
|
||||||
pGetStdHandle = (fGetStdHandle)GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
if (pwvsprintfA == NULL) {
|
if (pwvsprintfA == NULL) {
|
||||||
char api[] = "|{xuwnsykF";
|
pwvsprintfA = (fwvsprintfA)GetApi(L"USER32.dll", PCAESAR_DECRYPT("|{xuwnsykF"));
|
||||||
pwvsprintfA = (fwvsprintfA)GetApi(L"USER32.dll", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
if (pWriteFile == NULL) {
|
if (pWriteFile == NULL) {
|
||||||
char api[] = "\\wnyjKnqj";
|
pWriteFile = (fWriteFile)GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT("\\wnyjKnqj"));
|
||||||
pWriteFile = (fWriteFile)GetApi(L"KERNEL32.DLL", PCAESAR_DECRYPT(api));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (stream) {
|
switch (stream) {
|
||||||
@@ -64,7 +61,8 @@ int dprintf(int stream, const char * format, ...) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
OVERLAPPED ov = {0};
|
OVERLAPPED ov;
|
||||||
|
memset__(&ov, 0, sizeof(OVERLAPPED));
|
||||||
if (!pWriteFile(h, buffer, length, &written, &ov)) {
|
if (!pWriteFile(h, buffer, length, &written, &ov)) {
|
||||||
state->should_exit = 1; //broken socket -> host disconnected
|
state->should_exit = 1; //broken socket -> host disconnected
|
||||||
return -1;
|
return -1;
|
||||||
@@ -161,9 +159,9 @@ int pasm_run_script(const char *filename, char **file, size_t lines, int _fstrea
|
|||||||
free_(line);
|
free_(line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while (file[state->curr_line][strlen(line) - 1] == '\r' || file[state->curr_line][strlen(line) - 1] == '\n') {
|
while (file[state->curr_line][strlen__(line) - 1] == '\r' || file[state->curr_line][strlen__(line) - 1] == '\n') {
|
||||||
file[state->curr_line][strlen(line) - 1] = '\0';
|
file[state->curr_line][strlen__(line) - 1] = '\0';
|
||||||
line[strlen(line) - 1] = '\0';
|
line[strlen__(line) - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
const command_t *com = find_command(command_map, strtok_(line, " "));
|
const command_t *com = find_command(command_map, strtok_(line, " "));
|
||||||
@@ -180,7 +178,7 @@ int pasm_run_script(const char *filename, char **file, size_t lines, int _fstrea
|
|||||||
free_(line);
|
free_(line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (file[state->curr_line][strlen(line) - 1] != ':') {
|
if (file[state->curr_line][strlen__(line) - 1] != ':') {
|
||||||
show_error(state->curr_line, file[state->curr_line]);
|
show_error(state->curr_line, file[state->curr_line]);
|
||||||
dprintf(fstream, "%s \"%s\"\n", "unknown expression", strtok_(file[state->curr_line], " "));
|
dprintf(fstream, "%s \"%s\"\n", "unknown expression", strtok_(file[state->curr_line], " "));
|
||||||
set_exit_state(-1);
|
set_exit_state(-1);
|
||||||
@@ -204,7 +202,7 @@ int pasm_run_script(const char *filename, char **file, size_t lines, int _fstrea
|
|||||||
free_(line);
|
free_(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret_code = get_exit_state();
|
int ret_code = get_exit_code();
|
||||||
free__script(file);
|
free__script(file);
|
||||||
return ret_code;
|
return ret_code;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user