123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2026 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)openBasic_types.Integersletget_byte_atimgaddr=Bitvector.value_ofaddr|>Virtual_address.of_bigint|>Loader.read_addressimg|>Uint8.to_int(* { Manipulation of symbols } *)letsymbol_by_name~nameimg=letsymbols=Loader.Img.symbolsimgintrySome(Array_utils.find(funsy->String.compare(Loader.Symbol.namesy)name=0)symbols)withNot_found->Noneletaddress_of_symbolsymbol=Loader.Symbol.valuesymbolletaddress_of_symbol_by_name~nameimg=matchsymbol_by_name~nameimgwith|Somesymbol->Some(address_of_symbolsymbol)|None->Noneletsize_of_symbolsymbol:int=letheader=Loader.Symbol.headersymbolinmatchheaderwith|Loader.ELFelf->elf.Loader_elf.Sym.size|Loader.PE_->failwith"No size for PE symbols"|Loader.Raw_->failwith"No size for Raw symbols"|Loader.TI83_->failwith"No size for TI83 symbols"letsize_of_symbol_by_name~nameimg=matchsymbol_by_name~nameimgwith|Somesymbol->Some(size_of_symbolsymbol)|None->Noneletsymbol_intervalsymbol=letstart_addr=address_of_symbolsymbolinletsize=size_of_symbolsymbolinletend_addr=Virtual_address.add_intsizestart_addrin(start_addr,end_addr)letsymbol_interval_by_name~nameimg=matchsymbol_by_name~nameimgwith|Somesymbol->Some(symbol_intervalsymbol)|None->Noneletbelongs_to_symbolsymboladdr=letstart_addr,end_addr=symbol_intervalsymbolinVirtual_address.comparestart_addraddr<=0&&Virtual_address.compareend_addraddr>0letbelongs_to_symbol_by_name~nameimgaddr=matchsymbol_by_name~nameimgwith|Somesymbol->belongs_to_symbolsymboladdr|None->raiseNot_found(* { End of Manipulation of symbols } *)letintervalsection=letopenLoader_typesinletsec_start=(Loader.Section.possection).virtinletsec_end=Virtual_address.add_bigint(Z.pred(Loader.Section.sizesection).virt)sec_startin(sec_start,sec_end)letin_sectionsectionaddr=letopenLoader_typesinletlo=(Loader.Section.possection).virtandsz=(Loader.Section.sizesection).virtinlethi=Virtual_address.add_bigintszloinaddr>=lo&&addr<hiletfind_section~pimg=trySome(Array_utils.findp(Loader.Img.sectionsimg))withNot_found->Noneletfind_section_by_address~addressimg=find_section~p:(funs->in_sectionsaddress)imgletfind_section_by_address_exn~addressimg=Array_utils.find(funs->in_sectionsaddress)(Loader.Img.sectionsimg)letfind_section_by_namesection_nameimg=Array_utils.find(funsection->section_name=Loader.Section.namesection)(Loader.Img.sectionsimg)letsection_slice_by_namesection_nameimg=find_section_by_namesection_nameimg|>intervalletsection_slice_by_address~addressimg=find_section_by_address_exnimg~address|>intervalletentry_pointimg=Loader.Img.entryimgletaddress_of_symbol_or_section_by_name~nameimg=matchaddress_of_symbol_by_name~nameimgwith|Some_asa->a|None->(trySome(Loader.Section.pos(find_section_by_namenameimg)).Loader_types.virtwithNot_found->None)letsize_of_symbol_or_section_by_name~nameimg=matchsize_of_symbol_by_name~nameimgwith|Some_ass->s|None->(trySome(Z.to_int(Loader.Section.size(find_section_by_namenameimg)).Loader_types.virt)withNot_found->None)letinterval_of_symbol_or_section_by_name~nameimg=matchsymbol_interval_by_name~nameimgwith|Some_asi->i|None->(tryletsection=find_section_by_namenameimginletp=(Loader.Section.possection).Loader_types.virtands=(Loader.Section.sizesection).Loader_types.virtinSome(p,Virtual_address.add_bigintsp)withNot_found->None)moduleBinary_loc=structtypet=AddressofVirtual_address.t|Nameofstring|Offsetoft*intletnames=Namesletaddressa=Addressaletoffsetnt=ifn=0thentelsematchtwith|Name_ast->Offset(t,n)|Offset(t,m)->Offset(t,m+n)|Addressa->Address(Virtual_address.add_intna)letrecppppf=function|Names->Format.pp_print_stringppfs|Offset(t,n)->Format.fprintfppf"<%a %c %d>"ppt(ifn<0then'-'else'+')n|Addressa->Virtual_address.ppppfaletrecof_strings=matchs.[0]with|'<'->letpos_end=String.rindexs'>'inletpos_plus=String.indexs'+'inletbase=of_string(String.subs1(pos_plus-1))andint_off=letstart=pos_plus+1inletlen=pos_end-startinint_of_string(String.subsstartlen)inoffsetint_offbase|'0'->ifs.[1]='x'||s.[1]='X'thenAddress(Virtual_address.create(int_of_strings))elseNames|_->Names(* match int_of_string s with
* | addr -> Address (Virtual_address.create addr)
* | exception Failure "int_of_string" -> Name s *)let(>>)gf=matchgwithNone->None|Somev->Some(fv)letaddress_from_imgnameimg=address_of_symbol_by_nameimg~nameletto_virtual_address_from_file~filenamet=letreceval=function|Addressaddr->Someaddr|Namename->letimg=Loader.load_filefilenameinaddress_from_imgnameimg|Offset(t,n)->evalt>>Virtual_address.add_intninevaltletto_virtual_address~imgt=letrecloop=function|Addressaddr->Someaddr|Namename->address_from_imgnameimg|Offset(t,n)->loopt>>Virtual_address.add_intninlooptend