[erlang-questions] Encrypt beam

Ulf Wiger (TN/EAB) ulf.wiger@REDACTED
Thu Oct 11 11:09:50 CEST 2007


Roberto Saccon wrote:
> take a look at the beam_lib documentation
> 
> http://erlang.org/doc/man/beam_lib.html
> 

To clarify, beam_lib offers a way to encrypt the
'debug_info' (the source in parsed form) which can be
embedded in the beam file. This allows you to embed
debug_info even if you don't want to reveal the source
code. The encryption can be unlocked at runtime, so that
you can e.g. run profiling, etc. (perhaps eventually even
pretty-print the source and view it through distel?)

The beam code itself can of course be reverse-engineered.
The format isn't documented, but to get some idea of
what can possibly be extracted from beam code, you can view
the ASM code, from which the beam code is produced. How to
do this _is_ documented. Whether this is acceptable
obfuscation of your code, is of course up to you.

See an example at the end of this mail.

BR,
Ulf W


> 
> On 10/11/07, yerl@REDACTED <yerl@REDACTED> wrote:
>>  Hi guys !
>>
>> I'm looking for a simple to encrypt ".beam" files to be sure that nobody
>> could reverse engineer them and got the original source (.erl).
>>
>> For now, I'm just removing the debugging stuffs from them (.beam). Is it
>> enough for my problem ?
>>
>> Thanks in advance
>>
>> cheers
>> Y.
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://www.erlang.org/mailman/listinfo/erlang-questions

= = = = = Example:

***** lc.erl:

-module(lc).

-export([lc1/1,
          lc2/2]).


lc1(List) ->
     L = [foo(X) ||
             X <- List,
             X > 17],
     lists:reverse(L).

lc2(List1, List2) ->
     [foo({X, Y}) ||
         X <- List1,
         Y <- List2,
         X > Y].

foo(X) -> X.

*****
erlc -W -S lc.erl

***** lc.S:

{module, lc}.  %% version = 0

{exports, [{lc1,1},{lc2,2},{module_info,0},{module_info,1}]}.

{attributes, []}.

{labels, 22}.


{function, lc1, 1, 2}.
   {label,1}.
     {func_info,{atom,lc},{atom,lc1},1}.
   {label,2}.
     {allocate,0,1}.
     {'%live',1}.
     {call,1,{f,19}}.
     {call_ext_last,1,{extfunc,lists,reverse,1},0}.


{function, lc2, 2, 4}.
   {label,3}.
     {func_info,{atom,lc},{atom,lc2},2}.
   {label,4}.
     {call_only,2,{f,12}}.


{function, foo, 1, 6}.
   {label,5}.
     {func_info,{atom,lc},{atom,foo},1}.
   {label,6}.
     return.


{function, module_info, 0, 8}.
   {label,7}.
     {func_info,{atom,lc},{atom,module_info},0}.
   {label,8}.
     {move,{atom,lc},{x,0}}.
     {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.


{function, module_info, 1, 10}.
   {label,9}.
     {func_info,{atom,lc},{atom,module_info},1}.
   {label,10}.
     {move,{x,0},{x,1}}.
     {move,{atom,lc},{x,0}}.
     {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.


{function, '-lc2/2-lc$^0/1-0-', 2, 12}.
   {label,11}.
     {func_info,{atom,lc},{atom,'-lc2/2-lc$^0/1-0-'},2}.
   {label,12}.
     {test,is_nonempty_list,{f,13},[{x,0}]}.
     {get_list,{x,0},{x,3},{x,2}}.
     {move,{x,1},{x,0}}.
     {call_only,4,{f,15}}.
   {label,13}.
     {test,is_nil,{f,11},[{x,0}]}.
     return.


{function, '-lc2/2-lc$^1/1-1-', 4, 15}.
   {label,14}.
     {func_info,{atom,lc},{atom,'-lc2/2-lc$^1/1-1-'},4}.
   {label,15}.
     {test,is_nonempty_list,{f,17},[{x,0}]}.
     {get_list,{x,0},{x,4},{x,5}}.
     {test,is_lt,{f,16},[{x,4},{x,3}]}.
     {allocate_heap,4,3,6}.
     {move,{x,1},{y,3}}.
     {move,{x,2},{y,2}}.
     {move,{x,3},{y,1}}.
     {move,{x,5},{y,0}}.
     {put_tuple,2,{x,0}}.
     {put,{x,3}}.
     {put,{x,4}}.
     {'%live',1}.
     {call,1,{f,6}}.
     {move,{x,0},{x,4}}.
     {move,{y,2},{x,2}}.
     {move,{y,3},{x,1}}.
     {move,{y,1},{x,3}}.
     {move,{y,0},{x,0}}.
     {move,{x,4},{y,3}}.
     {'%live',4}.
     {kill,{y,0}}.
     {kill,{y,1}}.
     {kill,{y,2}}.
     {call,4,{f,15}}.
     {test_heap,2,1}.
     {put_list,{y,3},{x,0},{x,0}}.
     {'%live',1}.
     {deallocate,4}.
     return.
   {label,16}.
     {move,{x,5},{x,0}}.
     {call_only,4,{f,15}}.
   {label,17}.
     {test,is_nil,{f,14},[{x,0}]}.
     {move,{x,2},{x,0}}.
     {call_only,2,{f,12}}.


{function, '-lc1/1-lc$^0/1-0-', 1, 19}.
   {label,18}.
     {func_info,{atom,lc},{atom,'-lc1/1-lc$^0/1-0-'},1}.
   {label,19}.
     {test,is_nonempty_list,{f,21},[{x,0}]}.
     {get_list,{x,0},{x,1},{x,2}}.
     {test,is_lt,{f,20},[{integer,17},{x,1}]}.
     {allocate,1,3}.
     {move,{x,1},{x,0}}.
     {move,{x,2},{y,0}}.
     {'%live',1}.
     {call,1,{f,6}}.
     {move,{x,0},{x,1}}.
     {move,{y,0},{x,0}}.
     {move,{x,1},{y,0}}.
     {'%live',1}.
     {call,1,{f,19}}.
     {test_heap,2,1}.
     {put_list,{y,0},{x,0},{x,0}}.
     {'%live',1}.
     {deallocate,1}.
     return.
   {label,20}.
     {move,{x,2},{x,0}}.
     {call_only,1,{f,19}}.
   {label,21}.
     {test,is_nil,{f,18},[{x,0}]}.
     return.



More information about the erlang-questions mailing list