6 ms·
I believe that scripts without a shebang line cannot be executed by execve. They will only run if the shell sees them before the kernel does. It's an annoying l
by modeless 6y ago
I believe that scripts without a shebang line cannot be executed by execve. They will only run if the shell sees them before the kernel does. It's an annoying limitation of this approach and it wasn't clear to me whether this technique includes a workaround for this. Also the push for code signing everywhere is going to make this harder in the future as well. (I heard a rumor that the workaround to run unsigned executables on macOS no longer works when running on Apple Silicon.) Otherwise, I love it!
My approach was slightly different; I created a polyglot script header you can paste at the beginning of a C source file to make it essentially a C script which is just-in-time compiled when it is executed. Works on Windows, Linux, and Mac as long as a C compiler is installed. https://gist.github.com/jdarpinian/6860ddfd92b5b458a20ab6055583bc3e https://gist.github.com/jdarpinian/6860ddfd92b5b458a20ab6055...
- ChrisSD 6y ago> C compiler is installed It's a great idea but that part is a big ask for any Windows user who doesn't develop desktop applications.
- modeless 6y agoTrue. I'm imagining this as useful mostly for build scripts or other developer tools. To the extent that it's useful at all.
- terminalcommand 6y agoIt is actually pretty useful. If you’re given a locked down machine (for example in your company), you can write code in notepad, compile it with csc.exe and run it. As it is generated on the local machine, you may get to be able to execute it. (I tried this once when I was super bored at an intership, and a hello world program compiled and ran.)
- int_19h 6y agoOn Windows, though, there's C# compiler out of the box on every OS since Vista. And C# has a bunch of rarely-used syntax for things like raw pointers, that can work on more or less the same level as C, and even look pretty similar. It might be possible to do something with that.
- SyneRyder 6y agoHuh, I never knew this. For anyone else who didn't know, it's in the C:\Windows\Microsoft.NET\Framework64\ folders, it's the CSC.exe file included with each version of the .NET framework. Edit: Good grief, there's even vbc.exe, which is a command line Visual Basic 2012 compiler. Also JSC.exe for Jscript, aspnet_compiler.exe for ASP and MSBuild. Kinda embarrassed that I didn't know this.
- scruffyherder 6y agoIt’s been my go to toolset for ages. It’s the #1 reason to learn c# as it’s everywhere. Also if we are talking exploit vectors, uuencode is great for people that let you have a clipboard. Get uudecode in c#, and paste in your arbitrary binaries and you’ll be in business In no time!
- int_19h 6y agoIn case you're wondering why - it's because every version of Windows since Vista comes with .NET Framework, and .NET Framework has this API: https://docs.microsoft.com/en-us/dotnet/api/system.codedom https://docs.microsoft.com/en-us/dotnet/api/system.codedom If you look at the functionality provided there, it includes ability to compile generated code. This is implemented using those command-line compilers.
- JoshTriplett 6y ago> I believe that scripts without a shebang line cannot be executed by execve. This was once true on old systems, but current ones (including Linux) have native support for scripts starting with #!. See fs/binfmt_script.c in Linux, which has existed for several decades.
- modeless 6y agoI'm talking about scripts without the shebang (#!) line.
- JoshTriplett 6y agoI'm sorry, I completely misread that. There were once systems where scripts with the shebang line would get run by the shell rather than the kernel, hence my confusion.
- FeepingCreature 6y agoYes, that is the aforementioned shebang line.
- saagarjha 6y ago> the workaround to run unsigned executables Was there ever a workaround for this? I thought you just ran them…
- modeless 6y agoDownloaded unsigned executables will not run by default on macOS and the error dialog provides no affordance to override this. You just have to know that if you option-click and select "Open", which is always identical to double-clicking except in this special case, you get a different dialog that allows you to override the block.
- saagarjha 6y agoYou've always been able to run those without any warnings from the command line.
- modeless 6y agoI think that counts as a workaround and no longer works on Apple Silicon. But I haven't verified this myself. Would be interesting to hear from someone who knows. Edit: Here are the details. Looks like it's true that it simply won't run totally unsigned ARM code. But self-signing is allowed. For now. https://lapcatsoftware.com/articles/unsigned.html https://lapcatsoftware.com/articles/unsigned.html
- saagarjha 6y agoRight, Apple silicon has different rules.
- jart 6y agoAuthor here. I considered doing that. Then I learned about things like how MSVC 2017 would wrap the main() function of C programs with telemetry. The push for code signing, retpoline, aslr, etc. worries me too, from a software freedom standpoint, and the same goes for how difficult it's become to build native software from scratch, thanks to the shift from autotools to a whole new set of competitors like bazel, cmake, ninja, gin, etc. Secure boot is another red flag. By 2018 it almost felt like we were entering a world in which, for all practical purposes, we couldn't share native software easily in either source or binary forms. If PC platforms ever do manage to get consumers to accept the iPhone App Store restriction model, it'll likely stay that way. Best way to prevent that from happening is to use Actually Portable Executable. The more people who continue to depend directly on canonical long-standing stock platform abis, the more impossible it becomes for platforms to re-imagine them every few years. I'll take UNIX+WIN32 over things like XUL any day, since I don't want to fall into the JS dev trap of having to rewrite my app with each passing moon. Also note that the execve() shebang thing is a one-time cost. The printf statement in the header will overwrite the first 64-bytes of the executable, the first time it's invoked, so it becomes a canonical ELF or Mach-O executable for subsequent invocations. The one-time cost is also cheap. The shell script only needs three system calls (open, write, and execve) to patch the binary appropriately. The generation of this header is also abstracted by the GNU ld script, which made it easy for me to encode the ELF header relocations as octal printf codes!
- modeless 6y ago> The printf statement in the header will overwrite the first 64-bytes of the executable This is cool but also a problem for subsequent sharing of the executable. I thought about doing this as well but decided against having the file mutate into a version that wouldn't work on other systems. Again, super cool project! I love this kind of thing.
- 2bitencryption 6y ago> The printf statement in the header will overwrite the first 64-bytes of the executable, the first time it's invoked Is this a problem for anti-virus/other security measures? My understanding is, executables that manipulate themselves is something any security software will look for. Though perhaps the answer is "don't rely upon security software to police your system; do it yourself"