Skip to content

Commit

Permalink
merge dev for version v1.3.2
Browse files Browse the repository at this point in the history
  • Loading branch information
dderjoel committed Nov 15, 2022
1 parent a723364 commit cbf8feb
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 106 deletions.
10 changes: 10 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
version 1.3.2-release (2022-11-16)

- fixed bug which caused `asmline -{c,b} <NUM>` to not display the
correct chuks

- asmline {-h,--help} now emits to stdout to be conform with GNU standards
and with a slightly different indentation.

- provide bash and zsh auto completion helper for asmline cli-tool

version 1.3.1-release (2022-11-10)

- added support for all shift instructions shr/shl/sar/sal as well as all
Expand Down
13 changes: 12 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ include_HEADERS = src/assemblyline.h
# 3. Programs may need to be changed, recompiled, and relinked in order to use the new version. Bump current, set revision and age to 0.

# in short, if only patch from configure.ac is bumped, bump the middle number below. If more is changed, read the above
libassemblyline_la_LDFLAGS = -version-info 3:4:2
libassemblyline_la_LDFLAGS = -version-info 3:5:2
##############################################################################################
##############################################################################################
############################### BINS ##############################################
Expand All @@ -80,6 +80,17 @@ libassemblyline_la_LDFLAGS = -version-info 3:4:2
bin_PROGRAMS = tools/asmline
LDADD = libassemblyline.la

# completion --start--
if ENABLE_BASH_COMPLETION
bashcompletiondir = $(BASH_COMPLETION_DIR)
dist_bashcompletion_DATA = data/completion/asmline
endif
if ENABLE_ZSH_COMPLETION
zshcompletiondir = $(ZSH_COMPLETION_DIR)
dist_zshcompletion_DATA = data/completion/_asmline
endif
# completion --end--

##############################################################################################
##############################################################################################
############################### MANS ##############################################
Expand Down
39 changes: 38 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([assemblyline],[1.3.1],[[email protected]])
AC_INIT([assemblyline],[1.3.2],[[email protected]])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/assemblyline.c])
AC_CONFIG_AUX_DIR([build-aux])
Expand Down Expand Up @@ -34,6 +34,43 @@ AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T



# completion --start--
# bash
AC_ARG_WITH([bash-completion-dir],
AS_HELP_STRING([--with-bash-completion-dir[=PATH]],
[Install the bash auto-completion script in this directory. @<:@default=yes@:>@]),
[],
[with_bash_completion_dir=yes])

if test "x$with_bash_completion_dir" = "xyes"; then
PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
[BASH_COMPLETION_DIR="`pkg-config --variable=completionsdir bash-completion`"],
[BASH_COMPLETION_DIR="$datadir/bash-completion/completions"])
else
BASH_COMPLETION_DIR="$with_bash_completion_dir"
fi
AC_SUBST([BASH_COMPLETION_DIR])
AM_CONDITIONAL([ENABLE_BASH_COMPLETION],[test "x$with_bash_completion_dir" != "xno"])
# end bash
# start zsh
AC_ARG_WITH([zsh-completion-dir],
AS_HELP_STRING([--with-zsh-completion-dir[=PATH]],
[Install the zsh auto-completion script in this directory. @<:@default=yes@:>@]),
[],
[with_zsh_completion_dir=yes])

if test "x$with_zsh_completion_dir" = "xyes"; then
ZSH_COMPLETION_DIR="$datadir/zsh/site-functions"
else
ZSH_COMPLETION_DIR="$with_zsh_completion_dir"
fi
AC_SUBST([ZSH_COMPLETION_DIR])
AM_CONDITIONAL([ENABLE_ZSH_COMPLETION],[test "x$with_zsh_completion_dir" != "xno"])
# end zsh
# completion --end--

# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_MMAP
Expand Down
31 changes: 31 additions & 0 deletions data/completion/_asmline
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#compdef asmline

