Skip to content

rosemash/luape

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

96 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

luape

A self-patching Windows executable containing Lua 5.1.5 for quickly generating standalone executables that run Lua scripts.

How does it work?

The output of this source code is luape.exe, a minimal Windows executable that simply runs a Lua script contained at a hard-coded memory offset. The script contained there by default is designed to replace itself with any arbitrary Lua code, producing a new standalone executable.

The LuaSocket version of luape is compatible with Windows Vista and higher, and has access to low-level LuaSocket bindings (socket.core and mime.core). Check out the .lua files in /deps/luasocket to see how the official LuaSocket library scripts implement those bindings, and copy what you need into your own code for use with luape.

How do I use it?

You can build it (not recommended) or download one of the prebuilt versions here.

Usage: luape.exe <source OR file:source.lua> <output.exe> [option...]

Simple example: luape.exe "print('hello world')" hello.exe

Here are the available options:

  • /name=... Set the Lua chunk name to an alphanumeric string (example: /name=myscript)

  • /debug - Include Lua debug information in the compiled chunk

  • /hidden - Generate a PE that doesn't open a console window or GUI

Let's say you have a file called hello.lua in the same directory as luape.exe that you wish to compile into hello.exe, with debug information intact and the chunkname set to "myscript". This is the command you would execute: luape.exe file:hello.lua hello.exe /debug /name=myscript.

Options must go after the first and second argument. If the first argument doesn't begin with file: it will be interpreted as the source code, otherwise it will open from the filename after the separator and read that.

How do I build it?

First keep in mind my goal with this project was to create luape.exe, which itself acts as a builder of other executables. Now that luape.exe exists, this repository is pretty much useless to me, and it only exists for archival purposes. If you want to use luape, you don't have to build it, you can just download the pre-built luape.exe and use it to package other Lua scripts.

The method of building it is convoluted, and it might break when attempting to compile from other configurations. I have only tested compilation on Debian Buster using MinGW. To follow in my footsteps, make sure you've installed mingw-w64, wine32, and python2 with the future module (sudo apt install python-pip && sudo pip install future), then keep reading.

If your package manager can't find wine32 and you're on Debian Buster, it's because you have to enable 32-bit packages: run sudo dpkg --add-architecture i386, sudo apt update, then try again.

You will need to update _WIN32_WINNT in /usr/i686-w64-mingw32/include/_mingw.h to a value of 0x0600 (Windows Vista and higher) to compile with LuaSocket, otherwise you won't have a definition for the function inet_pton, which is necessary for ipv6 support. There unfortunately doesn't seem to be a way to override it without changing that file.

When you're ready, run ./build.sh in the project root. If you want to compile without LuaSocket, run ./build.sh nosocket instead.

If you are on a different system or using a different compiler with a different configuration, MAKE SURE TO STRIP DEBUG SYMBOLS! That's what the -s flag is doing in build.sh. The hack we're doing expects the PE sections to be at the very end of the file. If you can somehow include symbols without spamming useless garbage to the end of the file, go ahead, but I recommend generating the simplest PE you can with your compiler settings, otherwise it's going to break.

If you're compiling with your own configuration, make sure the output is a.exe in the project root folder. It will crash if you run it. Run python2 python/hack.py to create luape.exe. It uses pefile and a PE section editing module called SectionDoubleP (source: https://git.n0p.cc/SectionDoubleP) to create a new region for the generator script, and then creates a specialized version of lua/generator.template.lua that contains the correct offsets. This script will be patched into the newly-created section, and the magic offset in main.c will be updated to point to it. The script will then run luape.exe on its own Lua source, compiling it and creating a bootstrapped version of luape.exe that contains bytecode insead of the plain generator source.

After a successful build, the resulting executable should have the same behavior as the one currently available on the releases page. It is recommended to test all flags to make sure.

What is the purpose of luape?

I wanted to be able to easily package standalone Lua scripts as zero-dependency executable files without following complicated steps. While I came across projects that met some of these requirements (such as luastatic), nothing was completely satisfying. In particular, I didn't like the requirement to collect dependencies and compile the executable using a C compiler.

Initially, I had someone tell me that this concept was impractical and pointless, adding that they would be impressed if I actually managed to create it and not make it suck. I came up with an overly-complicated solution that packaged an entire portable distribution of MinGW, along with an executable that automated putting the Lua script into a C header and compiling it with the Lua source code. They weren't impressed at all, and I wasn't a big fan of it either.

Many years later, I had already moved on, but I created luape as a way to reconcile with this failure.

Can I use it in my project?

luape is released permissively under the MIT license.

About

A simple Windows executable that frankenstines with Lua to create portable scripts

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published