123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194(**************************************************************************)(* 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). *)(* *)(**************************************************************************)moduleLogger=Dba_loggerletcur_address=ref0letincr_addressaddr=cur_address:=addr.Dba.id+1letcur_address()=!cur_addressmoduleDeclarations=structmoduleSH=Basic_types.String.Htblletdeclarations:(Dba.size*Dba.Var.Tag.t)SH.t=SH.create16letaddnamesizeopttags=SH.adddeclarationsname(size,opttags)endmoduleMk=structopenDbamodulePredicates=structletrecof_listl=matchlwith|[]->assertfalse|[(elmt,p)]->([elmt],p)|(elmt,(p1,p2,p3))::l->letelmts,(q1,q2,q3)=of_listlin(elmt::elmts,(Expr.logandp1q1,Expr.logandp2q2,Expr.logandp3q3))endendletexpr_of_namename=letfirst_char=name.[0]iniffirst_char='_'||first_char='?'||first_char='!'thenletname=iffirst_char='_'then"*"elsenameinDba.Expr.varname0elseletopenDba.Exprinletregname=varname32inleteax=reg"eax"andebx=reg"ebx"andecx=reg"ecx"andedx=reg"edx"inmatchnamewith|"al"->restrict07eax|"ah"->restrict815eax|"ax"->restrict015eax|"eax"->eax|"bl"->restrict07ebx|"bh"->restrict815ebx|"bx"->restrict015ebx|"ebx"->ebx|"cl"->restrict07ecx|"ch"->restrict815ecx|"cx"->restrict015ecx|"ecx"->ecx|"dl"->restrict07edx|"dh"->restrict815edx|"dx"->restrict015edx|"edx"->edx|"di"->restrict015(reg"edi")|"edi"->reg"edi"|"si"->restrict015(reg"esi")|"esi"->reg"esi"|"bp"->restrict015(reg"ebp")|"ebp"->reg"ebp"|"sp"->restrict015(reg"esp")|"esp"->reg"esp"|"btemp"->temporary"btemp"~size:8|"stemp"->temporary"stemp"~size:16|"temp"->temporary"temp"~size:32|"dtemp"->temporary"dtemp"~size:64|name->Logger.error"Unknown variable name: %s"name;raiseParsing.Parse_errorletis_wildmetapld_expr=function|Dba.(Expr.Var{name;_})->letc=name.[0]inc='*'||c='?'||c='!'|_->falseletrecpatch_expr_sizeesz=letopenDba.ExprinLogger.debug~level:2"Will patch: %a with %d"Dba_printer.Ascii.pp_bl_termesz;matchewith|Dba.(Expr.Var{name;info=tag;_})->ifis_wildmetapld_expretheneelsevarnamesz~tag|Dba.Expr.Cstbv->constant(Bitvector.create(Bitvector.value_ofbv)sz)|Dba.Expr.Load(_old_sz,en,e,array)->letbysz=Size.(Bit.createsz|>Byte.of_bitsize)inloadbyszene?array|Dba.Expr.Unary(Dba.Unary_op.Uextsize,e)->uextsize(patch_expr_sizee(sz-size))|Dba.Expr.Unary(Dba.Unary_op.Sextsize,e)->sextsize(patch_expr_sizee(sz-size))|Dba.Expr.Unary(op,e)->unaryop(patch_expr_sizeesz)|_->emoduleMessage=structmoduleValue=structtypet=IntofZ.t|Strofstringletvstrv=Strvletvintv=Int(Z.of_stringv)endmoduleInstruction=structtypet=|Undefined|Unimplemented|Unsupportedof{read:Dba.LValue.tlist;write:Dba.LValue.tlist;goto:Virtual_address.t;}|Preciseof(Dba.address*Dba.Instr.t)listendtypet=(string*Value.t)list*Instruction.tendmoduleInitialization=structopenDbatypervalue=|Nondet|Signed_intervalofDba.Expr.t*Dba.Expr.t|Unsigned_intervalofDba.Expr.t*Dba.Expr.t|SetofDba.Expr.tlist|SingletonofDba.Expr.ttypeidentifier=stringtypeoperation=|AssignmentofDba.LValue.t*rvalue*identifieroption|Mem_loadofDba.Expr.t*int|AssumptionofDba.Expr.t|UniversalofDba.LValue.ttypet={controlled:bool;operation:operation}letcreate~controlled~operation={controlled;operation}letassumee=create~controlled:false~operation:(Assumptione)letassign?identifier?(controlled=true)lvalrval=letoperation=Assignment(lval,rval,identifier)increate~controlled~operationletuniversallval=create~controlled:false~operation:(Universallval)letfrom_assignment?identifier?(controlled=true)=function|Dba.Instr.Assign(lval,rval,_)->assign?identifier~controlledlval(Singletonrval)|Dba.Instr.Nondet(lval,_)->assign?identifier~controlledlvalNondet|_->failwith"initialization with non assignment"letfrom_store?(controlled=true)lv=Logger.debug"Init from store %a"Dba_printer.Ascii.pp_lhslv;matchlvwith|LValue.Store(size,_,addr,None)->(* assert (Dba.Expr.size_of addr = Kernel_options.Machine.word_size ()); *)letoperation=Mem_load(addr,size)increate~controlled~operation|_->failwith"initialization from file with non store"letset_controlcontrolledt=matcht.operationwithUniversal_->t|_->{twithcontrolled}endletmk_patchesl=List.fold_left(funvmap(vaddr,opcode)->Virtual_address.Map.add(Virtual_address.createvaddr)opcodevmap)Virtual_address.Map.emptyl