_arguments -S -s \
'(H --rand)--rand[runs the code and initializes memory with random data _rdi--r9 can be dereferenced_.]:random heap:' \
'(H -r --return)'{-r=-,--return=-}'[runs assembled code]:number of elements::resolution:(300 500)' \
'(H -p --print)'{-p,--print}'[print to stdout in ASCII-hex.]' \
'(H -P --printfile -o --object)'{-P+,--printfile+}'[write raw binary into FILE]' \
'(H -P --printfile -o --object)'{-o+,--object+}'[write raw binary machinecode to FILE.bin]' \
'(H -c --chunk)'{-c+,--chunk+}'[set (write) chunk size. Will NOP-pad every chunk]' \
'(H -b --breaks)'{-b+,--breaks+}'[set (read) chunk size. Counts how many chunks break a boundary.]' \
+ '(mov)' \
"(H)--nasm-mov-imm[nasm mov imm: mov to 32-bit reg if possible.]" \
"(H)--smart-mov-imm[smart mov imm: if 64-bit padded, mov to 64-bit reg, to 32-bit otherwise.]" \
"(H)--strict-mov-imm[strict mov imm: always mov to 64-bit reg.]" \
+ '(sib_index)' \
"(H)--nasm-sib-index-base-swap[nasm swap sib; 'lea r15, \[rax+rsp\]' -> 'lea r15, \[rsp+rax\]']" \
"(H)--strict-sib-index-base-swap[no swap sib; 'lea r15, \[rax+rsp\]' as is.]" \
+ '(sib_nobase)' \
"(H)--nasm-sib-no-base[nasm scale sib; 'lea r15, \[2*rax\]' -> 'lea r15, \[rax+1*rax\]']" \
"(H)--strict-sib-no-base[no scale sib; 'lea r15, \[2*rax\]' as is.]" \
+ '(sib_total)' \
"(H sib_index sib_nobase)--nasm-sib[implies --nasm-sib-{no-base,index-base-swap}]" \
"(H sib_index sib_nobase)--strict-sib[implies --strict-sib-{no-base,index-base-swap}]" \
+ '(mode_total)' \
"(H sib_total mov)"{--nasm,-n}'[implies --nasm-{mov-imm,sib-{no-base,index-base-swap}}]' \
"(H sib_total mov)"{--strict,-t}'[implies --strict-{mov-imm,-{no-base,index-base-swap}}]' \
+ '(H)' \
'(* - input)'{-v,--version}'[Prints version information to stdout and exits.]' \
'(* - input)'{-h,--help}'[Prints usage information to stdout and exits.]' \
+ '(input)' \
':assembly file:_files -g \*.\(asm\|s\|S\)' && ret=0
40 changes: 40 additions & 0 deletions data/completion/asmline
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
_asmline() {

local current="${COMP_WORDS[COMP_CWORD]}"
local options="
--breaks
--chunk
--help
--nasm
--nasm-mov-imm
--nasm-sib
--nasm-sib-index-base-swap
--nasm-sib-no-base
--object
--print
--printfile
--rand
--return
--smart-mov-imm
--strict
--strict-mov-imm
--strict-sib
--strict-sib-index-base-swap
--strict-sib-no-base
--version
-P
-b
-c
-h
-n
-o
-p
-r
-t
-v
"
mapfile -t COMPREPLY < <(compgen -W "${options}" -- "${current}")
}

complete -F _asmline asmline
9 changes: 9 additions & 0 deletions test/tools/asmline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,12 @@ mov [rdi + 0x00], rax
mov [rdi + 0x50], rax
ret
EOF

