MLI-X86(1)                  General Commands Manual                 MLI-X86(1)

NAME
       mli-x86 - Linux/x86 machine language interpreter

SYNOPSIS
       mli-x86 PROGRAM [ARGUMENTS...]

DESCRIPTION
       mli-x86 is a compact interpreter designed to load and execute position-
       independent flat binary executables on  the  x86  architecture.  Unlike
       standard  ELF  loaders,  mli-x86 maps the contents of a raw binary file
       directly into memory with read, write,  and  execute  permissions,  and
       then transfers control to the first byte of the file.

       It  is  intended  to  be  used  in  conjunction with the Linux kernel's
       binfmt_misc facility, allowing flat binaries (such as  those  generated
       by  mle(1))  to  be executed directly as if they were standard ELF exe‐
       cutables.

ARGUMENTS
       PROGRAM
              The path to the binary file to execute.

       ARGUMENTS
              Any subsequent arguments are passed directly to the loaded  pro‐
              gram. The interpreter manipulates the stack to ensure the target
              program receives an argc count and argv array  corresponding  to
              the program's invocation.

CONFIGURATION
       To  execute flat binaries transparently, mli-x86 can be registered as a
       binary format handler. The default configuration  associates  any  file
       starting with the 90 (NOP) opcode with the interpreter.

       Registration
              # mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
              # echo ':mli-x86:M:0:\x90::/usr/local/bin/mli-x86:' \
                   > /proc/sys/fs/binfmt_misc/register

       Confirmation
              # cat /proc/sys/fs/binfmt_misc/mli-x86
              enabled
              interpreter /usr/local/bin/mli-x86
              flags:
              offset 0
              magic 90

       Deregistration
              # echo -1 > /proc/sys/fs/binfmt_misc/mli-x86

EXAMPLE
       The  following  example demonstrates a functional implementation of the
       printenv utility.

       Preparation
              $ cd /tmp
              $ cat > printenv.src << "EOF"
              [ . x86 ]

              Magic:
                      90

              Start:
                      # Gather argc.
                      59                              # pop ecx

              SkipArguments:
                      5f                              # pop edi
                      49                              # dec ecx
                      75 [ rel8 SkipArguments ]       # jnz SkipArguments

                      # Skip the argument vector terminator.
                      5f                              # pop edi

              Print:
                      # Grab the next environment variable pointer.
                      5e                              # pop esi

                      # Exit if we've reached the NULL terminator.
                      85 f6                           # test esi esi
                      74 [ rel8 Quit ]                # jz Quit

                      # Get the variable length.
                      89 f7                           # mov esi edi
                      31 c0                           # xor eax eax
                      6a ff 59                        # mov -1 ecx
                      f2 ae                           # repnz scasb
                      f7 d1                           # not ecx

                      # Overwrite NUL terminator with LF.
                      c6 44 0e ff 0a                  # mov '\n' (esi + ecx - 1)

                      # write(STDOUT_FILENO, buffer, length);
                      89 ca                           # mov ecx edx
                      89 f1                           # mov esi ecx
                      6a 01 5b                        # mov STDOUT_FILENO ebx
                      6a 04 58                        # mov SYS_WRITE eax
                      cd 80                           # int 0x80

                      # Loop.
                      eb [ rel8 Print ]               # jmp Print

              Quit:
                      # exit(EXIT_SUCCESS);
                      31 db                           # xor ebx ebx
                      6a 01 58                        # mov SYS_EXIT eax
                      cd 80                           # int 0x80
              EOF

              $ mle -o printenv printenv.src
              $ chmod 755 printenv

              $ ls -al printenv
              -rwxr-xr-x 1 user user 49 Mar 29 05:39 printenv

       Explicit Execution (via the mli-x86 interpreter)
              $ mli-x86 ./printenv
              SHELL=/bin/sh
              PWD=/tmp
              LOGNAME=user
              HOME=/home/user
              TERM=linux
              USER=user
              PATH=/usr/sbin:/sbin:/usr/bin:/bin
              MAIL=/var/mail/user
              OLDPWD=/home/user

       Transparent Execution (after binfmt_misc registration)
              $ ./printenv
              SHELL=/bin/sh
              PWD=/tmp
              LOGNAME=user
              HOME=/home/user
              TERM=linux
              USER=user
              PATH=/usr/sbin:/sbin:/usr/bin:/bin
              MAIL=/var/mail/user
              OLDPWD=/home/user

