Erlang代码反编译以及查看汇编码

标签: Erlang探索 abstract_code erlc erl_syntax erts_debug | 发表时间:2011-10-02 00:46 | 作者:Yu Feng KnightE
出处:http://blog.yufeng.info

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: Erlang代码反编译以及查看汇编码

Erlang的代码是先翻译成abstract_code,再到目标代码的,如果有符号信息很容易恢复源代码,通常我们部署系统的时候需要把符号信息去掉,reltool就可以干这个事情!

我们演示下:

$ cat server.erl
-module(server).
-compile(export_all).

start() ->
    start(1234).

start(Port) ->
    register(?MODULE, self()),

    spawn_link(fun ()-> S= listen(Port), accept(S) end),

    receive Any -> io:format("~p~n", [Any]) end.  %% to stop: test!stop.

listen(Port) ->
    Opts = [{active, false},
            binary,
            {backlog, 256},
            {packet, raw},
            {reuseaddr, true}],
    {ok, S} = gen_tcp:listen(Port, Opts),
    S.

accept(S) ->
    case gen_tcp:accept(S) of
        {ok, Socket} -> spawn_opt(?MODULE, loop, [Socket,0], []);
        Error    -> erlang:error(Error)
    end,
    accept(S).

loop(S, N) ->
    case gen_tcp:recv(S, 1024) of
        {ok, _Data} ->
	    io:format("~p got ~w, ~w~n",[S, size(_Data), N]),
	    timer:sleep(100),
            loop(S, N+1);

        Error ->
            io:format("tcp ~p~n", [Error]),
            Error
    end.
$ erlc +debug_info server.erl
$ erl
Erlang R14B04 (erts-5.8.5) 1 [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.5  (abort with ^G)
1> f(),{ok, {_, [{abstract_code, {_,Abs}}]}} =  beam_lib:chunks("server.beam", [abstract_code]),io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(Abs))]).
-file("./server.erl", 1).

-module(server).

-compile(export_all).

start() -> start(1234).

start(Port) ->
    register(server, self()),
    spawn_link(fun () -> S = listen(Port), accept(S) end),
    receive Any -> io:format("~p~n", [Any]) end.

listen(Port) ->
    Opts = [{active, false}, binary, {backlog, 256},
            {packet, raw}, {reuseaddr, true}],
    {ok, S} = gen_tcp:listen(Port, Opts),
    S.

accept(S) ->
    case gen_tcp:accept(S) of
      {ok, Socket} ->
          spawn_opt(server, loop, [Socket, 0], []);
      Error -> erlang:error(Error)
    end,
    accept(S).

loop(S, N) ->
    case gen_tcp:recv(S, 1024) of
      {ok, _Data} ->
          io:format("~p got ~w, ~w~n", [S, size(_Data), N]),
          timer:sleep(100),
          loop(S, N + 1);
      Error -> io:format("tcp ~p~n", [Error]), Error
    end.

ok
2>

想查看模块的汇编码,也很容易,这样就好:

