Пример #1
0
    static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data )
    {
        //get the storage
        typedef converter::rvalue_from_python_storage< multi_array_t > storage_t;
        storage_t * the_storage = reinterpret_cast< storage_t * >( data );
        void * memory_chunk = the_storage->storage.bytes;
        //new (memory_chunk) multi_array_t(obj);

        //new placement
        object py_obj( handle<>( borrowed( obj ) ) );
        shape_t shape;
        get_shape( py_obj, shape );
        multi_array_t * a = new (memory_chunk) multi_array_t( shape );

        //extract each element from numpy array and put in c array
        index i( a->num_dimensions(), 0 );
        do {
            boost::python::list numpy_index;
            for( unsigned dim = 0; a->num_dimensions() != dim; ++dim ) {
                numpy_index.append( i[ dim ] );
            }
            (*a)(i) = extract<typename multi_array_t::element>(py_obj[ boost::python::tuple( numpy_index ) ]);
        }
        while( increment_index( i, *a ) );

        data->convertible = memory_chunk;
    }
Пример #2
0
//-------------------------------------------------------------------------
//<code(py_idp)>
//-------------------------------------------------------------------------
int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
{
  // This hook gets called from the kernel. Ensure we hold the GIL.
  PYW_GIL_GET;
  IDP_Hooks *proxy = (IDP_Hooks *)ud;
  int ret = 0;
  try
  {
    switch ( notification_code )
    {
    case processor_t::custom_ana:
      ret = proxy->custom_ana() ? 1 + cmd.size : 0;
      break;

    case processor_t::custom_out:
      ret = proxy->custom_out() ? 2 : 0;
      break;

    case processor_t::custom_emu:
      ret = proxy->custom_emu() ? 2 : 0;
      break;

    case processor_t::custom_outop:
      {
        op_t *op = va_arg(va, op_t *);
        ref_t py_obj(create_idaapi_linked_class_instance(S_PY_OP_T_CLSNAME, op));
        if ( py_obj == NULL )
          break;
        ret = proxy->custom_outop(py_obj.o) ? 2 : 0;
        break;
      }

    case processor_t::custom_mnem:
      {
        PYW_GIL_CHECK_LOCKED_SCOPE();
        PyObject *py_ret = proxy->custom_mnem();
        if ( py_ret != NULL && PyString_Check(py_ret) )
        {
          char *outbuffer = va_arg(va, char *);
          size_t bufsize  = va_arg(va, size_t);

          qstrncpy(outbuffer, PyString_AS_STRING(py_ret), bufsize);
          ret = 2;
        }
        else
        {
          ret = 0;
        }
        Py_XDECREF(py_ret);
        break;
      }

    case processor_t::is_sane_insn:
      {
        int no_crefs = va_arg(va, int);
        ret = proxy->is_sane_insn(no_crefs);
        break;
      }

    case processor_t::may_be_func:
      {
        int state = va_arg(va, int);
        ret = proxy->may_be_func(state);
        break;
      }

    case processor_t::closebase:
      {
        proxy->closebase();
        break;
      }

    case processor_t::savebase:
      {
        proxy->savebase();
        break;
      }

    case processor_t::auto_empty_finally:
      {
        proxy->auto_empty_finally();
        break;
      }

    case processor_t::rename:
      {
        ea_t ea = va_arg(va, ea_t);
        const char *new_name = va_arg(va, const char *);
        ret = proxy->rename(ea, new_name);
        break;
      }

    case processor_t::renamed:
      {
        ea_t ea = va_arg(va, ea_t);
        const char *new_name = va_arg(va, const char *);
        bool local_name = va_argi(va, bool);
        proxy->renamed(ea, new_name, local_name);
        break;
      }

    case processor_t::undefine:
      {
        ea_t ea = va_arg(va, ea_t);
        ret = proxy->undefine(ea);
        break;
      }

    case processor_t::make_code:
      {
        ea_t ea = va_arg(va, ea_t);
        asize_t size = va_arg(va, asize_t);
        ret = proxy->make_code(ea, size);
        break;
      }

    case processor_t::make_data:
      {
        ea_t ea = va_arg(va, ea_t);
        flags_t flags = va_arg(va, flags_t);
        tid_t tid = va_arg(va, tid_t);
        asize_t len = va_arg(va, asize_t);
        ret = proxy->make_data(ea, flags, tid, len);
        break;
      }

    case processor_t::load_idasgn:
      {
        const char *short_sig_name = va_arg(va, const char *);
        proxy->load_idasgn(short_sig_name);
        break;
      }

    case processor_t::auto_empty:
      {
        proxy->auto_empty();
        break;
      }

    case processor_t::auto_queue_empty:
      {
        atype_t type = va_arg(va, atype_t);
        ret = proxy->auto_queue_empty(type);
        break;
      }

    case processor_t::add_func:
      {
        func_t *func = va_arg(va, func_t *);
        proxy->add_func(func);
        break;
      }

    case processor_t::del_func:
      {
        func_t *func = va_arg(va, func_t *);
        ret = proxy->del_func(func);
        break;
      }

    case processor_t::is_call_insn:
      {
        ea_t ea = va_arg(va, ea_t);
        ret = proxy->is_call_insn(ea);
        break;
      }

    case processor_t::is_ret_insn:
      {
        ea_t ea = va_arg(va, ea_t);
        bool strict = va_argi(va, bool);
        ret = proxy->is_ret_insn(ea, strict);
        break;
      }

    case processor_t::assemble:
      {
        ea_t ea     = va_arg(va, ea_t);
        ea_t cs     = va_arg(va, ea_t);
        ea_t ip     = va_arg(va, ea_t);
        bool use32  = va_argi(va, bool);
        const char *line = va_arg(va, const char *);
        // Extract user buffer (we hardcode the MAXSTR size limit)
        uchar *bin = va_arg(va, uchar *);
        // Call python
        PYW_GIL_CHECK_LOCKED_SCOPE();
        PyObject *py_buffer = proxy->assemble(ea, cs, ip, use32, line);
        if ( py_buffer != NULL && PyString_Check(py_buffer) )
        {
          char *s;
          Py_ssize_t len;
          if ( PyString_AsStringAndSize(py_buffer, &s, &len) != -1 )
          {
            if ( len > MAXSTR )
              len = MAXSTR;
            memcpy(bin, s, len);
            ret = len;
          }
        }
        // ret = 0 otherwise
        Py_XDECREF(py_buffer);
        break;
      }
      //      validate_flirt_func,    // flirt has recognized a library function
      //      // this callback can be used by a plugin or proc module
      //      // to intercept it and validate such a function
      //      // args: ea_t start_ea
      //      //       const char *funcname
      //      // returns: -1-do not create a function,
      //      //           1-function is validated
      //      // the idp module is allowed to modify 'cmd'
      //      set_func_start,         // Function chunk start address will be changed
      //      // args: func_t *pfn
      //      //       ea_t new_start
      //      // Returns: 1-ok,<=0-do not change
      //      set_func_end,           // Function chunk end address will be changed
      //      // args: func_t *pfn
      //      //       ea_t new_end
      //      // Returns: 1-ok,<=0-do not change
      //    outlabel,               // The kernel is going to generate an instruction
      //      // label line or a function header
      //      // args:
      //      //   ea_t ea -
      //      //   const char *colored_name -
      //      // If returns value <=0, then the kernel should
      //      // not generate the label
      //      may_show_sreg,          // The kernel wants to display the segment registers
      //      // in the messages window.
      //      // arg - ea_t current_ea
      //      // if this function returns 0
      //      // then the kernel will not show
      //      // the segment registers.
      //      // (assuming that the module have done it)
      //      coagulate,              // Try to define some unexplored bytes
      //      // This notification will be called if the
      //      // kernel tried all possibilities and could
      //      // not find anything more useful than to
      //      // convert to array of bytes.
      //      // The module can help the kernel and convert
      //      // the bytes into something more useful.
      //      // arg:
      //      //      ea_t start_ea
      //      // returns: number of converted bytes + 1
      //      auto_empty,             // Info: all analysis queues are empty
      //      // args: none
      //      // returns: none
      //      // This callback is called once when the
      //      // initial analysis is finished. If the queue is
      //      // not empty upon the return from this callback,
      //      // it will be called later again.
      //      // See also auto_empty_finally.
      //      auto_queue_empty,       // One analysis queue is empty
      //      // args: atype_t type
      //      // returns: 1-yes, keep the queue empty
      //      //        <=0-no, the queue is not empty anymore
      //      // This callback can be called many times, so
      //      // only the autoMark() functions can be used from it
      //      // (other functions may work but it is not tested)
      //      func_bounds,            // find_func_bounds() finished its work
      //      // The module may fine tune the function bounds
      //      // args: int *possible_return_code
      //      //       func_t *pfn
      //      //       ea_t max_func_end_ea (from the kernel's point of view)
      //      // returns: none
      //      is_jump_func,           // is the function a trivial "jump" function?
      //      // args:  func_t *pfn
      //      //        ea_t *jump_target
      //      //        ea_t *func_pointer
      //      // returns: 0-no, 1-don't know, 2-yes, see jump_target
      //      // and func_pointer
      //      gen_regvar_def,         // generate register variable definition line
      //      // args:  regvar_t *v
      //      // returns: 0-ok
      //      setsgr,                 // The kernel has changed a segment register value
      //      // args:  ea_t startEA
      //      //        ea_t endEA
      //      //        int regnum
      //      //        sel_t value
      //      //        sel_t old_value
      //      //        uchar tag (SR_... values)
      //      // returns: 1-ok, 0-error
      //      set_compiler,           // The kernel has changed the compiler information
      //      // (inf.cc structure)
      //      is_basic_block_end,     // Is the current instruction end of a basic block?
      //      // This function should be defined for processors
      //      // with delayed jump slots. The current instruction
      //      // is stored in 'cmd'
      //      // args:  bool call_insn_stops_block
      //      // returns: 1-unknown, 0-no, 2-yes
      //      reglink,                // IBM PC only, ignore it
      //      get_vxd_name,           // IBM PC only, ignore it
      //      // Get Vxd function name
      //      // args: int vxdnum
      //      //       int funcnum
      //      //       char *outbuf
      //      // returns: nothing
      //
      //
      //      moving_segm,            // May the kernel move the segment?
      //      // args: segment_t - segment to move
      //      //       ea_t to   - new segment start address
      //      // returns: 1-yes, <=0-the kernel should stop
      //      move_segm,              // A segment is moved
      //      // Fix processor dependent address sensitive information
      //      // args: ea_t from  - old segment address
      //      //       segment_t* - moved segment
      //      // returns: nothing
      //
      //
      //      get_stkvar_scale_factor,// Should stack variable references be multiplied by
      //      // a coefficient before being used in the stack frame?
      //      // Currently used by TMS320C55 because the references into
      //      // the stack should be multiplied by 2
      //      // Returns: scaling factor
      //      // Note: PR_SCALE_STKVARS should be set to use this callback
      //
      //      create_flat_group,      // Create special segment representing the flat group
      //      // (to use for PC mainly)
      //      // args - ea_t image_base, int bitness, sel_t dataseg_sel
      //
      //      kernel_config_loaded,   // This callback is called when ida.cfg is parsed
      //      // args - none, returns - nothing
      //
      //      might_change_sp,        // Does the instruction at 'ea' modify the stack pointer?
      //      // args: ea_t ea
      //      // returns: 1-yes, 0-false
      //      // (not used yet)
      //
      //      is_alloca_probe,        // Does the function at 'ea' behave as __alloca_probe?
      //      // args: ea_t ea
      //      // returns: 2-yes, 1-false
      //
      //      out_3byte,              // Generate text representation of 3byte data
      //      // init_out_buffer() is called before this function
      //      // and all Out... function can be used.
      //      // uFlag contains the flags.
      //      // This callback might be implemented by the processor
      //      // module to generate custom representation of 3byte data.
      //      // args:
      //      // ea_t dataea - address of the data item
      //      // uint32 value - value to output
      //      // bool analyze_only - only create xrefs if necessary
      //      //              do not generate text representation
      //      // returns: 2-yes, 1-false
      //
      //      get_reg_name,           // Generate text representation of a register
      //      // int reg        - internal register number as defined in the processor module
      //      // size_t width   - register width in bytes
      //      // char *buf      - output buffer
      //      // size_t bufsize - size of output buffer
      //      // int reghi      - if not -1 then this function will return the register pair
      //      // returns: -1 if error, strlen(buf)+2 otherwise
      //      // Most processor modules do not need to implement this callback
      //      // It is useful only if ph.regNames[reg] does not provide
      //      // the correct register names
      //      // save its local data
      //      out_src_file_lnnum,     // Callback: generate analog of
      //      //   #line "file.c" 123
      //      // directive.
      //      // const char *file - source file (may be NULL)
      //      // size_t lnnum     - line number
      //      // returns: 2-directive has been generated
      //      get_autocmt,            // Callback: get dynamic auto comment
      //      // Will be called if the autocomments are enabled
      //      // and the comment retrieved from ida.int starts with
      //      // '$!'. 'cmd' is contains valid info.
      //      // char *buf  - output buffer
      //      // size_t bufsize - output buffer size
      //      // returns: 2-new comment has been generated
      //      //          1-callback has not been handled
      //      //            the buffer must not be changed in this case
      //      is_insn_table_jump,     // Callback: determine if instruction is a table jump or call
      //      // If CF_JUMP bit can not describe all kinds of table
      //      // jumps, please define this callback.
      //      // It will be called for insns with CF_JUMP bit set.
      //      // input: cmd structure contains the current instruction
      //      // returns: 1-yes, 0-no
      //      auto_empty_finally,     // Info: all analysis queues are empty definitively
      //      // args: none
      //      // returns: none
      //      // This callback is called only once.
      //      // See also auto_empty.
      //      loader_finished,        // Event: external file loader finished its work
      //      // linput_t *li
      //      // uint16 neflags
      //      // const char *filetypename
      //      // Use this event to augment the existing loader functionality
      //      loader_elf_machine,     // Event: ELF loader machine type checkpoint
      //      // linput_t *li
      //      // int machine_type
      //      // const char **p_procname
      //      // proc_def **p_pd (see ldr\elf.h)
      //      // set_elf_reloc_t *set_reloc
      //      // A plugin check the machine_type. If it is the desired one,
      //      // the the plugin fills p_procname with the processor name.
      //      // p_pd is used to handle relocations, otherwise can be left untouched
      //      // set_reloc can be later used by the plugin to specify relocations
      //      // returns: e_machine value (if it is different from the
      //      // original e_machine value, procname and p_pd will be ignored
      //      // and the new value will be used)
      //      // This event occurs for each loaded ELF file
      //      is_indirect_jump,       // Callback: determine if instruction is an indrect jump
      //      // If CF_JUMP bit can not describe all jump types
      //      // jumps, please define this callback.
      //      // input: cmd structure contains the current instruction
      //      // returns: 1-use CF_JUMP, 2-no, 3-yes
      //      verify_noreturn,        // The kernel wants to set 'noreturn' flags for a function
      //      // func_t *pfn
      //      // Returns: 1-ok, any other value-do not set 'noreturn' flag
      //      verify_sp,              // All function instructions have been analyzed
      //      // Now the processor module can analyze the stack pointer
      //      // for the whole function
      //      // input: func_t *pfn
      //      // Returns: 1-ok, 0-bad stack pointer
      //      treat_hindering_item,   // An item hinders creation of another item
      //      // args: ea_t hindering_item_ea
      //      //       flags_t new_item_flags (0 for code)
      //      //       ea_t new_item_ea
      //      //       asize_t new_item_length
      //      // Returns: 1-no reaction, <=0-the kernel may delete the hindering item
      //      str2reg,                // Convert a register name to a register number
      //      // args: const char *regname
      //      // Returns: register number + 2
      //      // The register number is the register index in the regNames array
      //      // Most processor modules do not need to implement this callback
      //      // It is useful only if ph.regNames[reg] does not provide
      //      // the correct register names
      //      create_switch_xrefs,    // Create xrefs for a custom jump table
      //      // in: ea_t jumpea;        - address of the jump insn
      //      //     switch_info_ex_t *; - switch information
      //      // returns: must return 2
      //      calc_switch_cases,      // Calculate case values and targets for a custom jump table
      //      // in:  ea_t insn_ea - address of the 'indirect jump' instruction
      //      //      switch_info_ex_t *si      - switch information
      //      //      casevec_t *casevec - vector of case values...
      //      //      evec_t *targets - ...and corresponding target addresses
      //      // casevec and targets may be NULL
      //      // returns: 2-ok, 1-failed
      //      determined_main,        // The main() function has been determined
      //      // in:  ea_t main - address of the main() function
      //      // returns: none
      //      preprocess_chart,       // gui has retrieved a function flow chart
      //      // in: qflow_chart_t *fc
      //      // returns: none
      //      // Plugins may modify the flow chart in this callback
      //      get_bg_color,           // Get item background color
      //      // in: ea_t ea, bgcolor_t *color
      //      // Returns: 1-not implemented, 2-color set
      //      // Plugins can hook this callback to color disassembly lines
      //      // dynamically
      //      get_operand_string,     // Request text string for operand (cli, java, ...)
      //      // args: int opnum
      //      //       char *buf
      //      //       size_t buflen
      //      // (cmd structure must contain info for the desired insn)
      //      // opnum is the operand number; -1 means any string operand
      //      // returns: 1 - no string (or empty string)
      //      //         >1 - original string length with terminating zero
      //
      //      // the following 5 events are very low level
      //      // take care of possible recursion
      //      add_cref,               // a code reference is being created
      //      // args: ea_t from, ea_t to, cref_t type
      //      // returns: <0 - cancel cref creation
      //      add_dref,               // a data reference is being created
      //      // args: ea_t from, ea_t to, dref_t type
      //      // returns: <0 - cancel dref creation
      //      del_cref,               // a code reference is being deleted
      //      // args: ea_t from, ea_t to, bool expand
      //      // returns: <0 - cancel cref deletion
      //      del_dref,               // a data reference is being deleted
      //      // args: ea_t from, ea_t to
      //      // returns: <0 - cancel dref deletion
      //      coagulate_dref,         // data reference is being analyzed
      //      // args: ea_t from, ea_t to, bool may_define, ea_t *code_ea
      //      // plugin may correct code_ea (e.g. for thumb mode refs, we clear the last bit)
      //      // returns: <0 - cancel dref analysis
      //      custom_fixup,           // mutipurpose notification for FIXUP_CUSTOM
      //      // args: cust_fix oper, ea_t ea, const fixup_data_t*, ... (see cust_fix)
      //      // returns: 1 - no accepted (fixup ignored by ida)
      //      //         >1 - accepted (see cust_fix)
      //      off_preproc,            // called from get_offset_expr, when refinfo_t
      //      // contain flag REFINFO_PREPROC. Normally this
      //      // notification used in a combination with custom_fixup
      //      // args: ea_t ea, int numop, ea_t* opval, const refinfo_t* ri,
      //      //       char* buf, size_t bufsize, ea_t* target,
      //      // ea_t* fullvalue, ea_t from, int getn_flags
      //      // returns: 2 - buf filled as simple expression
      //      //          3 - buf filled as complex expression
      //      //          4 - apply standard processing (with - possible - changed values)
      //      //     others - can't convert to offset expression
      //
      //      set_proc_options,       // called if the user specified an option string in the command line:
      //      //  -p<processor name>:<options>
      //      // can be used for e.g. setting a processor subtype
      //      // also called if option string is passed to set_processor_type()
      //      // and IDC's SetProcessorType()
      //      // args: const char * options
      //      // returns: <0 - bad option string
      //
    }