Get the source code of the escript executable
by mistake I deleted the escript source code I wrote; as a last resort, I am trying to get the source (if at all possible) by decompiling an executable that I have deployed to the server.
In case that matters, it was compiled on Ubuntu 16.04 by running mix escript.build with no additional arguments.
I would appreciate it if someone could give me some pointers on how to do this or where to start!
thank
source to share
You can get the compiled Erlang source of your files here. I do not think it is possible to return the original source of the elixir, as it is not at all in this document; only compiled Erlang bytecode. Decompiled Erlang code should be readable enough if you know some Erlang (if not, check out this quick Erlang β Elixir course).
The escript executable starts with #! /usr/bin/env escript
, followed by some lines, and then the inline compiled files are present as a binary zip file. Open the escript file in an editor and delete everything until the line starts with PK
(start zip).
$ mix escript.build
$ head -c 59 m
#! /usr/bin/env escript
%%
%%! -escript main m_escript
PK
$ vim m # remove everything until `PK`
$ head -c2 m
PK
Now you can extract the contents of the file with unzip
and get all the compiled files .beam
:
$ unzip m -d extracted
Archive: m
inflating: extracted/m_escript.beam
inflating: extracted/Elixir.Version.Parser.DSL.beam
inflating: extracted/Elixir.Kernel.LexicalTracker.beam
inflating: extracted/Elixir.IO.ANSI.beam
inflating: extracted/Elixir.Inspect.NaiveDateTime.beam
inflating: extracted/Elixir.Protocol.beam
inflating: extracted/Elixir.Inspect.Any.beam
...
Finally, you can decompile the modules you want to use decompile-beam
:
$ decompile-beam extracted/Elixir.M.beam
-compile(no_auto_import).
-file("lib/m.ex", 1).
-module('Elixir.M').
-export(['__info__'/1, main/0, main/1]).
-spec '__info__'(attributes | compile | exports |
functions | macros | md5 | module |
native_addresses) -> atom() |
[{atom(), any()} |
{atom(), byte(), integer()}].
'__info__'(functions) -> [{main, 0}, {main, 1}];
'__info__'(macros) -> [];
'__info__'(info) ->
erlang:get_module_info('Elixir.M', info).
main() -> main([]).
main(args@1) -> 'Elixir.IO':inspect({args@1, args@1}).
This was the original source of the elixir:
$ cat lib/m.ex
defmodule M do
def main(args \\ []) do
IO.inspect {args, args}
end
end
source to share