$ erl
Erlang R14B04 (erts-5.8.5) 1 [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.5  (abort with ^G)
1> erts_debug:df(server).
ok
2> 

$ cat server.dis
0117F108: i_func_info_IaaI 0 server start 0
0117F11C: i_move_call_only_fcr server:start/1 1234 x(0) 

0117F128: i_func_info_IaaI 0 server start 1
0117F13C: allocate_zero_tt 1 1
0117F144: self_x x(1)
0117F14C: move_ry x(0) y(0)
0117F154: move_cr server x(0)
0117F15C: call_bif2_e erlang:register/2
0117F164: move_yr y(0) x(0)
0117F16C: i_make_fun_It 18102836 1
0117F178: init_y y(0)
0117F180: i_call_ext_e erlang:spawn_link/1
0117F188: i_loop_rec_fr f(0117F1B8) x(0)
0117F190: remove_message
0117F194: test_heap_It 2 1
0117F1A0: put_list_rnx x(0) [] x(1)
0117F1A8: i_move_call_ext_last_ePcr io:format/2 1 "~p~n" x(0)
0117F1B8: wait_locked_f f(0117F188) 

0117F1C0: i_func_info_IaaI 0 server listen 1
0117F1D4: allocate_tt 0 1
0117F1DC: move_x1_c [{active,false},binary,{backlog,256},{packet,raw},{reuseaddr,true}]
0117F1E4: i_call_ext_e gen_tcp:listen/2
0117F1EC: is_tuple_of_arity_frA f(0117F218) x(0) 2
0117F1F8: extract_next_element2_x x(1)
0117F200: i_is_eq_exact_immed_fxc f(0117F218) x(1) ok
0117F210: move_deallocate_return_xrQ x(2) x(0) 0
0117F218: badmatch_r x(0) 

0117F21C: i_func_info_IaaI 0 server accept 1
0117F230: allocate_tt 1 1
0117F238: move_ry x(0) y(0)
0117F240: i_call_ext_e gen_tcp:accept/1
0117F248: is_tuple_of_arity_frA f(0117F2AC) x(0) 2
0117F254: extract_next_element2_x x(1)
0117F25C: i_is_eq_exact_immed_fxc f(0117F2AC) x(1) ok
0117F26C: test_heap_It 2 3
0117F278: put_list_xcx x(2) [0] x(2)
0117F284: move_x1_c loop
0117F28C: move_nx [] x(3)
0117F294: i_move_call_ext_cre server x(0) erlang:spawn_opt/4
0117F2A0: move_call_last_yrfQ y(0) x(0) server:accept/1 1
0117F2AC: call_bif1_e erlang:error/1 

0117F2B4: i_func_info_IaaI 0 server loop 2
0117F2C8: allocate_tt 2 2
0117F2D0: move_xy x(1) y(0)
0117F2D8: move_x1_c 1024
0117F2E0: move_ry x(0) y(1)
0117F2E8: i_call_ext_e gen_tcp:recv/2
0117F2F0: is_tuple_of_arity_frA f(0117F388) x(0) 2
0117F2FC: extract_next_element2_x x(1)
0117F304: i_is_eq_exact_immed_fxc f(0117F388) x(1) ok
0117F314: i_gc_bif1_jIsId j(00000000) 151104 x(2) 3 x(0)
0117F32C: test_heap_It 6 3
0117F338: put_list_ynx y(0) [] x(2)
0117F340: put_list_rxr x(0) x(2) x(0)
0117F348: put_list_yrx y(1) x(0) x(1)
0117F350: i_move_call_ext_cre "~p got ~w, ~w~n" x(0) io:format/2
0117F35C: i_move_call_ext_cre 100 x(0) timer:sleep/1
0117F368: i_increment_yIId y(0) 1 0 x(1)
0117F37C: move_call_last_yrfQ y(1) x(0) server:loop/2 2
0117F388: test_heap_It 2 1
0117F394: move_ry x(0) y(1)
0117F39C: put_list_ynx y(1) [] x(1)
0117F3A4: i_trim_I 1
0117F3AC: i_move_call_ext_cre "tcp ~p~n" x(0) io:format/2
0117F3B8: move_deallocate_return_yrQ y(0) x(0) 1 

0117F3C0: i_func_info_IaaI 0 server module_info 0
0117F3D4: move_cr server x(0)
0117F3DC: allocate_tt 0 1
0117F3E4: call_bif1_e erlang:get_module_info/1
0117F3EC: deallocate_return_Q 0 

0117F3F4: i_func_info_IaaI 0 server module_info 1
0117F408: move_rx x(0) x(1)
0117F410: move_cr server x(0)
0117F418: allocate_tt 0 2
0117F420: call_bif2_e erlang:get_module_info/2
0117F428: deallocate_return_Q 0 

0117F430: i_func_info_IaaI 0 server '-start/1-fun-0-' 1
0117F444: allocate_tt 0 1
0117F44C: i_call_f server:listen/1
0117F454: i_call_last_fP server:accept/1 0

了解更多汇编码,请参考这里

祝玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

相关 [erlang 代码 编译] 推荐:

让Erlang自动编译并加载代码

- Andy - Intridea East Blog
最近参与的项目使用了ejabberd,得此锲机第一次接触了Erlang. 作为一个函数式编程语言(functional language),除了函数式语言本身特点之外, 因为Erlang是为分布式,高并发,高容错系统量身设计的,所以也有一些属于自己的独门秘籍. 譬如热更新(hot swapping): 系统可以在运行过程中替换部分代码,更神奇的是,新旧代码还可以部分共存.

Erlang代码反编译以及查看汇编码

- KnightE - Erlang非业余研究
原创文章,转载请注明: 转载自Erlang非业余研究. 本文链接地址: Erlang代码反编译以及查看汇编码. Erlang的代码是先翻译成abstract_code,再到目标代码的,如果有符号信息很容易恢复源代码,通常我们部署系统的时候需要把符号信息去掉,reltool就可以干这个事情. 想查看模块的汇编码,也很容易,这样就好:.

《Erlang编程指南》读后感

- David Ruan - Tim[后端技术]
在云时代,我们需要有更好的能利用多核功能及分布式能力的编程语言,Erlang在这方面具有天生的优势,因此我们始终对它保持强烈关注. 按:此为客座文章,投稿人为新浪微博基础研发工程师赵鹏城(http://weibo.com/iamzpc),以下为原文. 在对一个分布式KV存储系统的研究过程中,我有幸遇到了Erlang语言.

Erlang监测系统CPU、内存、磁盘

- chuang - Jobin的主页
Erlang的os_mon服务中提供了一些用于监测系统信息的服务. cpu_sup:监测CPU负载和使用率(Unix). disksup:监测磁盘(Unix、Windows). memsup:监测内存(Unix、Windows、VxWorks). os_sup:监测系统日志(Solaris、Windows).

Erlang十分钟快速入门

- - 水煮沉浮
Erlang概述Erlang不但是一种编程语言,而且它具有比编程语言更加贴近操作系统的一些特性:并发线程、作业调度、内存管理、分布式、网络化等. 据说使用Erlang编写的Yaws Web服务器,其并发性能是apache的15倍. 这个Erlang初始开源版本包含了Erlang的实现,同时它也是用于构建分布式高可用性系统的Ericsson中间件的最大组成部分.

whatsapp深度使用Erlang有感

- - 系统技术非业余研究
原创文章,转载请注明: 转载自 系统技术非业余研究. whatsapp深度使用Erlang有感. 这么多年过去了,社区还在讨论erlang是不是小众语言,各种怀疑的时候,whatsapp已经把erlang用到了极致. 更为搞笑的是 主要开发者Rick Reed([email protected]),之前在Yahoo!, SGI工作,有着深厚的系统性能的背景.

Erlang进程堆垃圾回收机制

- - CSDN博客推荐文章
原文: Erlang进程堆垃圾回收机制. 作者:http://blog.csdn.net/mycwq. 每个Erlang进程创建之后都会有自己的PCB,栈,私有堆. erlang不知道他创建的进程会用到哪种场合下,所以一开始分配的内存比较小. 如果分配的空间不够了,erlang gc会动态调整堆大小以满足需求,如果分配的空间大了,就会收缩堆,回收内存.

Android 4.0编译源代码需要16GB内存

- coofucoo - Solidot
新一代的智能手机也许更轻更小巧,但它们的操作系统则走向另一个极端. Android 4.0 Ice Cream Sandwich(ICS)编译源代码将需要工作站内存不低于16GB,是编译Gingerbread的两倍. 如果开发者想编译ICS,他需要准备:单次构建需25GB空间,同时编译所有AOSP(Android Open Source Project)配置需要80GB空间,16GB以上内存,在二个四核处理器2.4GHz机器上完成单次构建需5+小时CPU时间,经过时间(wall time)25+分钟.

Ubunut 12.10 64位编译 android 4.2.1_r1 源代码

- - C++博客_首页
google推荐的编译环境是在Ubuntu LTS(10.04),但是最新版本12.10已经出来,没必要在旧版本上做文章了. 对于2.3.X和更新的版本,需要64位的系统,之前的老版本2.2以下(包括2.2)可以在32位版本上编译. 对于虚拟机,官网上写的虚拟机配置参数:16G RAM/swap & 30G+ 硬盘空间.