|
|
@ -3,6 +3,8 @@ |
|
|
|
-export([ |
|
|
|
genSrc/2 |
|
|
|
, genSrcs/2 |
|
|
|
, notCan/2 |
|
|
|
, reToDir/2 |
|
|
|
]). |
|
|
|
|
|
|
|
%% 通过beam生成erl文件,生成的beam编译选项必要带debug_info才能反编译生成代码 |
|
|
@ -23,28 +25,69 @@ genSrc(Module, SrcDir) -> |
|
|
|
|
|
|
|
%% 通过beam生成erl文件,生成的beam编译选项必要带debug_info才能反编译生成代码 |
|
|
|
genSrcs(BeamDir, SrcDir) -> |
|
|
|
FunRead = |
|
|
|
FunDeal = |
|
|
|
fun(File, ProAcc) -> |
|
|
|
case filename:extension(File) == ".beam" of |
|
|
|
true -> |
|
|
|
ModName = filename:basename(File, ".beam"), |
|
|
|
Module = list_to_atom(ModName), |
|
|
|
case beam_lib:chunks(code:which(Module), [abstract_code]) of |
|
|
|
{ok, {_, [{abstract_code, {_, AC}}]}} -> |
|
|
|
Code = erl_prettypr:format(erl_syntax:form_list(AC)), |
|
|
|
%% 如果代码中有unicode码 需要下面的函数转换一下 第二个函数效率更高 |
|
|
|
%% SrcStr = io_lib:fwrite("~ts~n", [erl_prettypr:format(erl_syntax:form_list(AC))]), |
|
|
|
SrcBin = unicode:characters_to_binary(Code), |
|
|
|
file:write_file(lists:concat([SrcDir, Module, ".erl"]), SrcBin), |
|
|
|
io:format("build beam:~p to erl:~p success.~n", [Module, Module]); |
|
|
|
{error, beam_lib, Reason} -> |
|
|
|
io:format("code_gen_erl_file error, reason:~p~n", [Reason]); |
|
|
|
_Err -> |
|
|
|
io:format("code_gen_erl_file error, reason:~p~n", [_Err]) |
|
|
|
end, |
|
|
|
ModName = filename:basename(File, ".beam"), |
|
|
|
Module = list_to_atom(ModName), |
|
|
|
case beam_lib:chunks(code:which(Module), [abstract_code]) of |
|
|
|
{ok, {_, [{abstract_code, {_, AC}}]}} -> |
|
|
|
Code = erl_prettypr:format(erl_syntax:form_list(AC)), |
|
|
|
%% 如果代码中有unicode码 需要下面的函数转换一下 第二个函数效率更高 |
|
|
|
%% SrcStr = io_lib:fwrite("~ts~n", [erl_prettypr:format(erl_syntax:form_list(AC))]), |
|
|
|
SrcBin = unicode:characters_to_binary(Code), |
|
|
|
file:write_file(lists:concat([SrcDir, Module, ".erl"]), SrcBin), |
|
|
|
io:format("build beam:~p to erl:~p success.~n", [Module, Module]); |
|
|
|
{error, beam_lib, Reason} -> |
|
|
|
io:format("code_gen_erl_file error, reason:~p~n", [Reason]); |
|
|
|
_Err -> |
|
|
|
io:format("code_gen_erl_file error, reason:~p~n", [_Err]) |
|
|
|
end, |
|
|
|
ProAcc |
|
|
|
end, |
|
|
|
filelib:fold_files(BeamDir, "\\.beam$", true, FunDeal, []). |
|
|
|
|
|
|
|
%% 将不能反编译的beam文件复制到指定的目录 |
|
|
|
notCan(BeamDir, SrcDir) -> |
|
|
|
FunDeal = |
|
|
|
fun(File, ProAcc) -> |
|
|
|
ModName = filename:basename(File, ".beam"), |
|
|
|
Module = list_to_atom(ModName), |
|
|
|
case beam_lib:chunks(code:which(Module), [abstract_code]) of |
|
|
|
{ok, {_, [{abstract_code, {_, _AC}}]}} -> |
|
|
|
ProAcc; |
|
|
|
{error, beam_lib, Reason} -> |
|
|
|
io:format("code_gen_erl_file error, reason:~p~n", [Reason]), |
|
|
|
file:copy(File, lists:concat([SrcDir, ModName, ".beam"])); |
|
|
|
_Err -> |
|
|
|
io:format("code_gen_erl_file error, reason:~p~n", [_Err]), |
|
|
|
file:copy(File, lists:concat([SrcDir, ModName, ".beam"])) |
|
|
|
end, |
|
|
|
ProAcc |
|
|
|
end, |
|
|
|
filelib:fold_files(BeamDir, "\\.beam$", true, FunDeal, []). |
|
|
|
|
|
|
|
%% 将反编译的文件根据最前面的-file信息 重新复制到正确的目录 |
|
|
|
reToDir(SSrcDir, DSrcDir) -> |
|
|
|
FunDeal = |
|
|
|
fun(File, ProAcc) -> |
|
|
|
case file:read_file(File) of |
|
|
|
{ok, <<"-file(", _/binary>> = BinStr} -> |
|
|
|
case binary:split(BinStr, <<"-module">>) of |
|
|
|
[AllFileInfo, _] -> |
|
|
|
FileInfo = binary:replace(AllFileInfo, [<<" ">>, <<"\n">>, <<"\"">>], <<"">>, [global]), |
|
|
|
[_, LeftFileInfo] = binary:split(FileInfo, <<"(">>), |
|
|
|
[DirInfo, _] = binary:split(LeftFileInfo, <<",">>), |
|
|
|
FileDir = filename:join(DSrcDir, DirInfo), |
|
|
|
filelib:ensure_dir(FileDir), |
|
|
|
{ok, _} = file:copy(File, FileDir), |
|
|
|
ok; |
|
|
|
_ -> |
|
|
|
ProAcc |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
ProAcc |
|
|
|
end |
|
|
|
end, |
|
|
|
filelib:fold_files(BeamDir, "\\.beam$", true, FunRead, []). |
|
|
|
filelib:fold_files(SSrcDir, "\\.erl$", true, FunDeal, []). |
|
|
|
|
|
|
|
%% 还可以根据反编译的内容恢复头文件 暂时没这个需求 |