From 657db241829ea41e5a5694ed0a740dd0d0cfa909 Mon Sep 17 00:00:00 2001 From: SisMaker <1713699517@qq.com> Date: Sun, 12 Feb 2023 14:50:55 +0800 Subject: [PATCH] =?UTF-8?q?ft:=20=E5=8F=8D=E7=BC=96=E8=AF=91=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compile/utBeamToSrc.erl | 81 ++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/src/compile/utBeamToSrc.erl b/src/compile/utBeamToSrc.erl index baa7a5d..bb0a6d0 100644 --- a/src/compile/utBeamToSrc.erl +++ b/src/compile/utBeamToSrc.erl @@ -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, []). \ No newline at end of file + filelib:fold_files(SSrcDir, "\\.erl$", true, FunDeal, []). + +%% 还可以根据反编译的内容恢复头文件 暂时没这个需求 \ No newline at end of file