ret=$(
${tool} -b 3 <<EOF
mov rax, 0xDEADBEEF
mov [rdi + 0x50], rax
ret
EOF
)
test "${ret}" -eq 2
192 changes: 88 additions & 104 deletions tools/asmline.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,109 +67,89 @@ struct parsed_ops {
static void parse_opt(assemblyline_t al, int argc, char **argv,
struct parsed_ops *r);

static void print_usage() {
printf("Usage: asmline [OPTIONS]... FILE\n");
printf("\
Assembles FILE into memory.\n\
-r[=LEN], --return[=LEN] Assembles FILE. Then executes it with six \n\
parameters to heap-allocated memory. Each \n\
pointer points to an array of LEN 64-bit \n\
elements which can be dereferenced in the asm-\n\
code, where LEN defaults to 10.\n\
After execution, it prints out the contents of\n\
the return (rax) register and frees the heap-\n\
memory.\n\
--rand Implies -r and will additionally initialize the \n\
memory from with random data. -r=11 can be used\n\
to alter LEN.\n\
-p, --print The corresponding machine code will be printed to\n\
stdout in hex form. Output is similar to \n\
`objdump`: Byte-wise delimited by space and \n\
linebreaks after 7 bytes. If -c is given, the\n\
chunks are delimited by '|' and each chunk is \n\
on one line.\n\
-P, --printfile FILENAME The corresponding machine code will be printed to\n\
FILENAME in binary form. Can be set to \n\
'/dev/stdout' to write to stdout.\n\
-o, --object FILENAME The corresponding machine code will be printed to\n\
FILENAME.bin in binary.\n\
-c, --chunk CHUNK_SIZE Sets a given CHUNK_SIZE>1 boundary in bytes. Nop \n\
padding will be used to ensure no instruction \n\
opcode will cross the specified CHUNK_SIZE \n\
boundary.\n\
-b, --breaks CHUNK_BOUNDARY Given a CHUNK_BOUNDARY>1, counts the number of \n\
instructions where their opcode crosses the \n\
specified CHUNK_BOUNDARY size in bytes.\n\
--nasm-mov-imm Enables nasm-style mov-immediate register-size\n\
handling. ex: if immediate size for mov is les\n\
than or equal to max signed 32 bit assemblyline\n\
will emit code to mov to the 32-bit register \n\
rather than 64-bit. That is: \n\
\"mov rax,0x7fffffff\" as \"mov eax,0x7fffffff\"\n\
-> b8 ff ff ff 7f note: rax got optimized to \n\
eax for faster immediate to register transfer\n\
and produces a shorter instruction\n\
--strict-mov-imm Disables nasm-style mov-immediate register-size\n\
handling. ex: even if immediate size for mov \n\
is less than or equal to max signed 32 bit \n\
assemblyline. Will pad the immediate to fit \n\
64-bit. That is: \"mov rax,0x7fffffff\" as\n\
\"mov rax,0x000000007fffffff\" ->\n\
48 b8 ff ff ff 7f 00 00 00 00\n\
--smart-mov-imm The immediate value will be checked for leading \n\
0's. Immediate must be zero padded to 64-bits\n\
exactly to ensure it will not optimize. This is\n\
currently set as default. ex: \n\
\"mov rax, 0x000000007fffffff\" -> \n\
48 b8 ff ff ff 7f 00 00 00 00\n\
--nasm-sib-index-base-swap In SIB addressing if the index register is esp or\n\
rsp then the base and index registers will be \n\
swapped. That is: \"lea r15, [rax+rsp]\" ->\n\
\"lea r15, [rsp+rax]\"\n\
--strict-sib-index-base-swap In SIB addressing the base and index registers \n\
will not be swapped even if the index register\n\
is esp or rsp.\n\
--nasm-sib-no-base In SIB addressing if there is no base register \n\
present and scale is equal to 2; the base \n\
register will be set to the index register and\n\
the scale will be reduced to 1. That is: \n\
\"lea r15, [2*rax]\" -> \"lea r15, [rax+1*rax]\"\n\
--strict-sib-no-base In SIB addressing when there is no base register\n\
present the index and scale would not change \n\
regardless of scale value. That is: \n\
\"lea r15, [2*rax]\" -> \"lea r15, [2*rax]\" \n\
--nasm-sib Is equivalent to --nasm-sib-index-base-swap \n\
--nasm-sib-no-base \n\
--strict-sib Is equivalent to --strict-sib-index-base-swap \n\
--strict-sib-no-base \n\
-n, --nasm Is equivalent to --nasm-mov-imm --nasm-sib \n\
-t, --strict Is equivalent to --strict-mov-imm --strict-sib \n\
-h, --help Prints usage information to stdout and exits. \n\
-v, --version Prints version information to stdout and exits.\n");
}
static void err_print_usage(char *error_msg) {
fprintf(
stderr,
"%s\nUsage: asmline "
"[OPTIONS]... path/to/file.asm\n\n"

" -r[=LEN], --return[=LEN]\n"
"\tAssembles given code. Then executes it with six parameters to "
"heap-allocated memory.\n\tEach pointer points to an array of LEN 64-bit "
"elements which can be dereferenced \n\tin the asm-code, where LEN "
"defaults "
"to 10.\n\tAfter execution, it prints out the contents of the return "
"(rax) register and frees \n\tthe heap-memory.\n\n"

" --rand \n"
"\tImplies -r and will additionally initialize the memory from with "
"random data. \n\t-r=11 can be used to alter LEN.\n\n"

" -p, --print\n"
"\tThe corresponding machine code will be printed to stdout in hex "
"form.\n"
"\tOutput is similar to `objdump`: Byte-wise delimited by space and "
"linebreaks after 7 bytes.\n\tIf -c is given, the chunks are "
"delimited by '|' and each chunk is on one line.\n\n"

" -P, --printfile FILENAME\n"
"\tThe corresponding machine code will be printed to FILENAME in binary "
"form.\n\tCan be set to '/dev/stdout' to write to stdout.\n\n"

" -o, --object FILENAME\n"
"\tThe corresponding machine code will be printed to FILENAME.bin in "
"binary.\n\n"

" -c, --chunk CHUNK_SIZE>1\n"
"\tSets a given CHUNK_SIZE boundary in bytes. Nop padding will be used "
"to ensure no instruction\n"
"\topcode will cross the specified CHUNK_SIZE boundary.\n\n"

" -b, --breaks CHUNK_BOUNDARY>1\n"
"\tGiven a CHUNK_BOUNDARY, counts the number of instructions where\n"
"\ttheir opcode crosses the specified CHUNK_BOUNDARY size in bytes.\n\n"

" --nasm-mov-imm\n"
"\tEnables nasm-style mov-immediate register-size handling.\n"
"\tex: if immediate size for mov is less than or equal to max "
"signed 32 bit assemblyline\n"
"\t will emit code to mov to the 32-bit register rather than 64-bit.\n"
"\tThat is: \"mov rax,0x7fffffff\" as \"mov eax,0x7fffffff\" "
"-> b8 ff ff ff 7f\n"
"\tnote: rax got optimized to eax for faster immediate to register "
"transfer\n"
"\t and produces a shorter instruction\n\n"

" --strict-mov-imm\n"
"\tDisables nasm-style mov-immediate register-size handling.\n"
"\tex: even if immediate size for mov is less than or equal to max "
"signed 32 bit assemblyline.\n"
"\t will pad the immediate to fit 64-bit\n"
"\tThat is: \"mov rax,0x7fffffff\" as \"mov rax,0x000000007fffffff\"\n"
"\t -> 48 b8 ff ff ff 7f 00 00 00 00\n\n"

" --smart-mov-imm\n"
"\tThe immediate value will be checked for leading 0's.\n"
"\tImmediate must be zero padded to 64-bits exactly to ensure\n"
"\tit will not optimize. This is currently set as default.\n"
"\tex: \"mov rax, 0x000000007fffffff\" -> 48 b8 ff ff ff 7f 00 00 00 "
"00\n\n"

" --nasm-sib-index-base-swap\n"
"\tIn SIB addressing if the index register is esp or rsp then\n"
"\tthe base and index registers will be swapped.\n"
"\tThat is: \"lea r15, [rax+rsp]\" -> \"lea r15, [rsp+rax]\"\n\n"
" --strict-sib-index-base-swap\n"
"\tIn SIB addressing the base and index registers will not be swapped\n"
"\teven if the index register is esp or rsp.\n\n"

" --nasm-sib-no-base\n"
"\tIn SIB addressing if there is no base register present and scale\n"
"\tis equal to 2; the base register will be set to the index register\n"
"\tand the scale will be reduced to 1.\n"
"\tThat is: \"lea r15, [2*rax]\" -> \"lea r15, [rax+1*rax]\"\n\n"
" --strict-sib-no-base\n"
"\tIn SIB addressing when there is no base register present the index\n"
"\tand scale would not change regardless of scale value.\n"
"\tThat is: \"lea r15, [2*rax]\" -> \"lea r15, [2*rax]\"\n\n"

" --nasm-sib\n"
"\tequivalent to --nasm-sib-index-base-swap --nasm-sib-no-base\n\n"
" --strict-sib\n"
"\tequivalent to --strict-sib-index-base-swap --strict-sib-no-base\n\n"

" -n, --nasm\n"
"\tequivalent to --nasm-mov-imm --nasm-sib\n\n"

" -t, --strict\n"
"\tequivalent to --strict-mov-imm --strict-sib\n\n"

" -h, --help\n"
"\tPrints usage information to stdout and exits.\n\n"

" -v, --version\n"
"\tPrints version information to stdout and exits.\n\n",
error_msg);
fprintf(stderr, "%s", error_msg);
print_usage();
exit(EXIT_FAILURE);
}

Expand Down Expand Up @@ -405,6 +385,10 @@ int main(int argc, char *argv[]) {
char *line = NULL;
int chunk_brks = 0;
size_t size = BUFFER_SIZE;
// init total count
if (m.count)
total_chunk_brks = 0;

while (getline(&line, &size, stdin) != -1) {

int ret = m.count ? asm_assemble_string_counting_chunks(
Expand Down Expand Up @@ -513,13 +497,13 @@ static void parse_opt(assemblyline_t al, int argc, char **argv,
asm_set_all(al, SMART);
break;
case 'c':
if (optarg == NULL || (temp = atoi(optarg) <= 1))
if (optarg == NULL || (temp = atoi(optarg)) <= 1)
err_print_usage("Error: [-c CHUNK_SIZE>1] expects an integer\n");
asm_set_chunk_size(al, temp);
break;

case 'b':
if (optarg == NULL || (temp = atoi(optarg) <= 1))
if (optarg == NULL || (temp = atoi(optarg)) <= 1)
err_print_usage("Error: [-b CHUNK_BOUNDARY>1] expects an integer\n");
r->chunk_boundary = temp;
break;
Expand Down

0 comments on commit cbf8feb

Please sign in to comment.