Home | History | Annotate | Download | only in libenc
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 /**
     18  * @author Alexander V. Astapchuk
     19  */
     20 
     21 /**
     22  * @file
     23  * @brief Main decoding (disassembling) routines and structures.
     24  *
     25  * @note Quick and rough implementation, subject for a change.
     26  */
     27 
     28 #ifndef __DEC_BASE_H_INCLUDED__
     29 #define __DEC_BASE_H_INCLUDED__
     30 
     31 
     32 #include "enc_base.h"
     33 #include "enc_prvt.h"
     34 
     35 #ifdef ENCODER_ISOLATE
     36 using namespace enc_ia32;
     37 #endif
     38 
     39 #define IF_CONDITIONAL  (0x00000000)
     40 #define IF_SYMMETRIC    (0x00000000)
     41 #define IF_BRANCH       (0x00000000)
     42 
     43 struct Inst {
     44     Inst() {
     45         mn = Mnemonic_Null;
     46         prefc = 0;
     47         size = 0;
     48         flags = 0;
     49         //offset = 0;
     50         //direct_addr = NULL;
     51         argc = 0;
     52         for(int i = 0; i < 4; ++i)
     53         {
     54             pref[i] = InstPrefix_Null;
     55         }
     56     }
     57     /**
     58      * Mnemonic of the instruction.s
     59      */
     60     Mnemonic mn;
     61     /**
     62      * Enumerating of indexes in the pref array.
     63      */
     64     enum PrefGroups
     65     {
     66         Group1 = 0,
     67         Group2,
     68         Group3,
     69         Group4
     70     };
     71     /**
     72      * Number of prefixes (1 byte each).
     73      */
     74     unsigned int prefc;
     75     /**
     76      * Instruction prefixes. Prefix should be placed here according to its group.
     77      */
     78     InstPrefix pref[4];
     79     /**
     80      * Size, in bytes, of the instruction.
     81      */
     82     unsigned size;
     83     /**
     84      * Flags of the instruction.
     85      * @see MF_
     86      */
     87     unsigned flags;
     88     /**
     89      * An offset of target address, in case of 'CALL offset',
     90      * 'JMP/Jcc offset'.
     91      */
     92     //int      offset;
     93     /**
     94      * Direct address of the target (on Intel64/IA-32 is 'instruction IP' +
     95      * 'instruction length' + offset).
     96      */
     97     //void *   direct_addr;
     98     /**
     99      * Number of arguments of the instruction.
    100      */
    101     unsigned argc;
    102     //
    103     EncoderBase::Operand operands[3];
    104     //
    105     const EncoderBase::OpcodeDesc * odesc;
    106 };
    107 
    108 inline bool is_jcc(Mnemonic mn)
    109 {
    110     return Mnemonic_JO <= mn && mn<=Mnemonic_JG;
    111 }
    112 
    113 class DecoderBase {
    114 public:
    115     static unsigned decode(const void * addr, Inst * pinst);
    116 private:
    117     static bool decodeModRM(const EncoderBase::OpcodeDesc& odesc,
    118         const unsigned char ** pbuf, Inst * pinst
    119 #ifdef _EM64T_
    120         , const Rex *rex
    121 #endif
    122         );
    123     static bool decode_aux(const EncoderBase::OpcodeDesc& odesc,
    124         unsigned aux, const unsigned char ** pbuf,
    125         Inst * pinst
    126 #ifdef _EM64T_
    127         , const Rex *rex
    128 #endif
    129         );
    130     static bool try_mn(Mnemonic mn, const unsigned char ** pbuf, Inst * pinst);
    131     static unsigned int fill_prefs( const unsigned char * bytes, Inst * pinst);
    132     static bool is_prefix(const unsigned char * bytes);
    133 };
    134 
    135 #endif  // ~ __DEC_BASE_H_INCLUDED__
    136 
    137