Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file sexpr.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2024 *)(* 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). *)(* *)(**************************************************************************)moduleBv=BitvectormoduleBiMap=Basic_types.BigInt.MapmodulerecExpr:(Term.Swithtypea:=stringandtypeb:=Memory.t)=Term.Make(structtypet=stringletcompare__=0letequal__=truelethash_=0end)(Memory)andChunk:sigincludeLmap.Valuetypehunk=(int,Bigarray.int8_unsigned_elt,Bigarray.c_layout)Bigarray.Array1.ttypekind=Hunkofhunk|TermofExpr.tvalinspect:t->kindvalof_hunk:hunk->tvalof_term:Expr.t->tvalto_term:t->Expr.t(** low level API *)valis_hunk:t->boolvalis_term:t->boolvalunsafe_to_hunk:t->hunkvalunsafe_to_term:t->Expr.tend=structtypettypehunk=(int,Bigarray.int8_unsigned_elt,Bigarray.c_layout)Bigarray.Array1.ttypekind=Hunkofhunk|TermofExpr.texternalis_unboxed:t->bool="%obj_is_int"externalstill_unboxed:Bv.t->bool="%obj_is_int"externalto_bv:t->Bv.t="%identity"externalof_bv:Bv.t->t="%identity"externalunsafe_to_term:t->Expr.t="%identity"externalof_term:Expr.t->t="%identity"externalunsafe_to_hunk:t->hunk="%identity"externalof_hunk:hunk->t="%identity"letis_hunkx=Obj.tag(Obj.reprx)=Obj.custom_tagletis_termx=is_unboxedx||not(is_hunkx)letof_bvbv=ifstill_unboxedbvthenof_bvbvelseof_term(Expr.constantbv)letinspectx=ifis_unboxedxthenTerm(Expr.constant(to_bvx))elseifis_hunkxthenHunk(unsafe_to_hunkx)elseTerm(unsafe_to_termx)letequalxy=x==y||(not(is_unboxedx))&&(not(is_hunkx))&&(not(is_unboxedy))&&(not(is_hunky))&&Expr.is_equal(unsafe_to_termx)(unsafe_to_termy)letlenx=ifis_unboxedxthenBv.size_of(to_bvx)lsr3elseifis_hunkxthenBigarray.Array1.dim(unsafe_to_hunkx)elseExpr.sizeof(unsafe_to_termx)lsr3letcrop~lo~hix=ifis_hunkxthenof_hunk(Bigarray.Array1.sub(unsafe_to_hunkx)lo(hi-lo+1))elseletlo=lolsl3andhi=(hilsl3)+7inifis_unboxedxthenof_bv(Bv.extract(to_bvx){lo;hi})elseof_term(Expr.restrict~lo~hi(unsafe_to_termx))lethunk_to_bvx=letx=unsafe_to_hunkxinlets=Bigarray.Array1.dimxinBv.create(Z.of_bits(String.inits(funi->Char.unsafe_chr(Bigarray.Array1.unsafe_getxi))))(slsl3)letconcatxy=ifis_unboxedxthenifis_unboxedythenof_bv(Bv.append(to_bvx)(to_bvy))elseifis_hunkythenof_bv(Bv.append(to_bvx)(hunk_to_bvy))elseof_term(Expr.append(Expr.constant(to_bvx))(unsafe_to_termy))elseifis_hunkxthenifis_unboxedythenof_bv(Bv.append(hunk_to_bvx)(to_bvy))elseifis_hunkythenof_bv(Bv.append(hunk_to_bvx)(hunk_to_bvy))elseof_term(Expr.append(Expr.constant(hunk_to_bvx))(unsafe_to_termy))elseifis_unboxedythenof_term(Expr.append(unsafe_to_termx)(Expr.constant(to_bvy)))elseifis_hunkythenof_term(Expr.append(unsafe_to_termx)(Expr.constant(hunk_to_bvy)))elseof_term(Expr.append(unsafe_to_termx)(unsafe_to_termy))letto_termx=ifis_unboxedxthenExpr.constant(to_bvx)elseifis_hunkxthenExpr.constant(hunk_to_bvx)elseunsafe_to_termxletof_term(x:Expr.t)=matchxwithCstbv->of_bvbv|x->of_termxendandStore:sigincludeLmap.Swithtypev:=Chunk.tvalsingleton:Bv.t->Chunk.t->tvalstore:Bv.t->Chunk.t->t->tvalselect:(Z.t->int->Chunk.t)->Bv.t->int->t->Chunk.tvaliter_term:(Z.t->Expr.t->unit)->t->unitvalfold_term:(Z.t->Expr.t->'a->'a)->'a->t->'aend=structincludeLmap.Make(Chunk)letsingletonkv=letz=Bv.value_ofkands=Chunk.lenvinletu=Z.addz(Z.of_ints)inletn=Bv.size_ofkinifZ.numbitsu>n&&Z.popcountu>1thenleto=Z.to_int(Z.extractu0n)instorez(Chunk.crop~hi:(s-o-1)~lo:0v)(singletonZ.zero(Chunk.crop~hi:(s-1)~lo:(s-o)v))elsesingletonzvletstorekvt=letz=Bv.value_ofkands=Chunk.lenvinletu=Z.addz(Z.of_ints)inletn=Bv.size_ofkinifZ.numbitsu>n&&Z.popcountu>1thenleto=Z.to_int(Z.extractu0n)instorez(Chunk.crop~hi:(s-o-1)~lo:0v)(storeZ.zero(Chunk.crop~hi:(s-1)~lo:(s-o)v)t)elsestorezvtletselectfkst=letz=Bv.value_ofkinletu=Z.addz(Z.of_ints)inletn=Bv.size_ofkinifZ.numbitsu>n&&Z.popcountu>1thenleto=Z.to_int(Z.extractu0n)inChunk.concat(selectfZ.zeroot)(selectfz(s-o)t)elseselectfzstletiter_termft=iter(funkv->ifnot(Chunk.is_hunkv)thenfk(Chunk.to_termv))tletfold_termfbt=fold(funkvb->ifnot(Chunk.is_hunkv)thenfk(Chunk.to_termv)belseb)btendandMemory:sigtypet=|Root|Symbolofstring|Layerof{id:int;over:t;addr:Expr.t;store:Store.t}valcompare:t->t->intvalequal:t->t->boolvalhash:t->intvalroot:tvalfresh:string->tvallayer:Expr.t->Store.t->t->tend=structtypet=|Root|Symbolofstring|Layerof{id:int;over:t;addr:Expr.t;store:Store.t}letid=ref0lethash=function|Root->0|Symbolname->Hashtbl.hashname|Layer{id;_}->idletcomparett'=hasht-hasht'letequaltt'=match(t,t')with|Root,Root->true|Symbolid,Symbolid'->id=id'|Layer{id;_},Layer{id=id';_}->id=id'|(Root|Symbol_|Layer_),(Root|Symbol_|Layer_)->falseletroot=Rootletfreshname=Symbolnameletlayeraddrstoreover=incrid;Layer{id=!id;over;addr;store}endmoduleBvTbl=Hashtbl.Make(structincludeExprletequal=is_equalend)moduleAxTbl=Hashtbl.Make(Memory)moduleBiTbl=Basic_types.BigInt.HtblmoduleStTbl=Basic_types.String.HtblmoduleS=Basic_types.String.MapmoduleI=Map.Make(structtypet=Z.tletcomparexy=-Z.comparexyend)letbswap=letrecitereir=ifi=0thenrelseitere(i-8)(Expr.append(Expr.restrict~hi:(i-1)~lo:(i-8)e)r)infune->letsize=Expr.sizeofeinassert(sizeland0x7=0);itere(size-8)(Expr.restrict~hi:(size-1)~lo:(size-8)e)moduleModel=structtypet=Expr.tStTbl.t*Bv.tBvTbl.t*charBiTbl.t*charBiTbl.tStTbl.t*intletemptyaddr_space=(StTbl.create0,BvTbl.create0,BiTbl.create0,StTbl.create0,addr_space)letmaybe_pp_charppfc=ifString_utils.is_char_printablecthenFormat.fprintfppf" (%c)"cletpp_variablesppfvarsvalues=ifStTbl.lengthvars>0then(Format.pp_print_stringppf"# Variables";Format.pp_print_cutppf();StTbl.iter(funnamevalue->Format.fprintfppf"%s : %a@ "nameBitvector.pp_hex_or_bin(BvTbl.findvaluesvalue))vars)letpp_int_as_bvppfx=function|1->Format.fprintfppf"#b%d"x|4->Format.fprintfppf"#x%01x"x|8->Format.fprintfppf"#x%02x"x|12->Format.fprintfppf"#x%03x"x|16->Format.fprintfppf"#x%04x"x|20->Format.fprintfppf"#x%05x"x|24->Format.fprintfppf"#x%06x"x|28->Format.fprintfppf"#x%07x"x|32->Format.fprintfppf"#x%08x"x|64whenx>=0->Format.fprintfppf"#x%016x"x|sz->Format.fprintfppf"(_ bv%d %d)"xszletpp_bvppfvaluesize=trypp_int_as_bvppf(Z.to_intvalue)sizewithZ.Overflow->Format.fprintfppf"(_ bv%a %d)"Z.pp_printvaluesizeletpp_memoryppfmemoryaddr_space=ifBiTbl.lengthmemory=0thenFormat.pp_print_stringppf"-- empty memory --"else(Format.pp_print_stringppf"# Memory";Format.pp_print_cutppf();letimg=Kernel_functions.get_img()inletnoname=""inletsection_nameaddr=tryletaddress=Virtual_address.to_int(Virtual_address.of_bigintaddr)inmatchLoader_utils.find_section_by_address~addressimgwith|None->noname|Somesection->Loader.Section.namesectionwithVirtual_address.Non_canonical_form->nonameinletpp_sectionppfname=ifname==nonamethenFormat.pp_print_stringppf"unamed section"elseFormat.fprintfppf"section %s"nameinletlast_section=ref"--"inI.iter(funaddrbyte->letname=section_nameaddrinifname<>!last_sectionthen(Format.fprintfppf"; %a@ "pp_sectionname;last_section:=name);pp_bvppfaddraddr_space;Format.fprintfppf" : %02x %a@ "(Char.codebyte)maybe_pp_charbyte)@@BiTbl.foldI.addmemoryI.empty)letpp_arrayppfnamearrayaddr_space=Format.pp_print_stringppf"# Array ";Format.pp_print_stringppfname;Format.pp_print_cutppf();I.iter(funaddrbyte->pp_bvppfaddraddr_space;Format.fprintfppf" : %02x %a@ "(Char.codebyte)maybe_pp_charbyte)@@BiTbl.foldI.addarrayI.emptyletppppf(vars,values,memory,arrays,addr_space)=ifStTbl.lengthvars=0&&BiTbl.lengthmemory=0&&StTbl.lengtharrays=0thenFormat.fprintfppf"@[<h>--- Empty model ---@]"else(Format.fprintfppf"@[<v 0>--- Model ---@ ";pp_variablesppfvarsvalues;Format.pp_print_spaceppf();pp_memoryppfmemoryaddr_space;StTbl.iter(funnamearray->ifBiTbl.lengtharray<>0then(Format.pp_print_spaceppf();pp_arrayppfnamearrayaddr_space))arrays;Format.pp_close_boxppf())letreceval?(symbols=fune->Bitvector.create(Z.of_int(Expr.hashe))(Expr.sizeofe))?(memory=fun__->'\x00')((vars,values,_,_,_)asm)=function|Expr.Cstbv->bv|e->(tryBvTbl.findvaluesewithNot_found->letvalue=matchewith|Expr.Cst_->assertfalse|Expr.Var{name;_}->StTbl.addvarsnamee;symbolse|Expr.Load{addr;len;dir;label;_}->eval_load~symbols~memorym(eval~symbols~memorymaddr)lendirlabel|Expr.Unary{f;x;_}->Term.Bv.unaryf(eval~symbols~memorymx)|Expr.Binary{f;x;y;_}->Term.Bv.binaryf(eval~symbols~memorymx)(eval~symbols~memorymy)|Expr.Ite{c;t;e;_}->ifBv.zero=eval~symbols~memorymctheneval~symbols~memorymeelseeval~symbols~memorymtinBvTbl.addvaluesevalue;value)andeval_load~symbols~memory((_,_,cache,arrays,addr_size)ast)ptrlendir(memory_term:Memory.t)=matchmemory_termwith|Root->letindex=matchdirwith|LittleEndian->Bv.add_intptr|BigEndian->lethi=Bv.add_intptr(len-1)infuni->Bv.add_inthi(-i)inletbits=String.initlen(funi->letx=Bv.value_of(indexi)intryBiTbl.findcachexwithNot_found->letbyte=memorymemory_term(Bv.createxaddr_size)inBiTbl.addcachexbyte;byte)inBv.create(Z.of_bitsbits)(lenlsl3)|Symboln->letindex=matchdirwith|LittleEndian->Bv.add_intptr|BigEndian->lethi=Bv.add_intptr(len-1)infuni->Bv.add_inthi(-i)inletbits=String.initlen(funi->letx=Bv.value_of(indexi)andarr=tryStTbl.findarraysnwithNot_found->letarr=BiTbl.create16inStTbl.addarraysnarr;arrintryBiTbl.findarrxwithNot_found->letbyte=memorymemory_term(Bv.createxaddr_size)inBiTbl.addarrxbyte;byte)inBv.create(Z.of_bitsbits)(lenlsl3)|Layer{addr;store;over;_}->letaddr=eval~symbols~memorytaddrinletsize=Bv.size_ofaddrinletoffset=Bv.subptraddrinletmissis=Chunk.of_term(Expr.loadsExpr.LittleEndian(Expr.constant(Bv.addaddr(Bv.createisize)))over)inletbytes=Chunk.to_term(Store.selectmissoffsetlenstore)inletbytes=matchdirwithLittleEndian->bytes|BigEndian->bswapbytesineval~symbols~memorytbytesendmoduleBvSet=Set.Make(Expr)moduleBvMap=Map.Make(Expr)