DEBUGGING
       Debugging mli-x86 programs involves inspecting the state of the  inter‐
       preter just before it yields control to the loaded binary. A GDB script
       is installed with mli-x86 to automate this process.

       Example Session
              Reading symbols from bin/mli-x86...
              (No debugging symbols found in bin/mli-x86)

              (gdb) source /usr/local/share/mli-x86/mli-x86.gdb
              Breakpoint 1 at 0x8049041

              (gdb) r
              Starting program: /usr/local/bin/mli-x86 ./printenv
              eax            0xf7ff7000          -134254592
              ecx            0x31                49
              edx            0x7                 7
              ebx            0x0                 0
              esp            0xffffd354          0xffffd354
              ebp            0x0                 0x0
              esi            0x2                 2
              edi            0x3                 3
              eip            0x8049041           0x8049041
              eflags         0x287               [ CF PF SF IF ]
              cs             0x23                35
              ss             0x2b                43
              ds             0x2b                43
              es             0x2b                43
              fs             0x0                 0
              gs             0x0                 0
              0xffffd354:     0x00000001      0xffffd504      0x00000000      0xffffd512
              0xffffd364:     0xffffd522      0xffffd534      0xffffd547      0xffffd55b

              Breakpoint 1, 0x08049041 in ?? ()
              1: x/4i $pc
              => 0x8049041:   jmp    *%eax
                 0x8049043:   push   $0x1
                 0x8049045:   pop    %ebx
                 0x8049046:   push   $0x1

              (gdb) stepi
              eax            0xf7ff7000          -134254592
              ecx            0x31                49
              edx            0x7                 7
              ebx            0x0                 0
              esp            0xffffd354          0xffffd354
              ebp            0x0                 0x0
              esi            0x2                 2
              edi            0x3                 3
              eip            0xf7ff7000          0xf7ff7000
              eflags         0x287               [ CF PF SF IF ]
              cs             0x23                35
              ss             0x2b                43
              ds             0x2b                43
              es             0x2b                43
              fs             0x0                 0
              gs             0x0                 0
              0xffffd354:     0x00000001      0xffffd504      0x00000000      0xffffd512
              0xffffd364:     0xffffd522      0xffffd534      0xffffd547      0xffffd55b
              0xf7ff7000 in ?? ()
              1: x/4i $pc
              => 0xf7ff7000:  nop
                 0xf7ff7001:  pop    %ecx
                 0xf7ff7002:  pop    %edi
                 0xf7ff7003:  dec    %ecx

       Pest Augmentation
              Refer to the shelf(1) manual page for more information about how
              to  use symbols.plan to generate a separate debug info file from
              the symbol map file produced by mle during the encoding process.

FILES
       /usr/local/bin/mli-x86
              The recommended installation location for the  interpreter  exe‐
              cutable.

       /usr/local/share/mli-x86/mli-x86.gdb
              A  GDB  script  which sets a breakpoint at the handover address,
              and displays CPU register states, the last 8 stack elements, and
              the next 4 instructions.

       /proc/sys/fs/binfmt_misc/register
              The  interface for registering new binary formats with the Linux
              kernel.

SEE ALSO
       mle(1), mle-x86(7), shelf(1)

AUTHOR
       Justin Swartz <justin.swartz@risingedge.co.za>

COPYRIGHT
       Copyright (c) 2024-2026 Justin Swartz.

       This software is distributed under the 2-Clause BSD License.  Redistri‐
       bution  and  use  in source and binary forms, with or without modifica‐
       tion, are permitted provided that the license conditions are met.

MLI-X86                            May 2026                         MLI-X86(1)
