erlang

erlang-常见的特殊文件

2019-12-10  本文已影响0人  Alking

$HOME/.erlang

文件$HOME/.erlang一旦存在,并且是一个合法的erlang语句,那么在erlang虚拟机启动之后会默认执行语句,执行语句参考c:erlangc().这个在自定义自己的虚拟机行为有很大的用途,比如在开启的时候默认输入一些内容到console或者文件中,再有甚者可以在开启的时候覆盖启动参数,比如cookie,例子如下(当然这种修改启动参数的习惯不是好习惯):

% 没有.erlang文件
alking-mbp:~ dev$ erl -sname abc -setcookie cookie
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Eshell V10.2  (abort with ^G)
(abc@alking-mbp)1> auth:cookie().
cookie
(abc@alking-mbp)2> 

% 自定义.erlang文件
alking-mbp:~ dev$ cat .erlang
io:format("hello,alking.~n",[]).% 在console打印字符串
auth:cookie("adcaca").%修改启动参数

alking-mbp:~ dev$ erl -sname abc -setcookie cookie
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

hello,alking.
Eshell V10.2  (abort with ^G)
(abc@alking-mbp)1> auth:cookie().
"adcaca"

$HOME/.erlang.cookie

文件$HOME/.erlang.cookie的用途相当于虚拟机启动参数-setcookie,在文件中保存一个字符串,在启动的时候,如果没有启动参数-setcookie那么该节点(node)的cookie就是文件中的内容,需要注意的是,该文件的文件模式(mod)必须是400,参考auth:read_cookie().

这个文件的好处就是源代码不会暴露自己的cookie,除非自己的机器被黑。下面演示启动参数-setcookie如何覆盖文件cookie内容

alking-mbp:~ dev$ cat .erlang.cookie 
NKEFXULSNLVBRFDHWYFC

% 启动参数 cookie覆盖文件中设置
erl -sname abc -setcookie cookie
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Eshell V10.2  (abort with ^G)
(abc@alking-mbp)1> auth:cookie().
cookie

$HOME/.erlang.crypt

文件$HOME/.erlang.crypt如果存在,那么erl文件编译成beam文件会默认进行代码加密,熟悉java的同学或许对代码混淆有所了解,这个加密有类似的功能,请参考beam_lib:crypto_key_fun_from_file().

大家在测试环境编译代码的时候,经常带上debug_info参数,通常配置在rebar.config内,方便测试,或者线上调试,但是这个选项生成的beam文件一旦被别人拿到,就容易反编译成源代码,下面我来演示一下:

% 源代码erlang_bullet_sup.erl
alking-mbp:src dev$ cat erlang_bullet_sup.erl 
-module(erlang_bullet_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
-define(SERVER, ?MODULE).

start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []).

init([]) -> {ok, {{one_for_all, 0, 1}, []}}.

% 编译成beam文件
alking-mbp:src dev$ erlc +debug_info erlang_bullet_sup.erl 


alking-mbp:src dev$ erl
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Eshell V10.2  (abort with ^G)
1> {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks("erlang_bullet_sup.beam",[abstract_code]).
{ok,{erlang_bullet_sup,[{abstract_code,{raw_abstract_v1,[{attribute,1,
                                                                    file,
                                                                    {"erlang_bullet_sup.erl",1}},
 ......
 ......
2> io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).
% 几乎可以重现源代码
-file("erlang_bullet_sup.erl", 1).
......

% 有加密文件
alking-mbp:src dev$ cat ~/.erlang.crypt 
[{debug_info, des3_cbc, [], "secret"}].

erlc +encrypt_debug_info erlang_bullet_sup.erl 

% 移除crypt文件之后,无法进行代码反编译了
alking-mbp:src dev$ mv ~/.erlang.crypt ~/.erlang.crypt.bak

alking-mbp:src dev$ erl
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Eshell V10.2  (abort with ^G)
1> {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks("erlang_bullet_sup.beam",[abstract_code]).
** exception error: no match of right hand side value {error,beam_lib,
                                                             {key_missing_or_invalid,"erlang_bullet_sup.beam",
                                                                                     abstract_code}}
                                                                                     
% 有了 .erlang.crypt 文件又可以获得源代码了
mv ~/.erlang.crypt.bak ~/.erlang.crypt
alking-mbp:src dev$ erl
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Eshell V10.2  (abort with ^G)
1> {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks("erlang_bullet_sup.beam",[abstract_code]).
{ok,{erlang_bullet_sup,[{abstract_code,{raw_abstract_v1,[{attribute,1,
                                                                    file
......

$HOME/.hosts.erlang or $OTP_ROOT/.hosts.erlang

文件.hosts.erlang中每一行都是一个主机名称,如下

'super.eua.ericsson.se'.
'renat.eua.ericsson.se'.
'grouse.eua.ericsson.se'.
'gauffin1.eua.ericsson.se'.
...

在执行net_adm:world().自动与这些主机打通。详细内容请参考net_adm:world(). net_adm:host_file().

总结

在开发的日常生活中,可以利用一些特性灵活高效的实现一些功能。

上一篇下一篇

猜你喜欢

热点阅读