123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696letmc_man={|
# DESCRIPTION
Disassembles a (human readable) string of bytes. This command is the
BAP machine code playground, which is intended to mimic a subset of
llvm-mc functionality, using the BAP disassembly backend. The main
use case is to explore various information associated with the
dissasembled instruction.
# EXAMPLES
The following input formats are supported:
```
0x31 0xd2 0x48 0xf7 0xf3
\\\\x31\\\\xd2\\\\x48\\\\xf7\\\\xf3
31 d2 48 f7 f3
31d248f7f3";
```
# SETTING ARCHITECHTURE
The target architecture is controlled by several groups of options
that can not be used together:
- $(b,arch);
- $(b,target) and $(b,encoding);
- $(b,triple), $(b,backend), $(b,cpu), $(b,bits), and $(b,order).
The $(b,arch) option provides the least control but is easiest to
use. It relies on the dependency-injection mechanism and lets the
target support packages (plugins that implement support for the given
architecture) do their best to guess the target and encoding that
matches the provided name. Use the common names for the architecture
and it should work. You can use the $(b,bits) and $(b,order) options
to give more hints to the target support packages. They default to
$(b,32) and $(b,little) correspondingly.
The $(b,target) and $(b,encoding) provides precise control over the
selection of the target and the encoding that is used to represent
machine instructions. The $(b,encoding) field can be omitted and will
be deduced from the target. Use $(b, bap list targets) and
$(b, bap list encodings) to get the list of supported targets and
encodings respectivly.
Finally, the $(b,triple), $(b,backend), $(b,cpu),... group of options
provides the full control over the disassembler backend and bypasses
the dependency-injection mechanism to pass the specified options
directly to the corresponding backends. This enables disassembling of
targets and encodings that are not yet supported by BAP. The meanings
of the options totally depend on the selected $(b,backend) and they
are passed as is to the corresponding arguments of the
$(b,Disasm_expert.Basic.create) function. The $(b,bits) and $(b,order)
defaults to $(b,32) and $(b,little) corresondingly and are used to
specify the number of bits in the target's addresses and the order of
bytes in the word. This group of options is useful during the
implementation and debugging of new targets and thus is reserved for
experts. Note, when this group is used the semantics of the instructions
will not be provided as it commonly requires the target specification.
|}letobjdump_man={|
# DESCRIPTION
Disassembles and prints a binary using the linear sweep algorithm.
This command is a sibling to the $(b,mc) command, except
that it takes a binary file as an input. If the binary contains only
raw code (i.e., no meta information), then use the $(b,raw) loader.
# EXAMPLES
```
bap objdump /bin/ls --show-asm
bap objdump ./code --loader=raw
```
|}openCore_kernelopenFormatopenRegular.StdopenBap.StdopenBap_plugins.StdopenBap_core_theoryopenBap_mainopenResult.Monad_infixtypeerror=|Bad_user_input|Bad_insnofmem*int*int|Create_memofError.t|No_input|Invalid_baseofstring|Trailing_dataofint|InconsistencyofKB.conflict|Unknown_formatofstring*string*stringlist|No_formats_expectedofstring|Disassembler_failedofError.t|Loader_failedofError.t|Target_must_be_unknown|Encoding_must_be_unknown|Triple_must_not_be_set|Arch_must_not_be_set|Backend_must_not_be_set|Cpu_must_not_be_set|Bits_must_not_be_set|Order_must_not_be_settypeExtension.Error.t+=Failoferrortypeoutput=[|`insn|`bil|`bir|`sema|`kinds|`size|`invalid|`addr|`memory|`knowledge][@@derivingcompare,enumerate]typetarget=|Targetof{name:Theory.Target.t;encoding:Theory.Language.t;}|Tripleof{name:string;backend:stringoption;cpu:stringoption;order:endian;bits:int;}letfailerr=Error(Failerr)letenabled="enabled"moduleSpec=structopenExtensionletinput=Command.argumentsType.stringletfile=Command.argumentType.fileletlanguage=Type.define~parse:(Theory.Language.read~package:"bap")~print:Theory.Language.to_stringTheory.Language.unknownlettarget=Type.define~parse:(Theory.Target.get~package:"bap")~print:Theory.Target.to_stringTheory.Target.unknownletorder=Type.enum["big",BigEndian;"little",LittleEndian;]letarch=Command.parameterType.(somestring)"arch"~aliases:["a"]~doc:"The target architecture."lettarget=Command.parametertarget"target"~aliases:["t"]~doc:"The target name."letencoding=Command.parameterlanguage"encoding"~aliases:["e"]~doc:"The target encoding."lettriple=Command.parameterType.(somestring)"triple"~doc:"The target triple."letcpu=Command.parameterType.(somestring)"cpu"~doc:"The target CPU (used with triple)."letbits=Command.parameterType.(someint)"bits"~doc:"The number of bits in the address \
(used with triple or arch)"letorder=Command.parameterType.(someorder)"order"~doc:"The order of bytes in the target's word \
(used with triple or arch)."letoutputs:(output,stringlist)List.Assoc.tExtension.Command.param=letname_of_output=function|`insn->"insn"|`bil->"bil"|`bir->"bir"|`sema->"sema"|`kinds->"kinds"|`size->"size"|`addr->"addr"|`memory->"memory"|`knowledge->"knowledge"|`invalid->"invalid"inletas_flag=function|`insn|`bil|`bir->["pretty"]|`sema->["all-slots"]|`kinds|`size|`invalid|`memory|`addr|`knowledge->[enabled]inletdoc=function|`insn->"Print the decoded instruction."|`bil->"Print the BIL code."|`bir->"Print the IR."|`sema->"Print the full semantics of the instruction."|`kinds->"Print semantics tags associated with instruction."|`size->"Print the instruction size."|`addr->"Print the instruction address"|`memory->"Print the instruction memory representation"|`knowledge->"Print the knowledge base."|`invalid->"Print invalid instructions."inletnames="show-"^name_of_outputsinExtension.Command.dictionary~doc~as_flagall_of_outputType.(liststring)nameletbase=letdoc="Specify an address of first byte"inCommand.parameter~aliases:["b"]~docType.string"address"letonly_one=letdoc="Stop after the first instruction is decoded"inCommand.flag~doc"only-one"letstop_on_error=Command.flag"stop-on-errors"~doc:"Stop disassembling on the first error and report it"letbackend=letdoc="The disassembling backend (used with triple)."inCommand.parameter~docType.(somestring)"backend"letloader=Extension.Command.parameter~doc:"Use the specified loader .
Use the loader `raw' to load unstructured files"Extension.Type.(string=?"llvm")"loader"endmoduleDis=Disasm_expert.Basicletbad_insnaddrstatestart=letstop=Addr.(Dis.addrstate-addr|>to_int|>ok_exn)infail(Bad_insn(Dis.memorystate,start,stop))letescape_0x=String.substr_replace_all~pattern:"0x"~with_:"\\x"letprepend_slash_xx="\\x"^x(** [to_binary ?escape s] make a binary string from ascii
representation, (e.g., "\x01\x02..."). Apply optional
escape function for each byte *)letto_binary?(map=ident)s=letseps=[' ';',';';']inletseparated=List.existsseps~f:(String.mems)inletbytes=ifseparatedthenString.split_on_chars~on:sepsselseList.init(String.lengths/2)~f:(funn->String.slices(n*2)(n*2+2))intryList.mapbytes~f:map|>String.concat|>Scanf.unescaped|>Result.returnwith_->failBad_user_inputletread_inputinput=letinput=matchinputwith|[]|["-"]->In_channel.input_lineIn_channel.stdin|s->Some(String.concats)inmatchinputwith|None->failNo_input|Someinput->matchString.prefixinput2with|""|"\n"->failNo_input|"\\x"->to_binaryinput|"0x"->to_binary~map:escape_0xinput|_->to_binary~map:prepend_slash_xinputletendian=function|Triple{order}->order|Target{name=t}->ifTheory.Endianness.(equalle)(Theory.Target.endiannesst)thenLittleEndianelseBigEndianletcreate_memoryarchdatabase=Memory.create(endianarch)base@@Bigstring.of_stringdata|>function|Okr->Okr|Errore->fail(Create_meme)letprint_kindsformatsinsn=List.iterformats~f:(fun_->Dis.Insn.kindsinsn|>List.map~f:sexp_of_kind|>List.iter~f:(printf"%a@."Sexp.pp))letnew_insnarchmeminsn=letopenKB.Syntaxinletprovide_targetunitlabel=function|Triple_->KB.return()|Target{name=target;encoding}->KB.provideTheory.Unit.targetunittarget>>=fun()->ifTheory.Language.is_unknownencodingthenKB.return()elseKB.provideTheory.Label.encodinglabelencodinginKB.Object.createTheory.Program.cls>>=funcode->KB.Symbol.intern"unit"Theory.Unit.cls>>=fununit->provide_targetunitcodearch>>=fun()->KB.promisingTheory.Label.unit~promise:(fun_->!!(Someunit))@@beginfun()->KB.provideMemory.slotcode(Somemem)>>=fun()->KB.provideDis.Insn.slotcode(Someinsn)>>=fun()->KB.collectTheory.Semantics.slotcode>>|fun_->codeendletliftarchmeminsn=matchToplevel.try_evalTheory.Semantics.slot(new_insnarchmeminsn)with|Errorconflict->fail(Inconsistencyconflict)|Oksema->Result.return@@ifInsn.(equalemptysema)thenInsn.of_basicinsnelsesemaletprint_insn_sizeformatsmem=List.iterformats~f:(fun_fmt->printf"%#x@\n"(Memory.lengthmem))letprint_insn_addrformatsmem=List.iterformats~f:(fun_enabled->printf"%a:@\n"Addr.pp(Memory.min_addrmem))letprint_insn_memoryformatsmem=List.iterformats~f:(fun_enabled->printf"%a@\n"Memory.ppmem)letprint_knowledgeformats=List.iterformats~f:(fun_->printf"%a@."KB.pp_state(Toplevel.current()))letprint_insninsn_formatsinsn=List.iterinsn_formats~f:(funfmt->Insn.with_printerfmt(fun()->printf"%a@."Insn.ppinsn))letprint_bilformatsinsn=letbil=Insn.bilinsninList.iterformats~f:(funfmt->printf"%a@."Bytes.pp(Bil.to_bytes~fmtbil))letprint_birformatsinsn=letbs=Blk.from_insninsninList.iterformats~f:(funfmt->List.iterbs~f:(funb->printf"%a@."Bytes.pp(Blk.to_bytes~fmtb)))letprint_semaformatssema=matchformatswith|[]->()|["all-slots"]->printf"%a@\n"KB.Value.ppsema|some_slots->letpp=KB.Value.pp_slotssome_slotsinprintf"%a@\n"ppsemaletequal_output=[%compare.equal:output]letis_enabled=function|[opt]->String.equalenabledopt|_->falseletformatsoutputskind=matchList.Assoc.findoutputskind~equal:equal_outputwith|None->[]|Somefmts->fmtsletprintarchmemcodeformats=liftarchmemcode>>|funinsn->print_insn_memory(formats`memory)mem;print_insn_addr(formats`addr)mem;print_insn_size(formats`size)mem;print_insn(formats`insn)insn;print_bil(formats`bil)insn;print_bir(formats`bir)insn;print_sema(formats`sema)insn;print_kinds(formats`kinds)code;print_knowledge(formats`knowledge)letbits=function|Target{name=t}->Theory.Target.bitst|Triple{bits}->bitsletparse_basearchbase=Result.map_error~f:(function|Invalid_argumentstr->Fail(Invalid_basestr)|exn->Fail(Invalid_base(Exn.to_stringexn)))@@Result.try_with@@fun()->Word.create(Bitvec.of_stringbase)(bitsarch)letcreate_disassemblerspec=Result.map_error~f:(funerr->Fail(Disassembler_failederr))@@matchspecwith|Target{name;encoding}->Dis.lookupnameencoding|Triple{name;cpu;backend}->Dis.create?backend?cpunameletmodule_of_kind=function|`insn->"Bap.Std.Insn"|`bil->"Bap.Std.Bil"|`bir->"Bap.Std.Blk"letvalidate_modulekindformats=letname=module_of_kindkindinData.all_writers()|>List.find_map~f:(fun(modname,fmts)->Option.some_if(String.equalmodnamename)fmts)|>function|None->failwithf"Unable to find printers for module %s"name()|Somefmts->letfmts=List.mapfmts~f:(fun(n,_,_)->n)inletprovided=Set.of_list(moduleString)fmtsinResult.all_unit@@List.mapformats~f:(funfmt->ifSet.memprovidedfmtthenOk()elseError(Unknown_format(name,fmt,fmts)))letvalidate_formatsformats=Result.map_error~f:(funerr->Failerr)@@Result.all_unit@@List.mapformats~f:(function|(`insn|`bil|`bir)askind,fmts->validate_modulekindfmts|(`kinds|`size|`invalid|`addr|`memory|`knowledge),[]->Ok()|(`kinds|`size|`invalid|`addr|`memory|`knowledge),[opt]whenString.equalenabledopt->Ok()|`kinds,_->Error(No_formats_expected"kinds")|`size,_->Error(No_formats_expected"size")|`addr,_->Error(No_formats_expected"addr")|`memory,_->Error(No_formats_expected"memory")|`knowledge,_->Error(No_formats_expected"knowledge")|`invalid,_->Error(No_formats_expected"invalid")|`sema,_->(* no validation right now, since the knowledge introspection
is not yet implemented *)Ok())letprint_invalid_pos=Format.printf"<invalid>@\n"letrun?(only_one=false)?(stop_on_error=false)disarchmemformats=letshow_invalid=is_enabled(formats`invalid)inDis.rundismem~init:0~return:Result.return~stop_on:[`Valid]~invalid:(funstate_pos->ifshow_invalidthenprint_invalidpos;ifstop_on_errorthenbad_insn(Memory.min_addrmem)stateposelseDis.stepstatepos)~hit:(funstatememinsnbytes->printarchmeminsnformats>>=fun()->ifonly_onethenDis.stopstatebyteselseDis.stepstate(bytes+Memory.lengthmem))letcheck_invariantsxs=List.concat_mapxs~f:(fun(pred,props)->ifpredthenpropselse[])|>Result.all_unitletcheckcheckterror=ifnot(checkt)thenfailerrorelseOk()lettarget_must_be_unknownt=checkTheory.Target.is_unknowntTarget_must_be_unknownletencoding_must_be_unknownt=checkTheory.Language.is_unknowntEncoding_must_be_unknownlettriple_must_not_be_setx=checkOption.is_nonexTriple_must_not_be_setletarch_must_not_be_setx=checkOption.is_nonexArch_must_not_be_setletbackend_must_not_be_setx=checkOption.is_nonexBackend_must_not_be_setletcpu_must_not_be_setx=checkOption.is_nonexCpu_must_not_be_setletbits_must_not_be_setx=checkOption.is_nonexBits_must_not_be_setletorder_must_not_be_setx=checkOption.is_nonexOrder_must_not_be_setletcompute_targetprovide=letextract_target=letopenKB.SyntaxinKB.Object.scopedTheory.Unit.cls@@fununit->KB.Object.scopedTheory.Program.cls@@funlabel->provideunit>>=fun()->KB.provideTheory.Label.unitlabel(Someunit)>>=fun()->Theory.Label.targetlabel>>=funname->KB.collectTheory.Label.encodinglabel>>|funencoding->Target{name;encoding}inletresult=Toplevel.var"target-and-encoding"inToplevel.putresultextract_target;Toplevel.getresultlettarget_of_archarchbitsorder=letbits=matchbitswith|None->32L|Somebits->Int64.of_intbitsinletis_little=matchorderwith|SomeBigEndian->false|_->trueinletmake_spec=letopenOgre.SyntaxinOgre.sequence[Ogre.provideImage.Scheme.archarch;Ogre.provideImage.Scheme.bitsbits;Ogre.provideImage.Scheme.is_little_endianis_little;]inletspec=matchOgre.execmake_specOgre.Doc.emptywith|Errorerr->failwithf"compute_target: failed to build a spec: %s"(Error.to_string_humerr)()|Okdoc->docincompute_target@@fununit->KB.provideImage.Spec.slotunitspecletmake_triple?(bits=32)?(order=BigEndian)?backend?cpuname=Triple{name;backend;cpu;bits;order}letmake_targettargetencoding=ifTheory.Language.is_unknownencodingthencompute_target@@fununit->KB.provideTheory.Unit.targetunittargetelseTarget{name=target;encoding}letparse_archarchtargetencodingtriplecpubackendbitsorder=check_invariants[Option.is_somearch,[target_must_be_unknowntarget;triple_must_not_be_settriple;];not(Theory.Target.is_unknowntarget),[arch_must_not_be_setarch;triple_must_not_be_settriple;];Option.is_sometriple,[target_must_be_unknowntarget;encoding_must_be_unknownencoding;arch_must_not_be_setarch;];Theory.Target.is_unknowntarget,[encoding_must_be_unknownencoding;];Option.is_nonetriple,[cpu_must_not_be_setcpu;backend_must_not_be_setbackend;];Option.is_nonetriple&&Option.is_nonearch,[bits_must_not_be_setbits;order_must_not_be_setorder;]]>>|fun()->matcharch,triplewith|None,None->ifTheory.Target.is_unknowntargetthentarget_of_arch"x86-64"NoneNoneelsemake_targettargetencoding|Somearch,None->target_of_archarchbitsorder|None,Sometriple->make_triple?bits?order?backend?cputriple|Some_,Some_->failwith"parse_arch: unchecked invariant"let()=Extension.Command.(begindeclare~doc:mc_man"mc"Spec.(args$arch$target$encoding$triple$cpu$backend$bits$order$base$only_one$stop_on_error$input$outputs)end)@@funarchtargetencodingtriplecpubackendbitsorderbaseonly_onestop_on_errorinputoutputs_ctxt->validate_formatsoutputs>>=fun()->parse_archarchtargetencodingtriplecpubackendbitsorder>>=funarch->read_inputinput>>=fundata->parse_basearchbase>>=funbase->create_memoryarchdatabase>>=funmem->create_disassemblerarch>>=fundis->letformats=formatsoutputsinrun~only_one~stop_on_errordisarchmemformats>>=funbytes->Dis.closedis;matchString.lengthdata-byteswith|0->Ok()|_whenonly_one->Ok()|n->fail(Trailing_datan)let()=Extension.Command.(begindeclare~doc:objdump_man"objdump"Spec.(args$loader$stop_on_error$file$outputs)end)@@funloaderstop_on_errorinputoutputs_ctxt->validate_formatsoutputs>>=fun()->letformats=formatsoutputsinmatchImage.create~backend:loaderinputwith|Errorerr->Error(Fail(Loader_failederr))|Ok(img,_warns)->lettarget=compute_target@@fununit->KB.provideImage.Spec.slotunit(Image.specimg)increate_disassemblertarget>>=fundis->Image.memoryimg|>Memmap.to_sequence|>Seq.filter_map~f:(fun(mem,data)->Option.some_if(Value.isImage.code_regiondata)mem)|>Seq.map~f:(funmem->run~stop_on_errordistargetmemformats>>=fun_bytes->Ok())|>Seq.to_list|>Result.all_unitletformat_infoget_fmts=get_fmts()|>List.map~f:fst3|>String.concat~sep:", "letstring_of_failure=function|Inconsistencyconflict->Format.asprintf"Lifters failed with a conflict: %a"KB.Conflict.ppconflict|Bad_user_input->"Could not parse: malformed input"|No_input->"No input was received"|Trailing_data1->"the last byte wasn't disassembled"|Trailing_dataleft->sprintf"%d bytes were left non disassembled"left|Create_memerr->Format.asprintf"Unable to create a memory: %a"Error.pperr|Invalid_basemsg->sprintf"Failed to parse the base address: %s"msg|Disassembler_failederr->Format.asprintf"Failed to create the disassembler backend: %a"Error.pperr|Bad_insn(mem,boff,stop)->letdump=Memory.hexdumpmem|>Bytes.of_stringinletline=boff/16inletposoff=line*77+(offmod16)*3+9inBytes.setdump(posboff)'(';Bytes.setdump(posstop)')';sprintf"Invalid instruction at offset %d:\n%s"boff(Bytes.to_stringdump)|Unknown_format(mname,fmt,fmts)->letpp_sep=Format.pp_print_newlineinFormat.asprintf"@[<v2>Unknown printer %s for %s, expecting: %a@]"fmtmnameFormat.(pp_print_list~pp_seppp_print_string)fmts|No_formats_expectedname->sprintf"--show-%s doesn't expect any formats yet"name|Loader_failederr->Format.asprintf"Failed to unpack the file: %a"Error.pperr|Target_must_be_unknown|Triple_must_not_be_set|Arch_must_not_be_set->"The target, triple, and arch options could not be used together"|Encoding_must_be_unknown->"The encoding option requires the target option"|Backend_must_not_be_set->"The backend option requires the triple option"|Cpu_must_not_be_set->"The CPU option requires the triple option"|Bits_must_not_be_set|Order_must_not_be_set->"The bits and order parameters are only accepted with arch or \
triple and are not allowed when the target is specified"let()=Extension.Error.register_printer@@function|Failerr->Some(string_of_failureerr)|_->None