rename minimize to minify + prepare lxsh commands + add reserved variables

This commit is contained in:
zawz 2021-03-20 11:09:02 +01:00
parent 75972d166b
commit 13c0d79bad
23 changed files with 165 additions and 112 deletions

3
.gitignore vendored
View file

@ -7,4 +7,5 @@
/gmon.out /gmon.out
/profiling/* /profiling/*
/profiling.* /profiling.*
/include/g_*.h /include/g_*
/src/g_*

View file

@ -59,6 +59,9 @@ $(ODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
$(ODIR)/main.o: $(SRCDIR)/main.cpp $(DEPS) $(IDIR)/g_version.h $(ODIR)/main.o: $(SRCDIR)/main.cpp $(DEPS) $(IDIR)/g_version.h
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/shellcode.o: $(SRCDIR)/shellcode.cpp $(DEPS) $(IDIR)/g_shellcode.h
$(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/debashify.o: $(SRCDIR)/debashify.cpp $(DEPS) $(IDIR)/g_shellcode.h $(ODIR)/debashify.o: $(SRCDIR)/debashify.cpp $(DEPS) $(IDIR)/g_shellcode.h
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<

View file

@ -1,6 +1,6 @@
# lxsh # lxsh
Extended shell linker for linking, processing and minimizing shell code Extended shell linker for linking, processing and minifying shell code
# Installing # Installing
@ -31,9 +31,9 @@ See [Build](#build).
# Features # Features
## Command extensions ## Linking
lxsh implements special linking commands that are resolved at linking. lxsh implements special linking commands that are resolved at build time.
These commands can be placed anywhere within the script like regular commands. These commands can be placed anywhere within the script like regular commands.
- `%include` : allows to insert file contents - `%include` : allows to insert file contents
@ -41,20 +41,20 @@ These commands can be placed anywhere within the script like regular commands.
> See `lxsh --help-commands` for more details > See `lxsh --help-commands` for more details
## Minimize code ## Minify code
Reduce code size to a minimum without changing functionality with the `-m` option. Reduce code size to a minimum without changing functionality with the `-m` option.
### Further minimizing ### Further minifying
The script can be further minimized by altering code elements. The script can be further minified by altering code elements.
This can cause some change in execution behavior if you are not careful. This can cause some change in execution behavior if you are not careful.
Variable names can be minimized with `--minimize-var`, Variable names can be minified with `--minify-var`,
use `--exclude-var` to exclude variables from being minimized (for example environment config). use `--exclude-var` to exclude variables from being minified (for example environment config).
Function names can be minimized with `--minimize-fct`, Function names can be minified with `--minify-fct`,
use `--exclude-fct` to exclude functions from being minimized. use `--exclude-fct` to exclude functions from being minified.
Unused functions and variables can be removed with `--remove-unused`. Unused functions and variables can be removed with `--remove-unused`.

View file

@ -5,7 +5,7 @@ tmpfile=${TMPDIR-/tmp}/lxsh_shellcodegen
codedir=shellcode codedir=shellcode
# $1 = file # $1 = file
minimize() { minify() {
if which lxsh >/dev/null 2>&1 ; then if which lxsh >/dev/null 2>&1 ; then
lxsh -m "$1" lxsh -m "$1"
elif which shfmt >/dev/null 2>&1 ; then elif which shfmt >/dev/null 2>&1 ; then
@ -19,12 +19,21 @@ to_cstr() {
sed 's|\\|\\\\|g;s|\"|\\\"|g' | sed ':a;N;$!ba;s/\n/\\n/g;' sed 's|\\|\\\\|g;s|\"|\\\"|g' | sed ':a;N;$!ba;s/\n/\\n/g;'
} }
echo '#ifndef G_VERSION_H' > "$tmpfile"
echo '#define G_VERSION_H' >> "$tmpfile" cat > "$tmpfile" << EOF
#ifndef G_VERSION_H
#define G_VERSION_H
EOF
unset all_fields
for I in "$codedir"/*.sh for I in "$codedir"/*.sh
do do
printf '#define %s "%s\\n"\n' "$(basename "$I" | tr [:lower:] [:upper:] | tr '.' '_')" "$(minimize "$I" | to_cstr)" >> "$tmpfile" field=$(basename "$I" | tr [:lower:] [:upper:] | tr '.' '_')
all_fields="$all_fields $field"
printf '#define %s "%s\\n"\n' "$field" "$(minify "$I" | to_cstr)" >> "$tmpfile"
done done
echo "#endif" >> "$tmpfile" echo "#endif" >> "$tmpfile"
if [ "$(md5sum "$tmpfile" | cut -d' ' -f1)" != "$(md5sum "$file" | cut -d' ' -f1)" ] ; then if [ "$(md5sum "$tmpfile" | cut -d' ' -f1)" != "$(md5sum "$file" | cut -d' ' -f1)" ] ; then

View file

@ -1,18 +1,18 @@
#ifndef MINIMIZE_HPP #ifndef MINIFY_HPP
#define MINIMIZE_HPP #define MINIFY_HPP
#include "struc.hpp" #include "struc.hpp"
#include <regex> #include <regex>
#include <string> #include <string>
void minimize_var(_obj* in, std::regex const& exclude); void minify_var(_obj* in, std::regex const& exclude);
void minimize_fct(_obj* in, std::regex const& exclude); void minify_fct(_obj* in, std::regex const& exclude);
bool delete_unused_fct(_obj* in, std::regex const& exclude); bool delete_unused_fct(_obj* in, std::regex const& exclude);
bool delete_unused_var(_obj* in, std::regex const& exclude); bool delete_unused_var(_obj* in, std::regex const& exclude);
void delete_unused(_obj* in, std::regex const& var_exclude, std::regex const& fct_exclude); void delete_unused(_obj* in, std::regex const& var_exclude, std::regex const& fct_exclude);
void minimize_quotes(_obj* in); void minify_quotes(_obj* in);
#endif //MINIMIZE_HPP #endif //MINIFY_HPP

View file

@ -5,12 +5,14 @@
extern ztd::option_set options; extern ztd::option_set options;
extern bool opt_minimize; extern bool opt_minify;
extern bool g_cd; extern bool g_cd;
extern bool g_include; extern bool g_include;
extern bool g_resolve; extern bool g_resolve;
extern bool g_shebang; extern bool g_shebang;
void print_lxsh_cmd_help();
void get_opts(); void get_opts();
ztd::option_set gen_options(); ztd::option_set gen_options();

View file

@ -9,7 +9,7 @@
#include "struc.hpp" #include "struc.hpp"
// constants // constants
#define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG" #define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG", "LC_.*", "LANG", "TERM", "RANDOM"
// types // types
typedef std::map<std::string,uint32_t> countmap_t; typedef std::map<std::string,uint32_t> countmap_t;

15
include/shellcode.hpp Normal file
View file

@ -0,0 +1,15 @@
#ifndef SHELLCODE_HPP
#define SHELLCODE_HPP
#include <map>
#include <string>
struct lxsh_fct {
std::string arguments;
std::string description;
const char* code;
};
extern const std::map<const std::string, const struct lxsh_fct> lxsh_shellcode_fcts;
#endif //SHELLCODE_HPP

View file

@ -1,4 +1,4 @@
__lxsh_array_create() { _lxsh_array_create() {
printf "%s" "$1" printf "%s" "$1"
shift 1 shift 1
for N ; do for N ; do

View file

@ -1,4 +1,4 @@
__lxsh_array_get() { _lxsh_array_get() {
if [ "$2" = "*" ] || [ "$2" = "@" ] ; then if [ "$2" = "*" ] || [ "$2" = "@" ] ; then
printf "%s" "$1" | tr '\t' ' ' printf "%s" "$1" | tr '\t' ' '
else else

View file

@ -1,4 +1,4 @@
__lxsh_array_set() _lxsh_array_set()
{ {
[ "$2" -gt 0 ] && printf "%s\t" "$(printf "%s" "$1" | cut -f1-$2)" [ "$2" -gt 0 ] && printf "%s\t" "$(printf "%s" "$1" | cut -f1-$2)"
printf "%s" "$3" printf "%s" "$3"

View file

@ -1,4 +1,4 @@
__lxsh_map_create() { _lxsh_map_create() {
for I for I
do do
printf "%s]%s\n" "$(echo "$I" | cut -d']' -f1 | cut -d '[' -f2)" "$(echo "$I" | cut -d '=' -f2-)" printf "%s]%s\n" "$(echo "$I" | cut -d']' -f1 | cut -d '[' -f2)" "$(echo "$I" | cut -d '=' -f2-)"

View file

@ -1,4 +1,4 @@
__lxsh_map_get() { _lxsh_map_get() {
if [ "$2" = \* ] || [ "$2" = @ ] ; then if [ "$2" = \* ] || [ "$2" = @ ] ; then
printf "%s" "$(printf "%s" "$1" | sort | cut -d ']' -f2-)" | tr '\n' ' ' printf "%s" "$(printf "%s" "$1" | sort | cut -d ']' -f2-)" | tr '\n' ' '
else else

View file

@ -1,4 +1,4 @@
__lxsh_map_set() { _lxsh_map_set() {
printf "%s\n" "$1" | grep -v "^$2\]" printf "%s\n" "$1" | grep -v "^$2\]"
if [ -n "$3" ] ; then if [ -n "$3" ] ; then
printf "%s]%s\n" "$2" "$3" printf "%s]%s\n" "$2" "$3"

View file

@ -1,3 +1,3 @@
__lxsh_random_string() { _lxsh_random_string() {
env LC_CTYPE=C tr -dc 'a-zA-Z0-9' </dev/urandom | head -c "${1-20}" env LC_CTYPE=C tr -dc 'a-zA-Z0-9' </dev/urandom | head -c "${1-20}"
} }

View file

@ -1,3 +1,3 @@
__lxsh_random_tmpfile() { _lxsh_random_tmpfile() {
echo "${TMPDIR-/tmp}/$1$(__lxsh_random_string 20)" echo "${TMPDIR-/tmp}/$1$(_lxsh_random_string $2)"
} }

View file

@ -340,12 +340,12 @@ subshell_arithmetic* do_debashify_arithmetic(arithmetic* in, debashify_params* p
cmd* c; cmd* c;
if(params->arrays[varname]) if(params->arrays[varname])
{ {
c = make_cmd_varindex("__lxsh_map_get", varname, index); c = make_cmd_varindex("_lxsh_map_get", varname, index);
params->need_map_get=true; params->need_map_get=true;
} }
else else
{ {
c = make_cmd_varindex("__lxsh_array_get", varname, index); c = make_cmd_varindex("_lxsh_array_get", varname, index);
params->need_array_get=true; params->need_array_get=true;
} }
@ -429,12 +429,12 @@ bool debashify_array_get(arg* in, debashify_params* params)
cmd* c; cmd* c;
if(params->arrays[varname]) if(params->arrays[varname])
{ {
c = make_cmd_varindex("__lxsh_map_get", varname, index); c = make_cmd_varindex("_lxsh_map_get", varname, index);
params->need_map_get=true; params->need_map_get=true;
} }
else else
{ {
c = make_cmd_varindex("__lxsh_array_get", varname, index); c = make_cmd_varindex("_lxsh_array_get", varname, index);
params->need_array_get=true; params->need_array_get=true;
} }
@ -465,15 +465,15 @@ bool debashify_array_set(cmd* in, debashify_params* params)
// create cmd out of arguments // create cmd out of arguments
arglist* args = parse_arglist( gen.c_str(), gen.size(), 0 ).first; arglist* args = parse_arglist( gen.c_str(), gen.size(), 0 ).first;
cmd* c = new cmd(args); cmd* c = new cmd(args);
// cmd first argument is __lxsh_X_create // cmd first argument is _lxsh_X_create
if(params->arrays[varname]) if(params->arrays[varname])
{ {
c->args->insert(0, new arg("__lxsh_map_create") ); c->args->insert(0, new arg("_lxsh_map_create") );
params->need_map_create=true; params->need_map_create=true;
} }
else else
{ {
c->args->insert(0, new arg("__lxsh_array_create") ); c->args->insert(0, new arg("_lxsh_array_create") );
params->need_array_create=true; params->need_array_create=true;
} }
subshell_subarg* sb = new subshell_subarg(new subshell(c)); subshell_subarg* sb = new subshell_subarg(new subshell(c));
@ -506,12 +506,12 @@ bool debashify_array_set(cmd* in, debashify_params* params)
cmd* c; cmd* c;
if(params->arrays[varname]) if(params->arrays[varname])
{ {
c = make_cmd_varindex("__lxsh_map_get", varname, copy(index)); c = make_cmd_varindex("_lxsh_map_get", varname, copy(index));
params->need_map_get=true; params->need_map_get=true;
} }
else else
{ {
c = make_cmd_varindex("__lxsh_array_get", varname, copy(index)); c = make_cmd_varindex("_lxsh_array_get", varname, copy(index));
params->need_array_get=true; params->need_array_get=true;
} }
subshell_subarg* sb = new subshell_subarg(new subshell(c)); subshell_subarg* sb = new subshell_subarg(new subshell(c));
@ -527,21 +527,21 @@ bool debashify_array_set(cmd* in, debashify_params* params)
cmd* c = new cmd(new arglist); cmd* c = new cmd(new arglist);
if(params->arrays[varname]) if(params->arrays[varname])
{ {
c->args->add(new arg("__lxsh_map_set") ); c->args->add(new arg("_lxsh_map_set") );
params->need_map_set=true; params->need_map_set=true;
} }
else else
{ {
c->args->add(new arg("__lxsh_array_set") ); c->args->add(new arg("_lxsh_array_set") );
params->need_array_set=true; params->need_array_set=true;
} }
// __lxsh_array_set "$VAR" // _lxsh_array_set "$VAR"
c->args->add( make_arg("\"$"+varname+"\"") ); c->args->add( make_arg("\"$"+varname+"\"") );
// __lxsh_array_set "$VAR" N // _lxsh_array_set "$VAR" N
c->args->add( index ); c->args->add( index );
// __lxsh_array_set "$VAR" N value // _lxsh_array_set "$VAR" N value
c->args->add( value ); c->args->add( value );
// $(__lxsh_array_set "$VAR" N value) // $(_lxsh_array_set "$VAR" N value)
subshell_subarg* sb = new subshell_subarg(new subshell(c)); subshell_subarg* sb = new subshell_subarg(new subshell(c));
it->second = new arg("="); it->second = new arg("=");
@ -563,14 +563,14 @@ bool debashify_array_set(cmd* in, debashify_params* params)
// create cmd out of arguments // create cmd out of arguments
arglist* args = parse_arglist( gen.c_str(), gen.size(), 0 ).first; arglist* args = parse_arglist( gen.c_str(), gen.size(), 0 ).first;
cmd* c = new cmd(args); cmd* c = new cmd(args);
// cmd first argument is __lxsh_array_create // cmd first argument is _lxsh_array_create
if(params->arrays[varname]) if(params->arrays[varname])
{ {
throw std::runtime_error("Cannot debashify VAR+=() on associative arrays"); throw std::runtime_error("Cannot debashify VAR+=() on associative arrays");
} }
else else
{ {
c->args->insert(0, new arg("__lxsh_array_create") ); c->args->insert(0, new arg("_lxsh_array_create") );
params->need_array_create=true; params->need_array_create=true;
} }
// second arg is varname // second arg is varname
@ -667,7 +667,7 @@ bool debashify_combined_redirects(block* in)
// replace <() and >() // replace <() and >()
/* /*
REPLACE TO: REPLACE TO:
fifoN=${TMPDIR-/tmp}/lxshfifo_$(__lxsh_random_string 10) fifoN=${TMPDIR-/tmp}/lxshfifo_$(_lxsh_random_string 10)
mkfifo "$fifoN" mkfifo "$fifoN"
( {PSUB;} [>|<] "$fifoN" ; rm "$fifoN") & ( {PSUB;} [>|<] "$fifoN" ; rm "$fifoN") &
CMD "$fifoN" CMD "$fifoN"
@ -709,9 +709,9 @@ bool debashify_procsub(list* lst, debashify_params* params)
std::string mkfifocmd="mkfifo"; std::string mkfifocmd="mkfifo";
for(uint32_t i=0; i<affected_args.size(); i++) for(uint32_t i=0; i<affected_args.size(); i++)
{ {
// fifoN=${TMPDIR-/tmp}/lxshfifo_$(__lxsh_random_string 10) // fifoN=${TMPDIR-/tmp}/lxshfifo_$(_lxsh_random_string 10)
lst_insert->add( make_condlist( strf("__lxshfifo%u=$(__lxsh_random_tmpfile lxshfifo)", i) ) ); lst_insert->add( make_condlist( strf("_lxshfifo%u=$(_lxsh_random_tmpfile lxshfifo)", i) ) );
mkfifocmd += strf(" \"$__lxshfifo%u\"", i); mkfifocmd += strf(" \"$_lxshfifo%u\"", i);
} }
// mkfifo "$fifoN" // mkfifo "$fifoN"
lst_insert->add( make_condlist(mkfifocmd) ); lst_insert->add( make_condlist(mkfifocmd) );
@ -724,13 +724,13 @@ bool debashify_procsub(list* lst, debashify_params* params)
brace* cbr = new brace(st->sbsh->lst); brace* cbr = new brace(st->sbsh->lst);
// deindex list for delete // deindex list for delete
st->sbsh->lst=nullptr; st->sbsh->lst=nullptr;
// {PSUB;} > "$__lxshfifoN" // {PSUB;} > "$_lxshfifoN"
cbr->redirs.push_back( new redirect( affected_args[i].second ? "<" : ">", make_arg(strf("\"$__lxshfifo%u\"", i)) ) ); cbr->redirs.push_back( new redirect( affected_args[i].second ? "<" : ">", make_arg(strf("\"$_lxshfifo%u\"", i)) ) );
// ( {PSUB;} > "$__lxshfifoN" ) // ( {PSUB;} > "$_lxshfifoN" )
psub->lst->add( new condlist(cbr) ); psub->lst->add( new condlist(cbr) );
// ( {PSUB;} > "$__lxshfifoN" ; rm "$__lxshfifoN" ) // ( {PSUB;} > "$_lxshfifoN" ; rm "$_lxshfifoN" )
psub->lst->add( make_condlist(strf("rm \"$__lxshfifo%u\"", i)) ); psub->lst->add( make_condlist(strf("rm \"$_lxshfifo%u\"", i)) );
// ( {PSUB;} > "$__lxshfifoN" ; rm "$__lxshfifoN" ) & // ( {PSUB;} > "$_lxshfifoN" ; rm "$_lxshfifoN" ) &
condlist* pscl = new condlist(psub); condlist* pscl = new condlist(psub);
pscl->parallel=true; pscl->parallel=true;
lst_insert->add( pscl ); lst_insert->add( pscl );
@ -738,7 +738,7 @@ bool debashify_procsub(list* lst, debashify_params* params)
// replace the arg // replace the arg
delete affected_args[i].first->sa[0]; delete affected_args[i].first->sa[0];
affected_args[i].first->sa[0] = new string_subarg("\""); affected_args[i].first->sa[0] = new string_subarg("\"");
affected_args[i].first->add( new variable_subarg( new variable(strf("__lxshfifo%u", i)) ) ); affected_args[i].first->add( new variable_subarg( new variable(strf("_lxshfifo%u", i)) ) );
affected_args[i].first->add( new string_subarg("\"") ); affected_args[i].first->add( new string_subarg("\"") );
} }
lst->insert(li, *lst_insert ); lst->insert(li, *lst_insert );

View file

@ -13,7 +13,7 @@ bool is_sub_special_cmd(std::string in)
std::string indented(std::string const& in, uint32_t ind) std::string indented(std::string const& in, uint32_t ind)
{ {
if(!opt_minimize) if(!opt_minify)
return indent(ind) + in; return indent(ind) + in;
else else
return in; return in;
@ -56,7 +56,7 @@ std::string pipeline::generate(int ind)
ret += cmds[0]->generate(ind); ret += cmds[0]->generate(ind);
for(uint32_t i=1 ; i<cmds.size() ; i++) for(uint32_t i=1 ; i<cmds.size() ; i++)
{ {
ret += opt_minimize ? "|" : " | " ; ret += opt_minify ? "|" : " | " ;
ret += cmds[i]->generate(ind); ret += cmds[i]->generate(ind);
} }
@ -72,16 +72,16 @@ std::string condlist::generate(int ind)
for(uint32_t i=0 ; i<pls.size()-1 ; i++) for(uint32_t i=0 ; i<pls.size()-1 ; i++)
{ {
if(or_ops[i]) if(or_ops[i])
ret += opt_minimize ? "||" : " || "; ret += opt_minify ? "||" : " || ";
else else
ret += opt_minimize ? "&&" : " && "; ret += opt_minify ? "&&" : " && ";
ret += pls[i+1]->generate(ind); ret += pls[i+1]->generate(ind);
} }
if(ret=="") if(ret=="")
return ""; return "";
if(parallel) if(parallel)
{ {
ret += opt_minimize ? "&" : " &\n"; ret += opt_minify ? "&" : " &\n";
} }
else else
ret += '\n'; ret += '\n';
@ -114,7 +114,7 @@ std::string redirect::generate(int ind)
std::string ret=op; std::string ret=op;
if(target!=nullptr) if(target!=nullptr)
{ {
if(!opt_minimize) if(!opt_minify)
ret += ' '; ret += ' ';
ret += target->generate(0); ret += target->generate(0);
} }
@ -130,7 +130,7 @@ std::string block::generate_redirs(int ind, std::string const& _str)
for(auto it: redirs) for(auto it: redirs)
{ {
std::string _r = it->generate(0); std::string _r = it->generate(0);
if(opt_minimize && _r.size() > 0 && !is_num(_r[0]) && previous_isnt_num) if(opt_minify && _r.size() > 0 && !is_num(_r[0]) && previous_isnt_num)
ret.pop_back(); // remove one space if possible ret.pop_back(); // remove one space if possible
ret += _r + ' '; ret += _r + ' ';
previous_isnt_num = ret.size()>1 && !is_num(ret[ret.size()-2]); previous_isnt_num = ret.size()>1 && !is_num(ret[ret.size()-2]);
@ -185,7 +185,7 @@ std::string for_block::generate(int ind)
ret += ops->generate(ind+1); ret += ops->generate(ind+1);
ret += indented("done", ind); ret += indented("done", ind);
if(opt_minimize && ret.size()>1 && !is_alpha(ret[ret.size()-2])) if(opt_minify && ret.size()>1 && !is_alpha(ret[ret.size()-2]))
ret.pop_back(); ret.pop_back();
ret += generate_redirs(ind, ret); ret += generate_redirs(ind, ret);
return ret; return ret;
@ -205,7 +205,7 @@ std::string while_block::generate(int ind)
ret += ops->generate(ind+1); ret += ops->generate(ind+1);
ret += indented("done", ind); ret += indented("done", ind);
if(opt_minimize && ret.size()>1 && !is_alpha(ret[ret.size()-2])) if(opt_minify && ret.size()>1 && !is_alpha(ret[ret.size()-2]))
ret.pop_back(); ret.pop_back();
ret += generate_redirs(ind, ret); ret += generate_redirs(ind, ret);
return ret; return ret;
@ -216,10 +216,10 @@ std::string subshell::generate(int ind)
std::string ret; std::string ret;
// open subshell // open subshell
ret += '('; ret += '(';
if(!opt_minimize) ret += '\n'; if(!opt_minify) ret += '\n';
// commands // commands
ret += lst->generate(ind+1); ret += lst->generate(ind+1);
if(opt_minimize && ret.size()>1) if(opt_minify && ret.size()>1)
ret.pop_back(); // ) can be right after command ret.pop_back(); // ) can be right after command
// close subshell // close subshell
ret += indented(")", ind); ret += indented(")", ind);
@ -238,7 +238,7 @@ std::string shmain::generate(bool print_shebang, int ind)
if(print_shebang && shebang!="") if(print_shebang && shebang!="")
ret += shebang + '\n'; ret += shebang + '\n';
ret += lst->generate(ind); ret += lst->generate(ind);
if( opt_minimize && ret[ret.size()-1] == '\n') if( opt_minify && ret[ret.size()-1] == '\n')
ret.pop_back(); ret.pop_back();
ret += generate_redirs(ind, ret); ret += generate_redirs(ind, ret);
@ -262,7 +262,7 @@ std::string function::generate(int ind)
std::string ret; std::string ret;
// function definition // function definition
ret += name + "()"; ret += name + "()";
if(!opt_minimize) ret += '\n'; if(!opt_minify) ret += '\n';
// commands // commands
ret += indented("{\n", ind); ret += indented("{\n", ind);
ret += lst->generate(ind+1); ret += lst->generate(ind+1);
@ -286,17 +286,17 @@ std::string case_block::generate(int ind)
ret += it->generate(ind) + '|'; ret += it->generate(ind) + '|';
ret.pop_back(); ret.pop_back();
ret += ')'; ret += ')';
if(!opt_minimize) ret += '\n'; if(!opt_minify) ret += '\n';
// commands // commands
ret += cs.second->generate(ind+1); ret += cs.second->generate(ind+1);
// end of case: ;; // end of case: ;;
if(opt_minimize && ret[ret.size()-1] == '\n') // ;; can be right after command if(opt_minify && ret[ret.size()-1] == '\n') // ;; can be right after command
ret.pop_back(); ret.pop_back();
ret += indented(";;\n", ind+1); ret += indented(";;\n", ind+1);
} }
// remove ;; from last case // remove ;; from last case
if(this->cases.size()>0 && opt_minimize) if(this->cases.size()>0 && opt_minify)
{ {
ret.erase(ret.size()-3, 2); ret.erase(ret.size()-3, 2);
} }
@ -374,9 +374,9 @@ std::string arithmetic_subarg::generate(int ind)
{ {
std::string ret; std::string ret;
ret += "$(("; ret += "$((";
if(!opt_minimize) ret += ' '; if(!opt_minify) ret += ' ';
ret += arith->generate(ind); ret += arith->generate(ind);
if(!opt_minimize) ret += ' '; if(!opt_minify) ret += ' ';
ret += "))"; ret += "))";
return ret; return ret;
} }
@ -389,15 +389,15 @@ std::string operation_arithmetic::generate(int ind)
if(precedence) if(precedence)
{ {
ret += oper; ret += oper;
if(!opt_minimize) ret += ' '; if(!opt_minify) ret += ' ';
ret += val1->generate(ind); ret += val1->generate(ind);
} }
else else
{ {
ret += val1->generate(ind); ret += val1->generate(ind);
if(!opt_minimize) ret += ' '; if(!opt_minify) ret += ' ';
ret += oper; ret += oper;
if(!opt_minimize) ret += ' '; if(!opt_minify) ret += ' ';
ret += val2->generate(ind); ret += val2->generate(ind);
} }
return ret; return ret;
@ -407,9 +407,9 @@ std::string parenthesis_arithmetic::generate(int ind)
{ {
std::string ret; std::string ret;
ret += '('; ret += '(';
if(!opt_minimize) ret += ' '; if(!opt_minify) ret += ' ';
ret += val->generate(ind); ret += val->generate(ind);
if(!opt_minimize) ret += ' '; if(!opt_minify) ret += ' ';
ret += ')'; ret += ')';
return ret; return ret;
} }

View file

@ -12,7 +12,7 @@
#include "parse.hpp" #include "parse.hpp"
#include "options.hpp" #include "options.hpp"
#include "recursive.hpp" #include "recursive.hpp"
#include "minimize.hpp" #include "minify.hpp"
#include "resolve.hpp" #include "resolve.hpp"
#include "processing.hpp" #include "processing.hpp"
#include "debashify.hpp" #include "debashify.hpp"
@ -39,13 +39,18 @@ void oneshot_opt_process(const char* arg0)
printf("%s\n", VERSION_SHA); printf("%s\n", VERSION_SHA);
exit(0); exit(0);
} }
else if(options["help-commands"]) else if(options["help-link-commands"])
{ {
print_include_help(); print_include_help();
printf("\n\n"); printf("\n\n");
print_resolve_help(); print_resolve_help();
exit(ERR_HELP); exit(ERR_HELP);
} }
else if(options["help-lxsh-commands"])
{
print_lxsh_cmd_help();
exit(ERR_HELP);
}
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@ -188,17 +193,17 @@ int main(int argc, char* argv[])
} }
// processing before output // processing before output
// minimize // minify
if(options['m']) if(options['m'])
opt_minimize=true; opt_minify=true;
if(options["remove-unused"]) if(options["remove-unused"])
delete_unused( sh, re_var_exclude, re_fct_exclude ); delete_unused( sh, re_var_exclude, re_fct_exclude );
if(options["minimize-quotes"]) if(options["minify-quotes"])
minimize_quotes(sh); minify_quotes(sh);
if(options["minimize-var"]) if(options["minify-var"])
minimize_var( sh, re_var_exclude ); minify_var( sh, re_var_exclude );
if(options["minimize-fct"]) if(options["minify-fct"])
minimize_fct( sh, re_fct_exclude ); minify_fct( sh, re_fct_exclude );
// other processing // other processing
if(options["unset-var"]) if(options["unset-var"])
add_unset_variables( sh, re_var_exclude ); add_unset_variables( sh, re_var_exclude );

View file

@ -1,4 +1,4 @@
#include "minimize.hpp" #include "minify.hpp"
#include "parse.hpp" #include "parse.hpp"
@ -105,7 +105,7 @@ bool is_this_quote(char c, bool is_doublequote)
return c == '\''; return c == '\'';
} }
void do_one_minimize_quotes(string_subarg* in, bool prev_is_var, bool start_quoted) void do_one_minify_quotes(string_subarg* in, bool prev_is_var, bool start_quoted)
{ {
std::string& val = in->val; std::string& val = in->val;
if(val.size() <= 1) if(val.size() <= 1)
@ -191,7 +191,7 @@ void do_one_minimize_quotes(string_subarg* in, bool prev_is_var, bool start_quot
} }
bool r_minimize_useless_quotes(_obj* in) bool r_minify_useless_quotes(_obj* in)
{ {
switch(in->type) switch(in->type)
{ {
@ -209,9 +209,9 @@ bool r_minimize_useless_quotes(_obj* in)
if(vs->var != nullptr && vs->var->is_manip == false && vs->var->varname.size()>0 && !(is_in(vs->var->varname[0], SPECIAL_VARS) || is_alpha(vs->var->varname[0]) ) ) if(vs->var != nullptr && vs->var->is_manip == false && vs->var->varname.size()>0 && !(is_in(vs->var->varname[0], SPECIAL_VARS) || is_alpha(vs->var->varname[0]) ) )
prev_is_var=true; prev_is_var=true;
} }
if(t->sa.size()==1 && (ss->val=="\"\"" || ss->val=="''") ) // single argument as "" or '': don't minimize if(t->sa.size()==1 && (ss->val=="\"\"" || ss->val=="''") ) // single argument as "" or '': don't minify
continue; continue;
do_one_minimize_quotes(ss, prev_is_var, i>0 && t->sa[i-1]->quoted); do_one_minify_quotes(ss, prev_is_var, i>0 && t->sa[i-1]->quoted);
} }
//if() //if()
} }
@ -221,7 +221,7 @@ bool r_minimize_useless_quotes(_obj* in)
return true; return true;
} }
/** NAME MINIMIZING **/ /** NAME MINIFYING **/
char nchar(uint32_t n) char nchar(uint32_t n)
{ {
@ -282,7 +282,7 @@ strmap_t gen_minimal_map(countmap_t const& vars, set_t const& excluded)
// calls // calls
void minimize_var(_obj* in, std::regex const& exclude) void minify_var(_obj* in, std::regex const& exclude)
{ {
// countmap_t vars; // countmap_t vars;
set_t excluded; set_t excluded;
@ -296,7 +296,7 @@ void minimize_var(_obj* in, std::regex const& exclude)
require_rescan_var(); require_rescan_var();
} }
void minimize_fct(_obj* in, std::regex const& exclude) void minify_fct(_obj* in, std::regex const& exclude)
{ {
// countmap_t fcts, cmdmap; // countmap_t fcts, cmdmap;
set_t allcmds, excluded, unsets; set_t allcmds, excluded, unsets;
@ -362,9 +362,9 @@ bool delete_unused_var(_obj* in, std::regex const& exclude)
return false; return false;
} }
void minimize_quotes(_obj* in) void minify_quotes(_obj* in)
{ {
recurse(r_minimize_useless_quotes, in); recurse(r_minify_useless_quotes, in);
} }
void delete_unused(_obj* in, std::regex const& var_exclude, std::regex const& fct_exclude) void delete_unused(_obj* in, std::regex const& var_exclude, std::regex const& fct_exclude)

View file

@ -1,9 +1,10 @@
#include "options.hpp" #include "options.hpp"
#include "processing.hpp" #include "processing.hpp"
#include "shellcode.hpp"
ztd::option_set options = gen_options(); ztd::option_set options = gen_options();
bool opt_minimize=false; bool opt_minify=false;
bool g_cd=false; bool g_cd=false;
bool g_include=true; bool g_include=true;
@ -17,7 +18,8 @@ ztd::option_set gen_options()
ztd::option("\r [Help]"), ztd::option("\r [Help]"),
ztd::option('h', "help", false, "Display this help message"), ztd::option('h', "help", false, "Display this help message"),
ztd::option("version", false, "Display version"), ztd::option("version", false, "Display version"),
ztd::option("help-commands", false, "Print help for linker commands"), ztd::option("help-link-commands", false, "Print help for special lxsh commands"),
ztd::option("help-lxsh-commands", false, "Print help for linker commands"),
ztd::option("\r [Output]"), ztd::option("\r [Output]"),
ztd::option('o', "output", true , "Output result script to file", "file"), ztd::option('o', "output", true , "Output result script to file", "file"),
ztd::option('c', "stdout", false, "Output result script to stdout"), ztd::option('c', "stdout", false, "Output result script to stdout"),
@ -25,15 +27,15 @@ ztd::option_set gen_options()
ztd::option("no-shebang", false, "Don't output shebang"), ztd::option("no-shebang", false, "Don't output shebang"),
ztd::option('J', "json", false, "Output the json structure"), ztd::option('J', "json", false, "Output the json structure"),
ztd::option("\r [Processing]"), ztd::option("\r [Processing]"),
ztd::option('m', "minimize", false, "Minimize code without changing functionality"), ztd::option('m', "minify", false, "Minify code without changing functionality"),
ztd::option("minimize-quotes", false, "Remove unnecessary quotes"), ztd::option("minify-quotes", false, "Remove unnecessary quotes"),
ztd::option('C', "no-cd", false, "Don't cd when doing %include and %resolve"), ztd::option('C', "no-cd", false, "Don't cd when doing %include and %resolve"),
ztd::option('I', "no-include", false, "Don't resolve %include commands"), ztd::option('I', "no-include", false, "Don't resolve %include commands"),
ztd::option('R', "no-resolve", false, "Don't resolve %resolve commands"), ztd::option('R', "no-resolve", false, "Don't resolve %resolve commands"),
ztd::option("debashify", false, "Attempt to turn a bash-specific script into a POSIX shell script"), ztd::option("debashify", false, "Attempt to turn a bash-specific script into a POSIX shell script"),
ztd::option("\r [var/fct processing]"), ztd::option("\r [var/fct processing]"),
ztd::option("minimize-var", false, "Minimize variable names"), ztd::option("minify-var", false, "Minify variable names"),
ztd::option("minimize-fct", false, "Minimize function names"), ztd::option("minify-fct", false, "Minify function names"),
ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing", "list"), ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing", "list"),
ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing", "list"), ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing", "list"),
ztd::option("no-exclude-reserved",false, "Don't exclude reserved variables"), ztd::option("no-exclude-reserved",false, "Don't exclude reserved variables"),
@ -121,3 +123,11 @@ void print_resolve_help()
printf("Options:\n"); printf("Options:\n");
opts.print_help(3,7); opts.print_help(3,7);
} }
void print_lxsh_cmd_help()
{
for(auto it: lxsh_shellcode_fcts)
{
printf("%s %s\n%s\n\n", it.first.c_str(), it.second.arguments.c_str(), it.second.description.c_str());
}
}

8
src/shellcode.cpp Normal file
View file

@ -0,0 +1,8 @@
#include "shellcode.hpp"
#include "g_shellcode.h"
const std::map<const std::string, const struct lxsh_fct> lxsh_shellcode_fcts = {
{ "_lxsh_random_string", { "N", "Generate a random alphanumeric string of length N. Default 20", RANDOM_STRING_SH} },
{ "_lxsh_random_tmpfile", { "N", "Get a random TMP filepath, with N random chars. Default 20", RANDOM_TMPFILE_SH} }
};

View file

@ -164,13 +164,13 @@ std::string arg::first_sa_string()
std::vector<std::string> arglist::strargs(uint32_t start) std::vector<std::string> arglist::strargs(uint32_t start)
{ {
std::vector<std::string> ret; std::vector<std::string> ret;
bool t=opt_minimize; bool t=opt_minify;
opt_minimize=true; opt_minify=true;
for(uint32_t i=start; i<args.size(); i++) for(uint32_t i=start; i<args.size(); i++)
{ {
ret.push_back(args[i]->generate(0)); ret.push_back(args[i]->generate(0));
} }
opt_minimize=t; opt_minify=t;
return ret; return ret;
} }