`
vanadiumlin
  • 浏览: 504940 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

erlang 代码安全

 
阅读更多

稍微深入研究过一点 java 的同学,恐怕都知道什么叫做 “反编译” 。也就是说,随便拿一个 class 文件,找一个 jad 来,所有的 “智慧结晶” 就全都 “真相大白” 了,跟原先的 source code 相比,区别只是没有注释而已。

对于开源软件开发者来说,这本是无所谓的事,但对于商业开发者而言,这简直就是噩梦。在 java 的世界,道高一尺魔高一丈(及其反复迭代)的结果是,这件事最终演变得比较诡异,以至于专门诞生了一个名叫 “代码混淆” 的产业。在我上一次关注的时候,这个领域的最新进展是可以 “混淆” 程序执行的流程,以至于正常的人类阅读反编译出来的源码,将会导致严重的脑残。不过,传说又出了个叫做 “流程优化器” 的东东……(这个故事未完待续)。

其实,这件事困扰的不仅只是 java ,几乎所有 “有源代码” 的程序都有这个烦恼。比如,饱受折磨的还有 php, asp 以及 .net。不知道有没有高人能从 “机器码” 反编译出 C 和 C++ 的源程序呢,反正我挺好奇的。不过,话说回来, “没有源代码” 的程序,恐怕还真的没有。保护源代码,在我们现如今 “处处是山寨,遍地是豺狼” 的产业现状之下,似乎仍然是个不得不认真对待的事情。

在源代码保护的问题上,Erlang 的表现又会如何?今天体验了一把,应该说,设计得很细致,至于说这样的设计是否能够完全杜绝源代码的泄露,这个问题恐怕仍然需要留给 “专家” 们去研究。好吧,口水就喷到这里,下面上干货。

目前这个阶段,对 Erlang 源代码的保护,主要是在 debug_info 上做手脚,因为,在 debug_info 里面有完整的源代码,可以极其轻松的从中 “找回” 源码(两个语句而已,在官方文档之中都有例子)。

先看如何从 Erlang 的 beam 文件获取源代码。象这样的一个简单程序:

-module(a).
 
-
export([test/0]).
 
test() ->
  
io:format("source code.~n"[]).

带 debug_info 编译,并运行之。

$ erlc +debug_info a.erl
$ erl -s a test -s c q -noshell
source code.
$

我们可以这样还原它的源码:

$ erl
1>  {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(code:which(a), abstract_code]).
{ok,{a,[{abstract_code,
            {raw_abstract_v1,
                [{attribute,1,file,{"./a.erl",1}},
                 {attribute,1,module,a},
                 {attribute,3,export,[{test,0}]},
                 {function,5,test,0,
                     [{clause,5,[],[],[{call,6,{remote,...},[...]}]}]},
                 {eof,7}]}}]}}
2> io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).
-file("./a.erl", 1).

-module(a).

-export([test/0]).

test() -> io:format("source code.~n", []).


ok
3>

看,和源码几乎完全一致。

那么,如果我们编译的时候不带 debug_info 呢?是的,完全可以。不过,如果你想要在这样的 beam 上执行 debugger 或者 xref 之类的动作,那么,没有 debug_info 就做不了。天知道我们会不会有需要做 “现场调试” 的时候呢。有没有既保留 debug_info 又阻止其他人通过 debug_info 来得到源码的办法呢?有,那就是——加密 debug_info 。

首先建立一个 ~/.erlang.crypt 文件,内容如下:

$ cat ~/.erlang.crypt
[{debug_info, des3_cbc, [], "my_source_code_secret_key"}].

这里的 “my_source_code_secret_key” 就被用来生成对 debug_info 加密的密钥。用 encrypt_debug_info 参数编译,并运行之。

$ erlc +encrypt_debug_info a.erl
$ erl -s a test -s c q -noshell
source code.

现在拿掉 ~/.erlang.crypt (模拟生产机环境),看看能否正常运行。

$ mv ~/.erlang.crypt ~/.erlang.old.crypt
$ erl -s a test -s c q -noshell
source code.

运行没问题。此时,是否还能还原源码呢。

$ erl
1>  beam_lib:chunks(code:which(a), [abstract_code]).
{error,beam_lib,
       {key_missing_or_invalid,"./a.beam",abstract_code}}

这正是我们想要的。

比如说,假如某日我们需要在这台生产机上做 “现场调试”,那就再加上 ~/.erlang.crypt 文件。作为验证,我们再执行一次还原源码的操作。

$ mv ~/.erlang.old.crypt ~/.erlang.crypt
$ erl
1>  {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(code:which(a), abstract_code]).
{ok,{a,[{abstract_code,
            {raw_abstract_v1,
                [{attribute,1,file,{"./a.erl",1}},
                 {attribute,1,module,a},
                 {attribute,3,export,[{test,0}]},
                 {function,5,test,0,
                     [{clause,5,[],[],[{call,6,{remote,...},[...]}]}]},
                 {eof,7}]}}]}}
2> io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).
-file("./a.erl", 1).

-module(a).

-export([test/0]).

test() -> io:format("source code.~n", []).


ok
3>

看 debug_info 还原出来了。

我们藏在 debug_info 中的源码是被 des3_cbc 算法保护起来的,有兴趣的童鞋可以去 wiki 百科了解它的加密强度,解开它的关键是 ~/.erlang.crypt 文件,只要它不泄露,那么在生产环境下,我们的代码就仍然是安全的,也就是说,就算这台机器被黑掉了,也还原不出源码(如果我说错了,请纠正我),而且只要你持有 .erlang.crypt 文件,(在需要的时候)仍然可以进行调试。

实验之前,确实没想到 Erlang 还设计了这么一个机制,挺细致的。需要说明的是,上述方案是对 beam 中的 debug_info 进行了加密,从而阻止其他人从中获取源码,至于是否还有其他的还原源码的可能,目前还不是很清楚。比如,理论上,是否有可能通过 beam 之中的 op code 反编译出原始的 source code 呢?对于这个话题,如果有童鞋知道,请不吝赐教。

 

分享到:
评论

相关推荐

    erlang代码热替换与应用部署

    beam模块是Erlang虚拟机(BEAM)的执行引擎,它负责解析和执行Erlang代码。代码服务器则管理Erlang系统的代码库,包括加载、替换和卸载代码等操作。 当需要进行代码热替换时,通常遵循以下步骤: 1. **准备新版本*...

    远古封神+英雄远征的ERLANG游戏服务器代码

    《远古封神》与《英雄远征》是两款受欢迎的网络游戏,它们的后端服务器采用了ERLANG这一编程语言来构建。ERLANG是一种为并发、分布式和容错系统设计的函数式编程语言,因其在实时系统和大规模并发处理中的优秀性能而...

    for_each_file 用erlang代码实现遍历文件

    在上述代码中,`for_each_file/2`首先列出目录中的所有文件,然后对每个文件调用`process_files/3`。`process_files/3`会打开每个文件,读取其内容,并对每一行调用`Callback`。当遇到错误或文件末尾时,它会关闭...

    rustler编写erlang nif

    - NIFs允许Erlang代码调用外部函数,这些函数由其他语言实现,通常用于性能优化。 - NIFs可以提高计算密集型任务的效率,但必须谨慎处理,因为它们可能会破坏Erlang的进程隔离和错误恢复机制。 2. **Rustler介绍*...

    erlang源码包

    Erlang是一种面向并发、分布式计算的编程语言,由瑞典电信设备制造商Ericsson为了...如果你正在使用这个版本,可能需要注意一些已知的问题和安全更新,对于新项目,建议使用更现代的版本,以获取更好的性能和安全性。

    erlang深度分析.pdf

    BEAM是Erlang的字节码解释器,模拟器可以用于开发阶段模拟运行和测试Erlang代码,有助于调试程序和优化性能。 #### 7. 内存管理 Erlang的内存管理是非常高效的,它使用了一种特殊的垃圾回收机制来确保低延迟。了解...

    erlang写的一个特别的web服务器

    总的来说,emongrel2是Erlang对Mongrel2的实现,它结合了Erlang的并发优势和Mongrel2的设计理念,旨在构建一个高性能、可扩展、安全的Web服务器。对于熟悉Erlang和想要在高并发场景下部署Web服务的开发者来说,这是...

    erlang nif test

    NIFs是Erlang与C交互的重要手段,它允许Erlang代码调用C函数,执行无法或不适合在Erlang虚拟机(VM)上进行的计算任务,比如硬件操作、加密算法或者高性能的数据处理。 创建一个Erlang NIF通常涉及以下几个步骤: ...

    erlang 21.3

    标签"erlang"、"linux"和"otp_src_21.3"明确了这个压缩包与Erlang语言、Linux操作系统以及OTP源代码版本21.3的关系。这意味着该压缩包是为Linux环境设计的,用户需要在Linux环境下编译和安装Erlang 21.3。 在Linux...

    Erlang程序设计(第2版)1

    书中详细介绍了如何设计和实现这样的分布式系统,包括如何确保节点间的通信安全和高效。此外,还讲解了分布式系统中常见的设计模式,帮助开发者构建可扩展且可靠的软件。 文件和网络编程是任何应用程序的基础。在...

    erlang 24.0版本 win64 位

    Erlang 24.0可能对这部分功能进行了优化,使得升级过程更加安全,减少了服务中断的风险。 在Windows 64位环境下,Erlang 24.0的安装包“otp_win64_24.0.exe”提供了完整的编译和运行环境。安装过程中,它会设置必要...

    Erlang深度分析

    Erlang代码的编写有着特定的最佳实践,比如避免共享状态、使用不可变数据结构以及利用模式匹配来简化代码逻辑。遵循这些最佳实践,不仅可以提高代码的可读性和可维护性,还有助于提升程序的并发性能。 #### 3. 工具...

    Erlang和RabbitMQ安装包

    Erlang是一种函数式编程语言,以其并发性、容错性和热代码升级能力而闻名,而RabbitMQ则是基于Erlang构建的一个开源消息代理,用于实现应用程序之间的异步通信。 **Erlang** Erlang由瑞典电信设备制造商Ericsson...

    Erlang的高级特性和应用

    - 编译器:负责将Erlang代码编译为opcode - 库:包含各种标准模块和函数 - VM + 基本库:Erlang虚拟机及基础库,用C编写 - 调试器:帮助开发者调试Erlang程序 - Profile:性能分析工具 - 工具集:提供各种开发辅助...

    RabbitMQ3.9.13和ErLang24.2版本

    2. **容错性**:Erlang的错误恢复机制和热代码升级功能使得Erlang程序能在出现错误时优雅地重启,而不影响整个系统。这对于保持RabbitMQ的稳定性至关重要。 3. **分布式特性**:Erlang的分布式特性使得构建分布式...

    Erlang安装包

    在Erlang中,新代码可以逐步加载到运行中的系统中,而不必一次性替换所有代码。这样可以逐步引入新功能,同时避免因整个系统替换带来的风险。 此外,Erlang还提供了丰富的外部接口,使其能够与各种其他语言和系统...

    erlang21.0源码

    在你提供的资料中,“erlang21.0源码”指的是Erlang编程语言的第21个主要版本的源代码,这对于我们深入理解Erlang的内部工作机制,以及学习如何构建基于Erlang的系统是非常有价值的。 OTP_src_21.0是Erlang/OTP ...

    erlang server源码

    Erlang代码通常按照模块来组织,每个模块包含一系列相关功能的函数。在echatServer中,可能会有如`user_management`、`message_routing`等模块,分别负责用户管理和消息路由。 3. **行为模式(Behavior)** ...

    erlang 深度分析

    - **实现**: 利用Erlang的代码加载机制实现代码的热更新。 - **应用场景**: 生产环境中进行无停机维护。 #### 10. 查看Erlang内存使用情况 - **工具**: `observer`和`sys`提供了丰富的内存监控功能。 - **指标**: ...

    erlang 24.0 龙芯 loongarch64 预编译版本

    由于Erlang官方不直接提供针对龙芯处理器的二进制包,这意味着这个预编译版本是由开发者或社区成员使用Erlang 24的源代码,在龙芯3A5000处理器上进行编译的,以适应该架构的硬件特性。 描述中提到,“解压缩以后将...

Global site tag (gtag.js) - Google Analytics