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

+3


source to share


1 answer


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

      

+3


source







All Articles