11mod edit_distance;
22
3- use gimli:: {
4- constants,
5- write:: {
6- Address , AttributeValue , DwarfUnit , EndianVec , Expression , Range , RangeList , Sections ,
7- UnitEntryId ,
8- } ,
9- } ;
10- use object:: { write, Architecture , BinaryFormat , SectionKind } ;
11- use std:: fs;
12-
3+ use binaryninja:: interaction:: form:: { Form , FormInputField } ;
134use binaryninja:: logger:: Logger ;
145use binaryninja:: {
156 binary_view:: { BinaryView , BinaryViewBase , BinaryViewExt } ,
167 command:: { register_command, Command } ,
178 confidence:: Conf ,
18- interaction,
19- interaction:: { FormResponses , FormResponses :: Index } ,
209 rc:: Ref ,
2110 symbol:: SymbolType ,
2211 types:: { MemberAccess , StructureType , Type , TypeClass } ,
2312} ;
13+ use gimli:: {
14+ constants,
15+ write:: {
16+ Address , AttributeValue , DwarfUnit , EndianVec , Expression , Range , RangeList , Sections ,
17+ UnitEntryId ,
18+ } ,
19+ } ;
2420use log:: { error, info, LevelFilter } ;
21+ use object:: { write, Architecture , BinaryFormat , SectionKind } ;
22+ use std:: fs;
23+ use std:: path:: { Path , PathBuf } ;
2524
2625fn export_type (
2726 name : String ,
@@ -598,10 +597,11 @@ fn export_data_vars(
598597 }
599598}
600599
601- fn present_form ( bv_arch : & str ) -> Vec < FormResponses > {
602- // TODO : Verify inputs (like save location) so that we can fail early
603- // TODO : Add Language field
604- // TODO : Choose to export types/functions/etc
600+ // TODO : Verify inputs (like save location) so that we can fail early
601+ // TODO : Add Language field
602+ // TODO : Choose to export types/functions/etc
603+ // TODO: Add actual / better support for formats other than elf?
604+ fn create_export_form ( bv_arch : & str ) -> Form {
605605 let archs = [
606606 "Unknown" ,
607607 "AArch64" ,
@@ -627,80 +627,37 @@ fn present_form(bv_arch: &str) -> Vec<FormResponses> {
627627 "Wasm32" ,
628628 "Xtensa" ,
629629 ] ;
630- interaction:: FormInputBuilder :: new ( )
631- . save_file_field (
632- "Save Location" ,
633- Some ( "Debug Files (*.dwo *.debug);;All Files (*)" ) ,
634- None ,
635- None ,
636- )
637- . choice_field (
638- "Architecture" ,
639- & archs,
640- archs
641- . iter ( )
642- . enumerate ( )
643- . min_by ( |& ( _, arch_name_1) , & ( _, arch_name_2) | {
644- edit_distance:: distance ( bv_arch, arch_name_1)
645- . cmp ( & edit_distance:: distance ( bv_arch, arch_name_2) )
646- } )
647- . map ( |( index, _) | index) ,
648- )
649- // Add actual / better support for formats other than elf?
650- // .choice_field(
651- // "Container Format",
652- // &["Coff", "Elf", "MachO", "Pe", "Wasm", "Xcoff"],
653- // None,
654- // )
655- . get_form_input ( "Export as DWARF" )
630+
631+ let mut form = Form :: new ( "Export as DWARF" ) ;
632+ form. add_field ( FormInputField :: SaveFileName {
633+ prompt : "Save Location" . to_string ( ) ,
634+ extension : Some ( "Debug Files (*.dwo *.debug);;All Files (*)" . to_string ( ) ) ,
635+ default_name : None ,
636+ default : None ,
637+ value : None ,
638+ } ) ;
639+ form. add_field ( FormInputField :: Choice {
640+ prompt : "Architecture" . to_string ( ) ,
641+ choices : archs. iter ( ) . map ( |arch| arch. to_string ( ) ) . collect ( ) ,
642+ default : archs
643+ . iter ( )
644+ . enumerate ( )
645+ . min_by ( |& ( _, arch_name_1) , & ( _, arch_name_2) | {
646+ edit_distance:: distance ( bv_arch, arch_name_1)
647+ . cmp ( & edit_distance:: distance ( bv_arch, arch_name_2) )
648+ } )
649+ . map ( |( index, _) | index) ,
650+ value : 0 ,
651+ } ) ;
652+ form
656653}
657654
658655fn write_dwarf < T : gimli:: Endianity > (
659- responses : Vec < FormResponses > ,
656+ file_path : & Path ,
657+ arch : Architecture ,
660658 endian : T ,
661659 dwarf : & mut DwarfUnit ,
662660) {
663- if responses. len ( ) < 2 {
664- return ;
665- }
666-
667- let arch = match responses[ 1 ] {
668- Index ( 0 ) => Architecture :: Unknown ,
669- Index ( 1 ) => Architecture :: Aarch64 ,
670- Index ( 2 ) => Architecture :: Aarch64_Ilp32 ,
671- Index ( 3 ) => Architecture :: Arm ,
672- Index ( 4 ) => Architecture :: Avr ,
673- Index ( 5 ) => Architecture :: Bpf ,
674- Index ( 6 ) => Architecture :: I386 ,
675- Index ( 7 ) => Architecture :: X86_64 ,
676- Index ( 8 ) => Architecture :: X86_64_X32 ,
677- Index ( 9 ) => Architecture :: Hexagon ,
678- Index ( 10 ) => Architecture :: LoongArch64 ,
679- Index ( 11 ) => Architecture :: Mips ,
680- Index ( 12 ) => Architecture :: Mips64 ,
681- Index ( 13 ) => Architecture :: Msp430 ,
682- Index ( 14 ) => Architecture :: PowerPc ,
683- Index ( 15 ) => Architecture :: PowerPc64 ,
684- Index ( 16 ) => Architecture :: Riscv32 ,
685- Index ( 17 ) => Architecture :: Riscv64 ,
686- Index ( 18 ) => Architecture :: S390x ,
687- Index ( 19 ) => Architecture :: Sbf ,
688- Index ( 20 ) => Architecture :: Sparc64 ,
689- Index ( 21 ) => Architecture :: Wasm32 ,
690- Index ( 22 ) => Architecture :: Xtensa ,
691- _ => Architecture :: Unknown ,
692- } ;
693-
694- // let format = match responses[2] {
695- // Index(0) => BinaryFormat::Coff,
696- // Index(1) => BinaryFormat::Elf,
697- // Index(2) => BinaryFormat::MachO,
698- // Index(3) => BinaryFormat::Pe,
699- // Index(4) => BinaryFormat::Wasm,
700- // Index(5) => BinaryFormat::Xcoff,
701- // _ => BinaryFormat::Elf,
702- // };
703-
704661 // TODO : Look in to other options (mangling, flags, etc (see Object::new))
705662 let mut out_object = write:: Object :: new (
706663 BinaryFormat :: Elf ,
@@ -738,16 +695,14 @@ fn write_dwarf<T: gimli::Endianity>(
738695 } )
739696 . unwrap ( ) ;
740697
741- if let interaction:: FormResponses :: String ( filename) = & responses[ 0 ] {
742- if let Ok ( out_data) = out_object. write ( ) {
743- if let Err ( err) = fs:: write ( filename, out_data) {
744- error ! ( "Failed to write DWARF file: {}" , err) ;
745- } else {
746- info ! ( "Successfully saved as DWARF to `{}`" , filename) ;
747- }
698+ if let Ok ( out_data) = out_object. write ( ) {
699+ if let Err ( err) = fs:: write ( file_path, out_data) {
700+ error ! ( "Failed to write DWARF file: {}" , err) ;
748701 } else {
749- error ! ( "Failed to write DWARF with requested settings" ) ;
702+ info ! ( "Successfully saved as DWARF to `{:?}`" , file_path ) ;
750703 }
704+ } else {
705+ error ! ( "Failed to write DWARF with requested settings" ) ;
751706 }
752707}
753708
@@ -757,7 +712,42 @@ fn export_dwarf(bv: &BinaryView) {
757712 } else {
758713 String :: from ( "Unknown" )
759714 } ;
760- let responses = present_form ( arch_name. as_str ( ) ) ;
715+ let mut export_form = create_export_form ( arch_name. as_str ( ) ) ;
716+ if !export_form. prompt ( ) {
717+ return ;
718+ }
719+
720+ let arch_field = export_form. get_field_with_name ( "Architecture" ) . unwrap ( ) ;
721+ let arch_field_idx = arch_field. try_value_index ( ) . unwrap_or_default ( ) ;
722+ let arch = match arch_field_idx {
723+ 0 => Architecture :: Unknown ,
724+ 1 => Architecture :: Aarch64 ,
725+ 2 => Architecture :: Aarch64_Ilp32 ,
726+ 3 => Architecture :: Arm ,
727+ 4 => Architecture :: Avr ,
728+ 5 => Architecture :: Bpf ,
729+ 6 => Architecture :: I386 ,
730+ 7 => Architecture :: X86_64 ,
731+ 8 => Architecture :: X86_64_X32 ,
732+ 9 => Architecture :: Hexagon ,
733+ 10 => Architecture :: LoongArch64 ,
734+ 11 => Architecture :: Mips ,
735+ 12 => Architecture :: Mips64 ,
736+ 13 => Architecture :: Msp430 ,
737+ 14 => Architecture :: PowerPc ,
738+ 15 => Architecture :: PowerPc64 ,
739+ 16 => Architecture :: Riscv32 ,
740+ 17 => Architecture :: Riscv64 ,
741+ 18 => Architecture :: S390x ,
742+ 19 => Architecture :: Sbf ,
743+ 20 => Architecture :: Sparc64 ,
744+ 21 => Architecture :: Wasm32 ,
745+ 22 => Architecture :: Xtensa ,
746+ _ => Architecture :: Unknown ,
747+ } ;
748+
749+ let save_loc_field = export_form. get_field_with_name ( "Save Location" ) . unwrap ( ) ;
750+ let save_loc_path = PathBuf :: from ( save_loc_field. try_value_string ( ) . unwrap_or_default ( ) ) ;
761751
762752 let encoding = gimli:: Encoding {
763753 format : gimli:: Format :: Dwarf32 ,
@@ -782,9 +772,9 @@ fn export_dwarf(bv: &BinaryView) {
782772 // TODO: Sections? Segments?
783773
784774 if bv. default_endianness ( ) == binaryninja:: Endianness :: LittleEndian {
785- write_dwarf ( responses , gimli:: LittleEndian , & mut dwarf) ;
775+ write_dwarf ( & save_loc_path , arch , gimli:: LittleEndian , & mut dwarf) ;
786776 } else {
787- write_dwarf ( responses , gimli:: BigEndian , & mut dwarf) ;
777+ write_dwarf ( & save_loc_path , arch , gimli:: BigEndian , & mut dwarf) ;
788778 } ;
789779}
790780
0 commit comments