首页
社区
课程
招聘
[原创]IDA反编译插件的SDK
发表于: 2016-3-3 17:21 23927

[原创]IDA反编译插件的SDK

2016-3-3 17:21
23927
IDA的反编译插件的SDK,库文件通过逆向而来,在6.8和6.6中可以正常使用,其它未测试。



测试环境:Windows 7 32bit+ IDA Pro 6.8/6.6

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 457
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢楼主的分享。
2016-3-3 21:18
0
雪    币: 12332
活跃值: (5103)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
多谢楼主分享哟
2016-3-3 22:13
0
雪    币: 6
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢分享,下载试试
2016-3-3 22:36
0
雪    币: 213
活跃值: (507)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
有没有哪位试成功了?分享下经验。
2016-3-10 21:01
0
雪    币: 95
活跃值: (55)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
由于当时用的VC6编译的,没有任何问题。今天用VS2013,确实有问题。
解决1:用VC6,复制VS2013的BIN(注意备份),Include使用VS2010的(VS2010的xtree的NodePtr与VS2013不同)。LIB也用vs2010

解决2:用makefile。

CPP=cl.exe

allfile:

OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros

ALL : "$(OUTDIR)\hexrays_kai2.dll"

CLEAN :
        -@erase "$(INTDIR)\main.obj"
        -@erase "$(INTDIR)\vc60.idb"
        -@erase "$(INTDIR)\vc60.pdb"
        -@erase "$(OUTDIR)\hexrays_kai2.dll"
        -@erase "$(OUTDIR)\hexrays_kai2.exp"
        -@erase "$(OUTDIR)\hexrays_kai2.ilk"
        -@erase "$(OUTDIR)\hexrays_kai2.lib"
        -@erase "$(OUTDIR)\hexrays_kai2.pdb"

"$(OUTDIR)" :
    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

#CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HEXRAYS_KAI2_EXPORTS" /I"$(IDASDK)" /I"$(VCSDK)" /Fp"$(INTDIR)\hexrays_kai2.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
CPP_PROJ=/nologo /EHsc /MT /W3  /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HEXRAYS_KAI2_EXPORTS" /I"$(IDASDK)" /I"$(VCSDK)" /Fp"Release/hexrays_kai2.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
       
LINK32=link.exe
#LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  "msvcprt.lib"  /nologo /dll /incremental:no /pdb:"$(OUTDIR)\hexrays_kai.pdb" /machine:I386 /nodefaultlib:"LIBCMT" /out:"C:\Program Files\IDA 6.8\plugins\hexrays_kai.plw" /implib:"$(OUTDIR)\hexrays_kai.lib" /EXPORT:PLUGIN  /LIBPATH:"$(VCLIB)" /LIBPATH:"C:\Program Files\Windows Kits\8.1\Lib\winv6.3\um\x86"
LINK32_FLAGS=/OUT:"C:\Program Files\IDA 6.8\plugins\hexrays_kai.plw" /MANIFEST  /NXCOMPAT /PDB:"$(OUTDIR)\hexrays_kai.pdb" /DYNAMICBASE "ida.lib" "kernel32.lib"  "msvcprt.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /nodefaultlib:libcmt /LIBPATH:"$(VCLIB)" /LIBPATH:"$(WINDOWSSDK)" /IMPLIB:"$(OUTDIR)\hexrays_kai.lib" /DEBUG /DLL /MACHINE:X86 /OPT:REF  /INCREMENTAL:NO  /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Release\hexrays_kai12.dll.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1  /EXPORT:PLUGIN
LINK32_OBJS= \
        "$(INTDIR)\main.obj"

"$(OUTDIR)\hexrays_kai2.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
    $(LINK32) @<<
  $(LINK32_FLAGS) $(LINK32_OBJS)
<<

.c{$(INTDIR)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $<
<<

.cpp{$(INTDIR)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $<
<<

.cxx{$(INTDIR)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $<
<<

.c{$(INTDIR)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $<
<<

.cpp{$(INTDIR)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $<
<<

.cxx{$(INTDIR)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $<
<<

SOURCE=.\main.cpp

"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)"

makefile:
IDASDK=C:\we\IDAPro68\idasdk68\include
VCSDK=C:\Program Files\Microsoft Visual Studio 10.0\VC\include
VCLIB=C:\Program Files\Microsoft Visual Studio 10.0\VC\lib
WINDOWSSDK=C:\Program Files\Windows Kits\8.1\Lib\winv6.3\um\x86

include allmake

再发一个PSP的demo插件的源码(仅供参考)
mips.h
enum RegNo
{
        ZERO,AT,
        V0,V1,
        A0,A1,A2,A3,
        T0,T1,T2,T3,T4,T5,T6,T7,
        S0,S1,S2,S3,S4,S5,S6,S7,
        T8,T9,
        K0,K1,
        GP,SP,FP,RA,
        F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,F14,F15,
        F16,F17,F18,F19,F20,F21,F22,F23,F24,F25,F26,F27,F28,F29,F30,F31,
        PC,CS,DS,MIPS16,
};

#define o_fpreg o_idpspec1

main.cpp
//#pragma comment(lib,"hexray68")
/*
*  This is a sample plugin module
*
*  It can be compiled by any of the supported compilers:
*
*      - Borland C++, CBuilder, free C++
*      - Watcom C++ for DOS32
*      - Watcom C++ for OS/2
*      - Visual C++
*
*/

#define __NT__
#define __IDP__
#include <windows.h>
#include <ida.hpp>
#include <idp.hpp>
#include <expr.hpp>
#include <bytes.hpp>
#include <loader.hpp>
#include <kernwin.hpp>
#include "hexrays.hpp"
#include <gdl.hpp>
#include <allins.hpp>
#include <frame.hpp>

#pragma comment(lib,"hexray68.lib")
#pragma comment(lib,"ida")

#pragma comment(lib,"msvcrt")

//#pragma comment(lib,"libcmt")
//#pragma comment(linker,"/entry:DllEntry")
//extern plugin_t PLUGIN;

//plugin_t PLUGIN;
#include "hdr.h"
#include "mips.h"

extern "C" hexplugin_t thePlugin;

#define BADMREG 0x12345678

extern "C"
{
        tinfo_t g_tifStocks[12];
};

CBitRange tmprgRange,varregRange;

bool may_be_base(minsn_t* minsn)
{
        if(minsn->z.type!=mot_reg)
                return false;
       
        insn_t tmp=cmd;
        if(decode_prev_insn(minsn->ea)==-1)
        {
                cmd=tmp;
                return false;
        }
        switch(cmd.itype)
        {
        case MIPS_beql:
        case MIPS_beqzl:
                cmd=tmp;
                return false;
        }
        cmd=tmp;
       
        return true;
}

int idaapi mreg_to_regnum(sval_t reg, int size);
struct mipsopt_visitor_t:public mmba_visitor_t
{

        mipsopt_visitor_t(mblock_t* _mblk=NULL,minsn_t* _parentInsn=NULL):mmba_visitor_t(_mblk,_parentInsn)
        {
                dwCombineNum=0;
        }
       
       

        int dwCombineNum;
       
        virtual int visit( void )
        {
               
                switch(curinsn->mtype)
                {
                case mit_jmpindirect:
                        if(curinsn->z.is_reg(MIPS_RA))
                        {
                                curinsn->mtype=mit_retn;
                                curinsn->x.put_number(0,4);
                                curinsn->y.~mexpr_t();
                                curinsn->z.~mexpr_t();
                                dwCombineNum++;
                                return 0;
                        }
                        break;
               
                       
                }
                return 0;
        }
       
};
struct mips_combinecallback_t:public hxcombine_callback_t
{

       
        virtual int __stdcall combine( mblock_t * mblk, minsn_t * minsn)
        {
               
                mipsopt_visitor_t t(mblk,minsn);
                minsn->apply_to(&t);
                return t.dwCombineNum;
                return 0;
        }
       
}theMipsCombine;

int calc_psp_retloc(const tinfo_t * rettype,cm_t cc,argloc_t* retloc)
{
       
        if(rettype->is_void())
                return 1;
        if(rettype->is_integral()||rettype->is_enum())
        {
                if(rettype->get_size()==8)
                {
                        retloc->_set_reg2(V0,V1);
                }
                else
                {
                        retloc->_set_reg1(V0);
                }
                return 1;
        }

       
        else if(rettype->is_float())
        {
                retloc->_set_reg1(F0);
        }

        else if(rettype->is_double())
        {
                retloc->_set_reg2(V0,V1);  //PSP:V0,V1
        }
        else
        {
                retloc->_set_reg1(V0);
        }
        return 1;
}

bool calc_psp_argloc(funcarg_t* fa,int& indArg,int& fltIndArg)
{
       
       
        if(!fa->type.is_float())
        {
                bool bInt64=fa->type.get_size()==8;

                if(bInt64)
                {
                        if((indArg%2)!=0)
                                indArg++;
                }
               
                if(!bInt64)
                {
                        fa->argloc._set_reg1(A0+indArg);
                        indArg++;
                }
                else
                {
                        fa->argloc._set_reg2(A0+indArg,A0+indArg+1);
                        indArg+=2;;
                }
               
        }
        else
        {
                if(fa->type.is_float())
                {
                        //warning("calc_psp_argloc float");
                        fa->argloc._set_reg1(F12+fltIndArg);
                        fltIndArg++;
                }
                else if(fa->type.is_double())
                {
                        if((indArg%2)!=0)
                                indArg++;
                        fa->argloc._set_reg2(A0+indArg,A0+indArg+1);
                        indArg+=2;
                        //warning("calc_psp_argloc double");
                }
                else
                {
                        warning("fgghjkj");
                }
        }
       
        return true;
}

bool calc_psp_arglocs(func_type_data_t* fti)
{
       
        if(!calc_psp_retloc(&fti->rettype,fti->cc,&fti->retloc))
                return 0;
        int indArg=0;
        int nRegArg=8;
        int purge_size=0;
        int elsize=4;
        int fltIndArg=0;
        for (funcargvec_t::iterator it=fti->begin();it!=fti->end();it++)
        {
                int size=it->type.get_size();
                if(size==-1)return false;
                int size_up=align_up(size,elsize);
                if(indArg<nRegArg)
                {
                       
                        if(!calc_psp_argloc(it,indArg,fltIndArg))
                        {
                                it->argloc.set_stkoff(0x10);
                                purge_size+=8;
                                indArg++;
                        }
                }
                else
                {
                        if(1)
                        {
                                it->argloc.set_stkoff(elsize*(indArg-nRegArg));
                        }
                        else
                        {
                               
                        }

                        indArg+=size_up/elsize;
                }
        }

        if(1)
        {
                fti->stkargs=indArg<=nRegArg?0:elsize*(indArg-nRegArg);
        }
       
        return true;
}

//PSP 参数,返回值fix
int idaapi callhook_proc(void *user_data, int notification_code, va_list va)
{
       

        switch(notification_code)
        {
        case processor_t::calc_retloc3:  /////< Calculate return value location.
                ///< The kernel uses this callback only if #PR_TINFO is set.
                ///< \param rettype      (const tinfo_t *)
                ///< \param cc           (::cm_t)
                ///< \param[out] retloc  (::argloc_t *)
                ///< \return  1  not implemented
                ///< \return  2  ok,
                                ///< \return -1  error
                //break;
                {
                        const tinfo_t *rettype=va_arg(va,const tinfo_t*);
                        cm_t cc=va_arg(va,cm_t);
                        argloc_t* retloc=va_arg(va,argloc_t*);
                        return calc_psp_retloc(rettype,cc,retloc)?2:-1;
                }

        case processor_t::calc_arglocs3:
                //break;
                ///< Calculate function argument locations.
                ///< This callback should fill retloc, all arglocs, and stkargs.
                ///< This callback supersedes calc_argloc2.
                ///< This callback is never called for ::CM_CC_SPECIAL functions.
                ///< The kernel uses this callback only if #PR_TINFO is set.
                ///< \param fti  (::func_type_data_t *) points to the func type info
                ///< \retval  1  not implemented
                ///< \retval  2  ok
                                ///< \retval -1  error
                {
                        func_type_data_t* fti=va_arg(va,func_type_data_t*);
                        return calc_psp_arglocs(fti)?2:-1;
                }

        case processor_t::get_fastcall_regs3:
               
                {
                        callregs_t *callregs = va_arg(va, callregs_t *);
                        static int regs[]={A0,A1,A2,A3,T0,T1,T2,T3,-1};
                        //static int fpregs[]={T0,T1,T2,T3,-1};
                        callregs->set(ARGREGS_INDEPENDENT, regs, NULL);
                        return callregs->nregs + 2;
                }
        case processor_t::get_varcall_regs3:
       
                {
                        callregs_t *callregs = va_arg(va, callregs_t *);
                        static int regs[]={A0,A1,A2,A3,T0,T1,T2,T3,-1};
                        //static int fpregs[]={T0,T1,T2,T3,-1};
                        callregs->set(ARGREGS_INDEPENDENT, regs, NULL);
                        return callregs->nregs + 2;
                }
                //case processor_t::calc_cdecl_purged_bytes2:
                        //return 4+2;
       
        }
        return 0;
}
bool idaapi init()
{
       
        install_hxcombine_callback(&theMipsCombine);
       

        hook_to_notification_point(HT_IDP,callhook_proc,NULL);
       
        tmprgRange.combine_bit(MIPS_S0,MIPS_S7-MIPS_S0+4);
        tmprgRange.combine_bit(MIPS_T8,MIPS_T9-MIPS_T8+4);
       

       
        varregRange.combine_bit(MIPS_T4,MIPS_T5-MIPS_T4+4);
       
       
        return true;
}

void idaapi term()
{
        remove_hxcombine_callback(&theMipsCombine);
        unhook_from_notification_point(HT_IDP,callhook_proc);
}

void LoadImmOpnum(mblock_t* mblk,op_t& op,ea_t ea,char dtype,uint32 value,mreg_t loc)
{
        mexpr_t x;
        int size=get_dtyp_size(dtype);

       
        if(x.put_offset(ea,op,value,size))
        {
                mexpr_t z;
                z.set_reg(loc,size);
                mblk->build_any_insn(mit_asg,&x,NULL,&z);
        }
        else
        {
                mblk->build_samesize_insn(mit_asgconst,size,value,BADMREG,loc,op.n);
        }
}

int idaapi regnum_to_mreg(int regnum);

bool get_itype_sign(uint16 itype);

mreg_t LoadOpnum(mblock_t* mblk,insn_t* insn,mreg_t mreg,int n)
{
        op_t& op=insn->Operands[n];

        switch(op.type)
        {
        case o_void:
                return -1;
        case o_displ:
                {
                        mexpr_t addrExpr,offExpr,regExpr;

                        op_t tmpOp=op;
                        uint32 v=op.addr;
                       
                        offExpr.set_reg(MIPS_off,4);
                        bool bNeg=false;
                        if(v>=0x8000)
                        {
                                v|=0xFFFF0000;
                        }
                       
                        addrExpr.put_offset(insn->ea,op,v,4);
                       
                        mreg_t mbasereg;
                        if(op.reg==ZERO)
                        {
                                mblk->build_samesize_insn(mit_asgconst,4,0,BADMREG,mreg);
                                mbasereg=mreg;
                        }
                        else
                        {
                                mbasereg=regnum_to_mreg(op.reg);
                        }
                        regExpr.set_reg(mbasereg,4);
                       
                        mblk->build_any_insn(mit_add,&addrExpr,®Expr,&offExpr);
                }
                return MIPS_off;
       
        case o_reg:
                if(op.reg==ZERO)
                {
                        mblk->build_samesize_insn(mit_asgconst,4,0,BADMREG,mreg);
                        return mreg;
                }
                else
                {
                        return regnum_to_mreg(op.reg);
                }
        case o_fpreg:
                return regnum_to_mreg(F0+op.reg);
        case o_imm:
                {
                        uval_t v=op.value;
                        char dtyp=op.dtyp;
                       
                        switch(insn->itype)
                        {
                        case MIPS_lui:
                                v<<=16;
                                break;
                       
                               
                        case MIPS_ext:
                                if(n==3)
                                        v=(1<<v)-1;
                                break;

                        default:
                                if(dtyp==dt_word&&get_itype_sign(insn->itype))
                                {
                                        if(v>=0x8000)v|=0xFFFF0000;
                                }
                                break;

                        }
                        dtyp=dt_dword;
                       
                        LoadImmOpnum(mblk,op,insn->ea,dtyp,v,mreg);
                }
               
                return mreg;

        case o_near:
                LoadImmOpnum(mblk,op,insn->ea,dt_dword,op.addr,MIPS_off);
                return MIPS_off;
        case o_mem:
                LoadImmOpnum(mblk,op,insn->ea,dt_dword,op.addr,MIPS_off);
                return MIPS_off;
        default:
                warning("LoadOpnum %X",op.type);
        }
}
ea_t eaMemOp=BADADDR;

bool get_itype_sign(uint16 itype)
{
        switch(itype)
        {
        case MIPS_lb:
        case MIPS_lh:
        case MIPS_slt:
        case MIPS_slti:
        case MIPS_addi:
        case MIPS_addiu:
                return true;
        default:
                return false;
        }
}
mreg_t LoadInsn(mblock_t* mblk,insn_t* insn,int n)
{
       
        op_t& op=insn->Operands[n];
        mreg_t opLoc;
        switch(n)
        {
        case 0:
                opLoc=MIPS_tmp0;
                break;
        case 1:
                opLoc=MIPS_tmp1;
                break;
        case 2:
                opLoc=MIPS_tmp2;
                break;
        case 3:
                opLoc=MIPS_tmp3;
                break;
        default:
                warning("LoadInsn");
        }

       
       
        mreg_t offLoc=LoadOpnum(mblk,insn,opLoc,n);
        if(offLoc!=MIPS_off||(op.type!=o_mem&&op.type!=o_phrase&&op.type!=o_displ))
        {
               
                return offLoc;
        }
        eaMemOp=insn->ea;
       

        int size=get_dtyp_size(op.dtyp);
       
        mblk->build_samesize_insn(mit_ptr,size,MIPS_ds,MIPS_off,opLoc,4);
        if(size<4)
                mblk->build_asgop(op.dtyp,dt_dword,opLoc,opLoc,get_itype_sign(insn->itype));
       
       
        //warning("off");
        return opLoc;
}

bool SaveInsn(mblock_t* mblk,mreg_t oploc,insn_t* insn,int n)
{
       
       
       
        mreg_t mreg=MIPS_off;

        op_t& op=insn->Operands[n];
        if(eaMemOp==insn->ea&&(op.type>=o_mem&&op.type<=o_phrase))
        {
                mreg=MIPS_off;
               
        }
        else
        {
                mreg=LoadOpnum(mblk,insn,MIPS_tmpt,n);
                if(mreg==-1)
                        return false;
               
        }

       
        if(mreg==MIPS_off)
        {
                //warning("ptrrev %X=4",oploc);
                //mblk->build_asgop(dt_dword,dt_word,oploc,oploc,false);
                /*
                mexpr_t opExpr,segExpr,offExpr;
                opExpr.set_reg(oploc,4);
                segExpr.set_reg(MIPS_ds,2);
                offExpr.set_reg(MIPS_off,4);

  */

                //mblk->build_any_insn(mit_ptrrev,&opExpr,&segExpr,&offExpr);
                //warning("%X",op.type);
               
                if(op.dtyp!=dt_dword)
                {
                        mexpr_t opExpr,opExprlow;
                        opExpr.set_reg(oploc,4);
                        opExprlow.set_reg(oploc,get_dtyp_size(op.dtyp));
                        //mblk->build_any_insn(mit_low,&opExpr,NULL,&opExprlow);
                        //mblk->build_asgop(op.dtyp,dt_dword,oploc,oploc,false);
                }
               
                mblk->build_samesize_insn(mit_ptrrev,get_dtyp_size(op.dtyp),oploc,MIPS_ds,MIPS_off,4);
        }
        else if(mreg!=oploc)
        {
                //warning("asg %X,%X",mreg,oploc);
                mblk->build_samesize_insn(mit_asg,4,oploc,BADMREG,mreg);
        }

        return true;
}

ea_t eaIp=BADADDR;

int  idaapi do_microcode(mblock_t *mblk, insn_t *insn, int im);
//jump later
void do_nextmicrocode(mblock_t* mblk,int im)
{
        insn_t tmpInsn=cmd;
        decode_insn(cmd.ea+cmd.size);
        insn_t nextInsn=cmd;
        cmd=tmpInsn;
        do_microcode(mblk,&nextInsn,im);
}

enum
{
        jlt_null=0,
        jlt_jr=1,
        jlt_jcc,
        jlt_j,   //j,jal
};
struct jmplater_t
{
        jmplater_t(){reset();}
        char type;
        bool bEnable;
        union
        {
                char dummy[32];
                struct
                {
                        mreg_t mreg; //jr ra
                        bool bJalr;  //jalr
                };
               

                //jcc
                struct  
                {
                        mreg_t cndReg;
                        ea_t jccaddr;
                        bool bLikely;
                       
                };

                struct
                {
                        ea_t jmpaddr; //j,jal
                        bool bCall;
                       
                };
               
        };

        void reset()
        {
               
                type=jlt_null;
                bEnable=false;
                memset(dummy,0,sizeof(dummy));
        }
        void set_jcc(mreg_t _cndReg,ea_t _addr)
        {
                type=jlt_jcc;
                cndReg=_cndReg;
                jccaddr=_addr;
                bLikely=false;

        }

        void set_j(ea_t _addr)
        {
                type=jlt_j;
                jmpaddr=_addr;
                bCall=false;
        }
}g_jmplater;

void build_bool_op(mblock_t* mblk,insn_t* insn,minsntype_t mtype,mreg_t srcreg,char dtype,mreg_t dstreg);

bool is_mips_reg(op_t& op)
{
        return op.type==o_reg||op.type==o_fpreg;
}

bool is_asm_insn(insn_t* insn)
{
        switch(insn->itype)
        {
        case MIPS_lwr:
        case MIPS_lwl:
        case MIPS_swl:
        case MIPS_swr:
        //case MIPS_break:
                return true;
        }
        return false;
}
int  idaapi do_microcode(mblock_t *mblk, insn_t *insn, int im)
{
       
        static int stat=0;
       
        //if(insn->ea>=0x8900334&&insn->ea<0x89008B4)
        {
                uint32 feature=insn->get_canon_feature();
                mreg_t op1Loc,op2Loc,op3Loc,op4Loc;
                mreg_t cndLoc;

               
               
               
               

                if(is_asm_insn(insn))
                {
                        //mblk->mba->nothllfloat_eaList.insert(insn->ea);
                }
  
               
                if((feature&CF_USE1)||is_mips_reg(insn->Operands[0]))
                {
                        op1Loc=LoadInsn(mblk,insn,0);
                }
                else
                        op1Loc=MIPS_tmp0;

                if((feature&CF_USE2)||is_mips_reg(insn->Operands[1]))
                {
                        op2Loc=LoadInsn(mblk,insn,1);
                }
                else
                        op2Loc=MIPS_tmp1;

                if((feature&CF_USE3)||is_mips_reg(insn->Operands[2]))
                {
                        op3Loc=LoadInsn(mblk,insn,2);
                }
                else
                        op3Loc=MIPS_tmp2;

                if((feature&CF_USE4)||is_mips_reg(insn->Operands[3]))
                {
                        op4Loc=LoadInsn(mblk,insn,3);
                }
                else
                        op4Loc=MIPS_tmp3;

                if(is_asm_insn(insn))
                {
                        mblk->build_samesize_insn(mit_asm,4,-1,-1,-1);
                        return 1;
                }
                int code=MERR_BLOCK;
                const char* name;
               
                switch(insn->itype)
                {
                        //x=y
                case MIPS_lui:
                case MIPS_li:
                case MIPS_mov:
                case MIPS_lw:
                case MIPS_lh:
                case MIPS_lb:
                case MIPS_la:
                case MIPS_lbu:
                case MIPS_lhu:
                case MIPS_lwc1:
                        mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
                        break;
               
               
                case MIPS_movz:
                case MIPS_movn:
                        //movz rd,rs,rt if(rt==0)rd=rs
                        /*
                        label: if(rt!=0)jmp label+2;

                        label+1: rd=rs

                        label+2:
                        */

                        //warning("MIPS_movz %X,%X,%X",op1Loc,op2Loc,op3Loc);
                        {
                                mexpr_t zeroExpr,op3Expr,flowExpr;
                               
                                zeroExpr.put_number(0,4,-1,0);
                                op3Expr.set_reg(op3Loc,4);
                                flowExpr.set_label(mblk->label_num+2);
                                mblk->build_any_insn(insn->itype==MIPS_movz?mit_nejmp:mit_eqjmp,&op3Expr,&zeroExpr,&flowExpr);
                                //jmp后不能有指令
                                mblk=mblk->mba->append_blk(insn->ea);

                                mblk->build_samesize_insn(mit_asg,4,LoadInsn(mblk,insn,1),BADMREG,op1Loc);
                                mblk=mblk->mba->append_blk(insn->ea);
                        }
                       
                        break;
                        //y=x
                case MIPS_sw:
                case MIPS_sh:
                case MIPS_sb:
                case MIPS_swc1:
                case MIPS_mtc1:
                       
                        mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,op2Loc);
                        break;

                case MIPS_sltiu:
                case MIPS_slti:
                case MIPS_sltu:
                case MIPS_slt:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                               
                        }
                        //rt<-rs<imm rt=(rs<imm)&1

                        //mblk->build_asgop(dt_word,dt_dword,op3Loc,op3Loc,true);
                       
                        mblk->build_samesize_insn(get_itype_sign(insn->itype)?mit_slt:mit_ult,4,op2Loc,op3Loc,op1Loc);
                       
                        {
                                mexpr_t op1Expr,numExpr;
                                op1Expr.type=mot_reg;
                                op1Expr.mreg=op1Loc;
                                op1Expr.size=4;

                                numExpr.put_number(1,4,-1,0);
                                mblk->build_any_insn(mit_band,&op1Expr,&numExpr,&op1Expr);
                        }
                       
                       
                       
                        //warning("sltiu");
                        break;

                        //op1=(op2Loc>>op3Loc)&op4Loc
                case MIPS_ext:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_ushr,4,op2Loc,op3Loc,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_band,4,MIPS_tmpt,op4Loc,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_asg,4,MIPS_tmpt,BADMREG,op1Loc);
                       
                        break;

                case MIPS_srl:
                case MIPS_srlv:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_ushr,4,op2Loc,op3Loc,op1Loc);
                        break;
                case MIPS_sra:
                case MIPS_srav:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_sshr,4,op2Loc,op3Loc,op1Loc);
                        break;

                case MIPS_sll:
                case MIPS_sllv:
                       
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                       
                        mblk->build_samesize_insn(mit_shl,4,op2Loc,op3Loc,op1Loc);
                        break;

               
                       
                case MIPS_addiu:
                case MIPS_addi:
                case MIPS_addu:
                        if(insn->itype==MIPS_addi)
                        {
                                warning("MIPS_addi");
                        }
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                       
                        mblk->build_samesize_insn(mit_add,4,op2Loc,op3Loc,op1Loc);
                        //build_bool_op(mblk,insn,mit_SETP,op1Loc,dt_dword,MIPS_pf);
                        break;
                case MIPS_subu:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                       
                        mblk->build_samesize_insn(mit_sub,4,op2Loc,op3Loc,op1Loc);
                        break;
               
                case MIPS_or:
                case MIPS_ori:
                       
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                       
                        mblk->build_samesize_insn(mit_bor,4,op2Loc,op3Loc,op1Loc);

                       
                        break;
                case MIPS_nor:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_bor,4,op2Loc,op3Loc,MIPS_tmp3);
                        mblk->build_samesize_insn(mit_bnot,4,MIPS_tmp3,BADMREG,op1Loc);
                        break;
                       
                case MIPS_andi:
                case MIPS_and:

                       
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                       
                        mblk->build_samesize_insn(mit_band,4,op2Loc,op3Loc,op1Loc);
                        break;
                case MIPS_xori:
                case MIPS_xor:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                       
                        mblk->build_samesize_insn(mit_xor,4,op2Loc,op3Loc,op1Loc);
                        break;

                case MIPS_negu:
                        mblk->build_samesize_insn(mit_neg,4,op2Loc,BADMREG,op1Loc);
                        break;
                case MIPS_ins:
                        {

                                uint32 mask=((1<<insn->Operands[3].value)-1)<<insn->Operands[2].value;
                               
                                mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,MIPS_tmp4);
                                mblk->build_samesize_insn(mit_asgconst,4,mask,BADMREG,MIPS_tmpt);
                                mblk->build_samesize_insn(mit_band,4,MIPS_tmp4,MIPS_tmpt,MIPS_tmp4);

                                mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,MIPS_tmp3);
                                mblk->build_samesize_insn(mit_asgconst,4,~mask,BADMREG,MIPS_tmpt);
                                mblk->build_samesize_insn(mit_band,4,MIPS_tmp3,MIPS_tmpt,MIPS_tmp3);

                                mblk->build_samesize_insn(mit_bor,4,MIPS_tmp3,MIPS_tmp4,op1Loc);
                                break;

                        }
                        mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,op1Loc);
                        /*
                        mblk->build_samesize_insn(mit_band,4,op2Loc,op4Loc,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_band,4,op2Loc,op4Loc,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_shl,4,MIPS_tmpt,op3Loc,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_bor,4,MIPS_tmpt,op1Loc,op1Loc);
                        */
                        break;
                case PSP_max:
                case PSP_min:
                        //rd=rs>=rt?rs:rt;
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        {
                               
                               
                                mexpr_t l3Expr,l4Expr,cndExpr;
                                cndExpr.set_reg(MIPS_zf,1);
                                l3Expr.set_label(mblk->label_num+2);
                                l4Expr.set_label(mblk->label_num+3);
                               
                                mblk->build_samesize_insn(insn->itype==PSP_max?mit_sgt:mit_sle,4,op2Loc,op3Loc,MIPS_zf);
                                //break;
                                mblk->build_any_insn(mit_jcc,&cndExpr,NULL,&l3Expr);

                               
                               
                                mblk=mblk->mba->append_blk(insn->ea);
                               
                                mblk->build_samesize_insn(mit_asg,4,op3Loc,BADMREG,op1Loc);
                                //warning("");

                               
                                mblk->build_any_insn(mit_jmp,&l4Expr);

                               
                                mblk=mblk->mba->append_blk(insn->ea);
                                mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
                               
                               
                        }
                       
                        break;
                case MIPS_mult:
                case MIPS_multu:
                        {

                                bool sign=insn->itype==MIPS_mul?true:false;
                               
                                mblk->build_asgop(dt_dword,dt_qword,op1Loc,MIPS_tmp2,sign);
                                mblk->build_asgop(dt_dword,dt_qword,op2Loc,MIPS_tmp3,sign);
                        }
                       
                        op1Loc=MIPS_tmp2;
                        op2Loc=MIPS_tmp3;
                        mblk->build_samesize_insn(mit_mul,8,op1Loc,op2Loc,MIPS_LO);
                        break;
                       
                case MIPS_seb:
                case MIPS_seh:
                        mblk->build_asgop(insn->itype==MIPS_seb?dt_byte:dt_word,dt_dword,op2Loc,op1Loc,true);
                        break;
                case MIPS_mflo:
                        mblk->build_samesize_insn(mit_asg,4,MIPS_LO,BADMREG,op1Loc);
                        break;
                case MIPS_mfhi:
                        mblk->build_samesize_insn(mit_asg,4,MIPS_HI,BADMREG,op1Loc);
                        break;
                //case MIPS_fmul:
                       
                //        break;
                case MIPS_lwl:
                case MIPS_lwr:
               
                        mblk->build_samesize_insn(mit_asm,4,op1Loc,op2Loc,-1);
                        break;
                case MIPS_swl:
                case MIPS_swr:
                        //warning("%x,%x,%x",op1Loc,op2Loc,op3Loc);

                        mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,op2Loc);
                       
                        return 0;
                        break;
                case MIPS_break:
                       
                        {
                                marg_t arg;
                                arg.set_reg(op1Loc,4);
                                arg.tif=tinfo_t(BTF_INT32);
                                arg.ea=insn->ea;
                                minsn_t* p=create_fastcall_helpfunc(insn->ea,"break",tinfo_t(BT_VOID),1,&arg,false);
                                //p->z.a->flags|=8;
                               
                                //p->flags|=0x400;
                                mblk->safe_build_insn(p);
                               
                                //mblk->mba->nothllfloat_eaList.erase(insn->ea);
                        }
                        break;
                case MIPS_cache:
                        {
                                marg_t arg[2];
                                arg[0].set_reg(op1Loc,4);
                                arg[0].tif=tinfo_t(BTF_INT32);
                                arg[0].ea=insn->ea;

                                arg[1]=arg[0];
                                arg[1].set_reg(op2Loc,4);
                                minsn_t* p=create_fastcall_helpfunc(insn->ea,"cache",tinfo_t(BT_VOID),2,arg,false);
                                //p->z.a->flags|=8;
                               
                                //p->flags|=0x400;
                                mblk->safe_build_insn(p);
                               
                                //mblk->mba->nothllfloat_eaList.erase(insn->ea);
                        }
                        break;

                case MIPS_clz:
                        {
                                marg_t arg;
                                arg.set_reg(op2Loc,4);
                                arg.tif=tinfo_t(BTF_UINT32);
                                arg.ea=insn->ea;
                               
                               
                                minsn_t* p=create_fastcall_helpfunc(insn->ea,"clz",tinfo_t(BTF_UINT32),1,&arg,false);
                               
                                mexpr_t xExpr,resExpr;
                                xExpr.type=mot_insn;
                                xExpr.minsn=p;
                                xExpr.size=p->z.size;
                                resExpr.set_reg(op1Loc,4);
                                mblk->build_any_insn(mit_asg,&xExpr,NULL,&resExpr);
                               
                        }
                        break;
                case MIPS_div:
                case MIPS_divu:
                        //LO=rs/rt,HI=rs%rt
                        mblk->build_asgop(dt_dword,dt_qword,op1Loc,MIPS_tmp2,insn->itype==MIPS_div?true:false);
                        mblk->build_asgop(dt_dword,dt_qword,op2Loc,MIPS_tmp3,insn->itype==MIPS_div?true:false);
                        op1Loc=MIPS_tmp2;
                        op2Loc=MIPS_tmp3;
                        mblk->build_samesize_insn(insn->itype==MIPS_div?mit_sdiv:mit_udiv,8,op1Loc,op2Loc,MIPS_LO);
                        mblk->build_samesize_insn(insn->itype==MIPS_div?mit_smod:mit_umod,8,op1Loc,op2Loc,MIPS_HI);
                        break;

                case MIPS_fmul:
                       
                        //warning("%X,%X,%X",op1Loc,op2Loc,op3Loc);
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_fmul,4,op3Loc,op2Loc,op1Loc);
                        break;
                case MIPS_fcvt_s:
                        mblk->build_samesize_insn(mit_intfloatasg,4,op2Loc,BADMREG,op1Loc);
                        break;
                case MIPS_fdiv:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_fdiv,4,op2Loc,op3Loc,op1Loc);
                        break;
                case MIPS_mfc1:
                        //mblk->build_samesize_insn(mit_intfloatasg,4,op2Loc,BADMREG,op2Loc);
                        mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
                        //mblk->build_samesize_insn(mit_asg,4,MIPS_F0,BADMREG,MIPS_V1);
                        //mblk->build_samesize_insn(mit_add,4,op2Loc,op2Loc,op1Loc);
                        break;
                       
                case MIPS_fc_le:
                       
                        mblk->build_samesize_insn(mit_ule,4,op1Loc,op2Loc,MIPS_CC,-1);  //-1-->浮点指令
                        break;
                case MIPS_fc_eq:
                       
                        mblk->build_samesize_insn(mit_eq,4,op1Loc,op2Loc,MIPS_CC,-1);  //-1-->浮点指令
                        break;
                case MIPS_fc_lt:
                        mblk->build_samesize_insn(mit_ult,4,op1Loc,op2Loc,MIPS_CC,-1);
                        break;
                case MIPS_fmov:
                        mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
                        break;
                       
                       
                case MIPS_fadd:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_fadd,4,op2Loc,op3Loc,op1Loc);
                        break;

                case MIPS_fsub:
                        if(insn->Operands[2].type==o_void)
                        {
                                op3Loc=op2Loc;
                                op2Loc=op1Loc;
                        }
                        mblk->build_samesize_insn(mit_fsub,4,op2Loc,op3Loc,op1Loc);
                        break;

                case MIPS_fneg:
                        mblk->build_samesize_insn(mit_fneg,4,op2Loc,BADMREG,op1Loc);
                        break;
                case MIPS_fsqrt:
                        {
                                mexpr_t resExpr;
                                marg_t arg;
                                arg.set_reg(op2Loc,4);
                                arg.ea=insn->ea;
                                arg.tif=tinfo_t(BT_FLOAT);
                                minsn_t* p=create_fastcall_helpfunc(insn->ea,"sqrt",tinfo_t(BT_FLOAT),1,&arg,false);
                                resExpr.set_reg(op1Loc,4);

                                mexpr_t xExpr;
                                xExpr.type=mot_insn;
                                xExpr.minsn=p;
                                xExpr.size=p->z.size;
                                mblk->build_any_insn(mit_asg,&xExpr,NULL,&resExpr);
                               
                        }
                        break;
                case MIPS_ftrunc_w:
                        mblk->build_samesize_insn(mit_floatintasg,4,op2Loc,BADMREG,op1Loc);
                        //mblk->build_samesize_insn(mit_asgconst,4,6,BADMREG,op1Loc);
                        break;
                case MIPS_bc1t:
                case MIPS_bc1f:
                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[0].addr);
                        build_bool_op(mblk,insn,insn->itype==MIPS_bc1t?mit_ne:mit_eq,MIPS_CC,dt_byte,g_jmplater.cndReg);
                        //mblk->build_samesize_insn(mit_eq,4,MIPS_CC,op2Loc,g_jmplater.cndReg);
                        break;
                case MIPS_beq:
                       
                        //if(rs==rt) branch

                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[2].addr);
                        mblk->build_samesize_insn(mit_eq,4,op1Loc,op2Loc,g_jmplater.cndReg);
                        //code=MERR_OK;
                        break;
               
                       
                case MIPS_bne:
                       
                        //if(rs==rt) branch
                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[2].addr);
                        mblk->build_samesize_insn(mit_ne,4,op1Loc,op2Loc,g_jmplater.cndReg);
                        break;
                case MIPS_bnez:
                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
                        {
                                build_bool_op(mblk,insn,mit_ne,op1Loc,dt_dword,g_jmplater.cndReg);
                                //mblk->build_samesize_insn(mit_asgconst,4,0,BADMREG,MIPS_tmpt);
                                //mblk->build_samesize_insn(mit_ne,4,op1Loc,MIPS_tmpt,g_jmplater.cndReg);
                        }
                       
                        break;
                case MIPS_beqz:

                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_eq,op1Loc,dt_dword,g_jmplater.cndReg);
                        //mblk->build_samesize_insn(mit_asg,4,MIPS_V0,BADMREG,MIPS_A0);
                        //mblk->build_samesize_insn(mit_lnot,1,op1Loc,BADMREG,g_jmplater.cndReg);
                        //build_bool_op(mblk,insn,mit_ne,op1Loc,dt_dword,g_jmplater.cndReg);
                        //mblk->build_samesize_insn(mit_lnot,1,op1Loc,BADMREG,g_jmplater.cndReg);
                        //code=MERR_OK;
                        break;
                case MIPS_bltz:
                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
                        mblk->build_samesize_insn(mit_SETS,4,op1Loc,BADMREG,g_jmplater.cndReg);
                        break;
                case MIPS_bgtz:
                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_sgt,op1Loc,dt_dword,g_jmplater.cndReg);
                        break;

                case MIPS_bgez:
                        g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_sge,op1Loc,dt_dword,g_jmplater.cndReg);
                        break;
                case MIPS_blez:
                        //op1<=0
                        g_jmplater.set_jcc(MIPS_sf,insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_sle,op1Loc,dt_dword,g_jmplater.cndReg);
                        //mblk->build_samesize_insn(mit_SETS,1,op1Loc,BADMREG,g_jmplater.cndReg);
                        //code=MERR_OK;
                        break;

                case MIPS_bnezl:
                       
                        g_jmplater.set_j(insn->Operands[1].addr);
                        //zf=op1Loc!=0 if(!zf)jmp nextAddr
                        build_bool_op(mblk,insn,mit_ne,op1Loc,dt_dword,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;
                       
                case MIPS_beqzl:
                       
                        g_jmplater.set_j(insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_eq,op1Loc,dt_dword,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;

                case MIPS_beql:
                        g_jmplater.set_j(insn->Operands[2].addr);
                        mblk->build_samesize_insn(mit_eq,4,op1Loc,op2Loc,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;

                case MIPS_bnel:
                        g_jmplater.set_j(insn->Operands[2].addr);
                        mblk->build_samesize_insn(mit_ne,4,op1Loc,op2Loc,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;

                case MIPS_bgezl:
                        g_jmplater.set_j(insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_sge,op1Loc,dt_dword,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;

                case MIPS_blezl:
                        g_jmplater.set_j(insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_sle,op1Loc,dt_dword,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;

       
                case MIPS_bgtzl:
                        g_jmplater.set_j(insn->Operands[1].addr);
                        build_bool_op(mblk,insn,mit_sgt,op1Loc,dt_dword,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;

                case MIPS_bltzl:
                        g_jmplater.set_j(insn->Operands[1].addr);
                        mblk->build_samesize_insn(mit_SETS,4,op1Loc,BADMREG,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;

                case MIPS_bc1tl:
                        g_jmplater.set_j(insn->Operands[0].addr);
                        build_bool_op(mblk,insn,mit_ne,MIPS_CC,1,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;
                case MIPS_bc1fl:
                        g_jmplater.set_j(insn->Operands[0].addr);
                        build_bool_op(mblk,insn,mit_eq,MIPS_CC,1,MIPS_zf);
                        mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
                        mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
                        break;
                case MIPS_jal:
                case MIPS_j:
                case MIPS_b:
               
                       
                       
                       
                       
                        if(insn->itype==MIPS_jal)
                        {
                                //mblk->build_samesize_insn(mit_asgconst,4,insn->ea+8,BADMREG,MIPS_RA);
                        }
                       

                       
                        g_jmplater.set_j(insn->Operands[0].addr);
                        if(insn->itype==MIPS_jal)
                                g_jmplater.bCall=true;

                        //g_jmplater.bEnable=true;
                        //code=MERR_OK;
                        break;

                case MIPS_jr:
                case MIPS_jalr:
                        //if(op1Loc==MIPS_RA)
                        {
                                g_jmplater.type=jlt_jr;
                                g_jmplater.mreg=op1Loc;
                                if(insn->itype==MIPS_jalr||(insn->itype==MIPS_jr&&(!insn->Operands[0].is_reg(RA))))
                                        g_jmplater.bJalr=true;
                                //code=MERR_OK;
                               
                               
                               
                        }
                       
                       
                        break;

                case MIPS_nop:
                        //code=MERR_OK;
                        break;
                default:
                        warning("itype %X,%X",insn->itype,insn->ea);
                }

                bool ret=true;
               
               
                if(feature&CF_CHG1)
                {
                        if(!SaveInsn(mblk,op1Loc,insn,0))
                                ret=false;
                }

                if(feature&CF_CHG2)
                {
                        if(!SaveInsn(mblk,op2Loc,insn,1))
                                ret=false;
                       
                }
               
                if(!ret)
                {
                        mblk->mba->errea=insn->ea;
                        return MERR_INSN;
                }

               
                if(g_jmplater.bEnable)
                {
                        switch(g_jmplater.type)
                        {
                        case jlt_jr:
                                //if(g_jmplater.mreg==MIPS_RA)

                               
                               
                                if(g_jmplater.bJalr)
                                {
                                        mexpr_t segExpr,regExpr;
                                        segExpr.set_reg(MIPS_cs,4);
                                        regExpr.set_reg(g_jmplater.mreg,4);
                                        mblk->build_any_insn(mit_callindirect,&segExpr,®Expr,NULL);
                                       
                                }
                                else
                                {
                                        mblk->build_samesize_insn(mit_jmpindirect,4,BADMREG,MIPS_cs,g_jmplater.mreg,4);
                                        //mblk=mblk->mba->append_blk(insn->ea);
                                }

                               
                                if(!g_jmplater.bJalr)
                                {
                                        //mblk=mblk->mba->append_blk(insn->ea);
                                        //mblk->build_samesize_insn(mit_retn,4,0,BADMREG,BADMREG);
                                }
                                //mblk->build_samesize_insn(mit_retn,4,0,BADMREG,BADMREG);
                                //else
                                //        warning("");
                                g_jmplater.reset();
                                break;
                               
                        case jlt_jcc:
                               
                                if(g_jmplater.bLikely)
                                {
                                        mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jccaddr,BADMREG,BADMREG);

                                }
                                else
                                {
                                        //mblk->build_samesize_insn(mit_asgconst,4,g_jmplater.jccaddr,BADMREG,MIPS_off);
                                        //mblk->build_samesize_insn(mit_jccindirect,1,g_jmplater.cndReg,MIPS_ds,MIPS_off,4);
                                        mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,g_jmplater.jccaddr);
                                        //mblk=mblk->mba->append_blk(insn->ea);
                                        //mblk->build_samesize_insn(mit_jmp,4,insn->ea+4,BADMREG,BADMREG);
                                }
                                //mblk=mblk->mba->append_blk(insn->ea);
                                /*
                                mblk->build_samesize_insn(mit_lnot,1,g_jmplater.cndReg,BADMREG,g_jmplater.cndReg);
                                mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,insn->ea+insn->size);
                                //mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,g_jmplater.jccaddr);
                                //mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,g_jmplater.jccaddr);
                                mblk=mblk->mba->append_blk(insn->ea);
                                mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jccaddr,BADMREG,BADMREG);
                                //mblk->build_samesize_insn(mit_asg,4,)
                                //mblk->build_samesize_insn(mit_jmp,-1,0x12,BADMREG,BADMREG);
                                */
                                g_jmplater.reset();
                               
                                break;
                        case jlt_j:
                               
                               
                                //mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jmpaddr,BADMREG,BADMREG);
                                if(g_jmplater.bCall)
                                {
                                        /*
                                        if(build_float_func(mblk,insn,g_jmplater.jmpaddr))
                                        {
                                                g_jmplater.reset();
                                                return MERR_OK;
                                        }
                                        */
                                        mexpr_t x;
                                        x.set_obj(g_jmplater.jmpaddr,-1);
                                        mblk->build_any_insn(mit_call,&x,NULL,NULL);
                                        //mblk=mblk->mba->append_blk(insn->ea);
                                        //mblk->build_samesize_insn(mit_jmp,4,insn->ea+4,BADMREG,BADMREG);
                                        //mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jmpaddr,BADMREG,BADMREG);
                                }

                               
                                else
                                {

                                        //warning("jmp:%X",g_jmplater.jmpaddr);
                                        mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jmpaddr,BADMREG,BADMREG);
                                        mblk=mblk->mba->append_blk(insn->ea);
                                }
                                //mblk=mblk->mba->append_blk(insn->ea);
                                //mblk->build_samesize_insn(mit_asgconst,4,4,BADMREG,MIPS_V0);
                                g_jmplater.reset();
                                break;
                       
                        }
               
                }

               

                if((!g_jmplater.bEnable)&&(g_jmplater.type!=jlt_null))
                {
                       
                        g_jmplater.bEnable=true;
                }

               

               
                return code;
        }
       

       
        return MERR_OK;
}

bool calc_stkvar_offset(mbl_array_t* mba,ea_t ea,mreg_t mreg,sval_t& off)
{
        func_t* pfn=get_func(ea);
        if(!pfn)
                return false;
        if(mreg==MIPS_SP)
        {
                off+=pfn->frsize+pfn->frregs+get_effective_spd(pfn,ea)+mba->stk_delta;
                return true;
        }
       
        return false;
}

bool calcinsn_stkvar_offset(mbl_array_t* mba,minsn_t* minsn,ea_t ea,sval_t& off)
{
        mreg_t mreg=-1;
        sval_t t;
        switch(minsn->mtype)
        {
        case mit_add:
                if(minsn->x.type==mot_reg&&minsn->y.type==mot_num)
                {
                        t=minsn->y.n->value;
                        if(t<=0xFFFFFFFF)
                                mreg=minsn->x.mreg;
                        //warning("calcinsn_stkvar_offset::add reg,num");
                }

                if(minsn->y.type==mot_reg&&minsn->x.type==mot_num)
                {
                        t=minsn->x.n->value;
                        if(t<=0xFFFFFFFF)
                                mreg=minsn->y.mreg;
                }
                break;
        case mit_sub:
                if(!minsn->x.is_reg(MIPS_BP))
                        return false;
                warning("calcinsn_stkvar_offset::sub bp,");
        default:
                return false;
        }

        if(mreg==-1)
                return false;

        off=t;
        return calc_stkvar_offset(mba,ea,mreg,off);

}
bool idaapi combine_mem_expr(HEXFUNC *mba, minsn_t *minsn, mexpr_t *meSeg, mexpr_t *me2, mexpr_t *meRet, int size, int bWarn, int *bObjOff)
{
        segment_t* s=getseg(minsn->ea);
        if(s)
        {
                if(me2->size==s->abytes()&&(!meSeg||meSeg->is_reg(MIPS_ss)))
                {
                        sval_t off=0;
                        switch(me2->type)
                        {
                        case mot_reg:
                                if(!meSeg)
                                        return false;
                                if(!calc_stkvar_offset(mba,minsn->ea,me2->mreg,off)||off<0)
                                        return false;
setstkvar:
                                meRet->~mexpr_t();
                                meRet->type=mot_stkvar;
                                meRet->stkvar=new mstkvar_t(mba,off);
                                return true;

                                break;
                        case mot_num:
                                if(!meSeg)
                                        return false;
                                meRet->~mexpr_t();
                                meRet->type=mot_obj;
                                meRet->obj_ea=me2->n->value;
                                return true;
                                break;

                        case mot_insn:
                                if(!meSeg)
                                        return false;
                                //analyze_minsn(me2->minsn,true);
                                if(calcinsn_stkvar_offset(mba,me2->minsn,minsn->ea,off)&&off>=0)
                                        goto setstkvar;
                               
                               
                                break;

                        case mot_obj:
                                return false;
                               

                        case mot_ref:
                               
                                {
                                        mexpr_t t(*me2->me);
                                        meRet->swap(t);
                                }
                                return true;

                        case mot_stkvar:
                        case mot_str:
                                return false;
                        default:
                                warning("combine_mem_expr::%X",me2->type);
                        }
                }
               
               
               
        }
       
        return false;
}

struct RegDesc
{
        mreg_t mreg;
        char name[4];
        int minsize,maxsize;
}
g_RegDescs[]=
{
        MIPS_zf,"zf",1,1,
        MIPS_sf,"sf",1,1,
        MIPS_AT,"at",4,4,
        MIPS_V0,"v0",4,8,
        MIPS_V1,"v1",4,4,
        MIPS_A0,"a0",4,8,
        MIPS_A1,"a1",4,4,
        MIPS_A2,"a2",4,8,
        MIPS_A3,"a3",4,4,
        MIPS_T0,"t0",4,8,
        MIPS_T1,"t1",4,4,
        MIPS_T2,"t2",4,8,
        MIPS_T3,"t3",4,4,
        MIPS_T4,"t4",4,8,
        MIPS_T5,"t5",4,4,
        MIPS_T6,"t6",4,8,
        MIPS_T7,"t7",4,4,
        MIPS_S0,"s0",4,8,
        MIPS_S1,"s1",4,4,
        MIPS_S2,"s2",4,8,
        MIPS_S3,"s3",4,4,
        MIPS_S4,"s4",4,8,
        MIPS_S5,"s5",4,4,
        MIPS_S6,"s6",4,8,
        MIPS_S7,"s7",4,4,
        MIPS_T8,"t8",4,8,
        MIPS_T9,"t9",4,4,
        MIPS_K0,"k0",4,4,
        MIPS_K1,"k1",4,4,
        MIPS_GP,"gp",4,4,
        MIPS_SP,"sp",4,4,
        MIPS_FP,"fp",4,4,
        MIPS_RA,"ra",4,4,
        MIPS_LO,"lo",4,8,
        MIPS_HI,"hi",4,4,

        MIPS_F0,"f0",4,4,
        MIPS_F1,"f1",4,4,
        MIPS_F2,"f2",4,4,
        MIPS_F3,"f3",4,4,
        MIPS_F4,"f4",4,4,
        MIPS_F5,"f5",4,4,
        MIPS_F6,"f6",4,4,
        MIPS_F7,"f7",4,4,
        MIPS_F8,"f8",4,4,
        MIPS_F9,"f9",4,4,
        MIPS_F10,"f10",4,4,
        MIPS_F11,"f11",4,4,
        MIPS_F12,"f12",4,4,
        MIPS_F13,"f13",4,4,
        MIPS_F14,"f14",4,4,
        MIPS_F15,"f15",4,4,
        MIPS_F16,"f16",4,4,
        MIPS_F17,"f17",4,4,
        MIPS_F18,"f18",4,4,
        MIPS_F19,"f19",4,4,
        MIPS_F20,"f20",4,4,
        MIPS_F21,"f21",4,4,
        MIPS_F22,"f22",4,4,
        MIPS_F23,"f23",4,4,
        MIPS_F24,"f24",4,4,
        MIPS_F25,"f25",4,4,
        MIPS_F26,"f26",4,4,
        MIPS_F27,"f27",4,4,
        MIPS_F28,"f28",4,4,
        MIPS_F29,"f29",4,4,
        MIPS_F30,"f30",4,4,
        MIPS_F31,"f31",4,4,
        MIPS_CC,"cc",1,1,

        MIPS_tmp0,"tm0",4,8,
        MIPS_tmp1,"tm1",4,8,
        MIPS_tmp2,"tm2",4,8,
        MIPS_tmp3,"tm3",4,8,
        MIPS_tmp4,"tm4",4,8,
        MIPS_tmpt,"tmt",4,8,
        MIPS_off,"off",4,4,
        MIPS_ds,"ds",2,2,

        MIPS_maxreg,"max",0,0,

       
};

int idaapi get_mreg_minsize(mreg_t mreg)
{
       
        //warning("get_mreg_minsize");
        RegDesc* p=g_RegDescs;
        while(p->name[0]!=0)
        {
                if(p->mreg>mreg)
                        break;
                p++;
        }

        p--;
        return p->mreg==mreg?p->minsize:1;
       
        return 0;
}
int idaapi print_mreg(int mreg, int size, char *buf, int bufsize)
{
        RegDesc* p=g_RegDescs;
        do
        {
                if(p->mreg>mreg)
                        break;
                p++;
        }while(p->name[0]!=0);

       
        p--;

       
        if(size>p->maxsize)
                size=p->maxsize;
        if(buf)
        {
                qstrncpy(buf,p->name,bufsize);
               
                if(mreg!=p->mreg)
                        append_snprintf(buf,buf+bufsize,"^%d",mreg-p->mreg);
        }
        return size;
}

int idaapi do_prolog_analysis(HEXFUNC *mba, qflow_chart_t *, bitset_t *)
{
        //mba->bp_off=MIPS_BP;
        mba->field_1A8=new hxpushpopregs_t;

        func_t* pfn=get_func(mba->entry_ea);

        //fix processor  BUG
        if(pfn)
        {
                if(pfn->frsize!=mba->minspd)
                {
                        del_frame(pfn);
                        add_frame(pfn,mba->minspd,0,0);
                        return MERR_REDO;
                }
               
               
        }
        return MERR_OK;
}

bool idaapi hxcan_be_pair_x(int mreg, int size)
{
        switch(mreg)
        {
        case MIPS_tmp0:
        case MIPS_tmp1:
        case MIPS_tmp2:
        case MIPS_tmp3:
        case MIPS_tmp4:
        case MIPS_tmpt:
                return true;
        }
        if(mreg>=MIPS_maxreg)
                return true;
        if(mreg<MIPS_GPR)
                return false;
        switch(mreg)
        {
        case MIPS_V0:
        case MIPS_T0:
        case MIPS_T2:
        case MIPS_LO:
        case MIPS_A0:
        case MIPS_A2:
                return true;
        }
        return false;

       
       
        return false;
}

CBitRange& idaapi hxget_extmreg_range(void)
{
       
       
        static CBitRange ext(MIPS_tmpbeg,MIPS_tmpend-MIPS_tmpbeg);
        //LOG("hxget_extmreg_range %X::example\n",ext.get_value());
        return ext;
       
}

CBitRange& idaapi hxget_tempmreg_range(void)
{
        //warning("hxget_tempmreg_range");
        //static CBitRange r;
       
       
        return tmprgRange;
}

CBitRange& idaapi hxget_varmreg_range(void)
{
       
       
        return varregRange;
}

CBitRange& idaapi hxget_argmreg_range(void)
{
       
        //warning("hxget_argmreg_range");
        static CBitRange r;
        r.combine_bit(MIPS_A0,MIPS_T3-MIPS_A0+4);
        r.combine_bit(MIPS_F12,MIPS_F17-MIPS_F12+4);
        return r;
}

extern "C"
{
        stackarea_t g_MaxArea={0,-1};
};

void idaapi hxget_call_chg_range(HEXFUNC *mba, signed int ea, tinfo_t *tif, CBitRange *retRange, CBitRange *spoiledRange)
{

       

       
        func_type_data_t ftd;
        int nArg=-1;
        if(tif&&tif->get_func_details(&ftd))
                nArg=ftd.size();
       
       
        if(spoiledRange)
        {
                if(nArg>=0&&(ftd.flags&FTI_SPOILED))
                {
                        warning("spoil");
                        spoiledRange->cleanup();
                        for (reginfovec_t::iterator it=ftd.spoiled.begin();it<ftd.spoiled.end();it++)
                        {
                               
                                mreg_t mreg=thePlugin.regnum_to_mreg(it->reg);
                                if(mreg!=-1)
                                {
                                        spoiledRange->combine_bit(mreg,it->size);
                                }
                        }
                        spoiledRange->combine_stackarea(g_MaxArea);
                }
                else
                {

                        static CBitRange rangeArg;
                        if(rangeArg.empty())
                        {
                                rangeArg.combine_bit(MIPS_A0,MIPS_T3-MIPS_A0+4);
                                rangeArg.combine_bit(MIPS_F12,MIPS_F13-MIPS_F12+4);
                                rangeArg.combine_stackarea(g_MaxArea);
                        }
                        *spoiledRange=rangeArg;
                        //warning("hxget_call_chg_range nArg=%X,flags=%X",nArg,ftd.flags);
                        //warning("%X",tif!=0?tif->get_decltype():0x12345678);
                }
        }

        CBitRange t;
        if(nArg<0)
        {
                //t.combine_bit(MIPS_V0,MIPS_V1-MIPS_V0+4+4);
                t.combine_bit(MIPS_V0,8);
                t.combine_bit(MIPS_F0,4);
                //t.combine_bit(MIPS_V1,8);
        }
        else
        {
                int size=ftd.rettype.get_size();
                if(size!=-1)
                {
                        vdloc_t vloc=mba->aloc2vloc(ftd.retloc,size);
                        vloc.combine_range(&t,size);
                        t.field_8.clear();
                        t.ext2DWORD(size);

                       
                        //warning("hxget_call_chg_range ftd.rettype");
                }
        }

        if(spoiledRange)
        {
                spoiledRange->combine(t);
        }

        if(retRange)
        {
                qswap(*retRange,t);
        }
}

argloc_t idaapi hxget_def_retaloc(tinfo_t * tif)
{
        argloc_t aloc;
        if(tif->is_float())
        {
                aloc._set_reg1(F0);
        }
        else
        {
                aloc._set_reg1(V0);
        }
       
        return aloc;
}

bool idaapi hxand_if_retfloat(HEXFUNC *mba, mblock_t *mblk, minsn_t *minsn, CBitRange *andRange, bool *pandret)
{

       
       
       
        if(minsn)
        {
               
                return false;
        }
        else
        {
                if(mba->flags&0x10)
                {
                        msg("hxand_if_retfloat:mba->flags&0x10 %X",mba->flags);
                        return true;
                }
                if(!mba->func_type.empty())
                {
                        func_type_data_t fti;
                        if(mba->func_type.get_func_details(&fti)&&fti.rettype.is_float())
                        {
                                msg("hxand_if_retfloat float");
                                vdloc_t vloc;
                                int size=fti.rettype.get_size();
                                mba->aloc2vloc(fti.retloc,size);
                                CBitRange t;
                                vloc.combine_range(&t,size);
                                *pandret=andRange->and(t);
                                return true;
                        }
                }

                *pandret=andRange->andnot(MIPS_F0,4);
        }
        //icon
        //warning("hxand_if_retfloat");
        return false;
}

void idaapi hxcombine_with_funcargsrange(CBitRange *r)
{
       
       
        r->combine_bit(MIPS_RA,4);
       
}

bool idaapi hx_is_defcall(marglist_t *a)
{
       
        return !is_user_cc(a->cc);
       
}

int idaapi regnum_to_mreg(int regnum)
{
        switch(regnum)
        {
        case AT:
                return MIPS_AT;
        case A0:
                return MIPS_A0;
        case A1:
                return MIPS_A1;
        case A2:
                return MIPS_A2;
        case A3:
                return MIPS_A3;
        case T0:
                return MIPS_T0;
        case T1:
                return MIPS_T1;
        case T2:
                return MIPS_T2;
        case T3:
                return MIPS_T3;
        case T4:
                return MIPS_T4;
        case T5:
                return MIPS_T5;
        case T6:
                return MIPS_T6;
        case T7:
                return MIPS_T7;
        case T8:
                return MIPS_T8;
        case T9:
                return MIPS_T9;
        case S0:
                return MIPS_S0;
        case S1:
                return MIPS_S1;
        case S2:
                return MIPS_S2;
        case S3:
                return MIPS_S3;
        case S4:
                return MIPS_S4;
        case S5:
                return MIPS_S5;
        case S6:
                return MIPS_S6;
        case S7:
                return MIPS_S7;
        case V0:
                return MIPS_V0;
        case V1:
                return MIPS_V1;
        case RA:
                return MIPS_RA;
        case SP:
                return MIPS_SP;
        case FP:
                return MIPS_FP;
        case K0:
                return MIPS_K0;
        case ZERO:
                return -1;
        case F0:
                return MIPS_F0;
        case F1:
                return MIPS_F1;
        case F2:
                return MIPS_F2;
        case F3:
                return MIPS_F3;
        case F4:
                return MIPS_F4;
        case F5:
                return MIPS_F5;
        case F6:
                return MIPS_F6;
        case F7:
                return MIPS_F7;
        case F8:
                return MIPS_F8;
        case F9:
                return MIPS_F9;
        case F10:
                return MIPS_F10;
        case F11:
                return MIPS_F11;
        case F12:
                return MIPS_F12;
        case F13:
                return MIPS_F13;
        case F14:
                return MIPS_F14;
        case F15:
                return MIPS_F15;
        case F16:
                return MIPS_F16;
        case F17:
                return MIPS_F17;
        case F18:
                return MIPS_F18;
        case F19:
                return MIPS_F19;
        case F20:
                return MIPS_F20;
        case F21:
                return MIPS_F21;
        case F22:
                return MIPS_F22;
        case F23:
                return MIPS_F23;
        case F24:
                return MIPS_F24;
        case F25:
                return MIPS_F25;
        case F26:
                return MIPS_F26;
        case F27:
                return MIPS_F27;
        case F28:
                return MIPS_F28;
        case F29:
                return MIPS_F29;
        case F30:
                return MIPS_F30;
        case F31:
                return MIPS_F31;

        }

       
       
       
       
        return 0;
}

int idaapi mreg_to_regnum(sval_t reg, int size)
{
       
        if((size&(size-1))!=0)
                return -1;
        if((reg%4)!=0)
                return -1;
        switch(reg)
        {
        case MIPS_A0:
                return A0;
        case MIPS_A1:
                return A1;
        case MIPS_V0:
                return V0;
        case MIPS_V1:
                return V1;
        case MIPS_A2:
                return A2;
        case MIPS_A3:
                return A3;

        case MIPS_T0:
                return T0;
        case MIPS_T1:
                return T1;
        case MIPS_T2:
                return T2;
        case MIPS_T3:
                return T3;
        case MIPS_T4:
                return T4;
        case MIPS_T5:
                return T5;
        case MIPS_T7:
                return T7;
        case MIPS_T8:
                return T8;
        case MIPS_T9:
                return T9;
        case MIPS_S0:
                return S0;
        case MIPS_S1:
                return S1;
        case MIPS_S2:
                return S2;
        case MIPS_S3:
                return S3;
        case MIPS_S4:
                return S4;
        case MIPS_S5:
                return S5;
        case MIPS_S6:
                return S6;
        case MIPS_S7:
                return S7;
                       
       
                       

        case MIPS_RA:
                return RA;
        case MIPS_SP:
                return SP;
        case MIPS_FP:
                return FP;
        case MIPS_K0:
                return K0;
               
        case MIPS_F0:
                return F0;
        case MIPS_F1:
                return F1;
        case MIPS_F2:
                return F2;
        case MIPS_F3:
                return F3;
        case MIPS_F4:
                return F4;
        case MIPS_F5:
                return F5;
        case MIPS_F6:
                return F6;
        case MIPS_F7:
                return F7;
        case MIPS_F8:
                return F8;
        case MIPS_F9:
                return F9;
        case MIPS_F10:
                return F10;
        case MIPS_F11:
                return F11;
        case MIPS_F12:
                return F12;
        case MIPS_F13:
                return F13;
        case MIPS_F14:
                return F14;
        case MIPS_F15:
                return F15;
        case MIPS_F16:
                return F16;
        case MIPS_F17:
                return F17;
        case MIPS_F18:
                return F18;
        case MIPS_F19:
                return F19;
        case MIPS_F20:
                return F20;
        case MIPS_F21:
                return F21;
        case MIPS_F22:
                return F22;
        case MIPS_F23:
                return F23;
        case MIPS_F24:
                return F24;
        case MIPS_F25:
                return F25;
        case MIPS_F26:
                return F26;
        case MIPS_F27:
                return F27;
        case MIPS_F28:
                return F28;
        case MIPS_F29:
                return F29;
        case MIPS_F30:
                return F30;
        case MIPS_F31:
                return F31;
       
       
        }
       
        return -1;
}

argloc_t idaapi mreg_to_argloc(int mreg, int size)
{
        argloc_t aloc;
        int reg;

       
        if(size==8)
        {
                int reg1,reg2;
                reg1=mreg_to_regnum(mreg,4);
                reg2=mreg_to_regnum(mreg+4,4);
                QASSERT(50513,reg1!=-1&®2!=-1);
               
                aloc._set_reg2(reg1,reg2);
               
        }

        else
        {
                reg=mreg_to_regnum(mreg,size);
                if(reg!=-1)
                        aloc._set_reg1(reg);
        }
       
       
       
       
        return aloc;
}

int idaapi mregnum_align_down(sval_t mreg)
{
       

       
        if(mreg>=MIPS_GPR&&mreg<MIPS_tmpbeg)
                mreg&=0xFFFFFFFC;
        return mreg;
       
        switch(mreg)
        {
        case MIPS_A0:
        case MIPS_A1:
        case MIPS_A2:
        case MIPS_A3:
        case MIPS_V0:
        case MIPS_V1:
        case MIPS_T0:
        case MIPS_T1:
        case MIPS_T2:
        case MIPS_T3:
        case MIPS_S0:
        case MIPS_RA:
                return mreg;
        }
       
       
        return 0;
}

bool idaapi hxis_fltmreg(sval_t mreg)
{
       
       
        return mreg>=MIPS_F0&&mreg<MIPS_F31+4;
}

bool idaapi hxcan_advance_reg(int mreg)
{
       
       
        if(mreg>=MIPS_F0&&mreg<MIPS_F31+4)
                return false;
       
}

bool idaapi hxcan_be_regarg(int mreg)
{
       
       
        switch(mreg)
        {
        case MIPS_A0:
        case MIPS_A1:
        case MIPS_A2:
        case MIPS_A3:
        case MIPS_T0:
        case MIPS_T1:
        case MIPS_T2:
        case MIPS_T3:
        case MIPS_F0:
        case MIPS_F1:
        case MIPS_F2:
                return true;
        }

       
        return false;
}

bool idaapi hxis_use_reg(int reg, ea_t ea, ea_t maxea)
{
       
       
        mreg_t mreg=regnum_to_mreg(reg);
        for (;ea<maxea;ea=nextthat(ea,maxea,f_isCode,NULL))
        {
                if(decode_insn(ea))
                {
                        for(int n=0;n<6;n++)
                        {
                                op_t& op=cmd.Operands[n];
                                switch(op.type)
                                {
                                case o_reg:
                                        //warning("hxis_use_reg reg");
                                        if(mreg==regnum_to_mreg(op.reg))
                                                return true;
                                        break;
                                case o_mem:
                                        break;
                                case o_phrase:
                               
                                        warning("hxis_use_reg mem");
                                        break;

                                case o_displ:
                                        if(mreg==regnum_to_mreg(op.reg))
                                                return true;
                                       
                                }
                        }
                }
        }
        return false;
}

int idaapi hxget_access_reg(int mreg)
{
       
        return mreg;
        return 0;
}

bool idaapi hxis_segrg(int mreg)
{
       
        return mreg==MIPS_ds||mreg==MIPS_ss||mreg==MIPS_cs;
        return false;
}

extern "C" hexplugin_t thePlugin=
{
        PLFM_MIPS,   //id
        "hexarm",    //name
        0x35B,
        //0x1B44,                 //flags
        MIPS_ds,        //ds
        MIPS_ss,        //ss
        MIPS_SP,        //sp
        MIPS_cs,        //cs
        MIPS_regext,        //regext
        MIPS_maxreg,        //fps
        8,                        //dummy
        0x100000,        //eaHole
        init,                //init
        term,                //term
        do_microcode,
        combine_mem_expr,
        NULL,
        get_mreg_minsize,
        print_mreg,
        NULL,
        do_prolog_analysis,

        NULL,
        NULL,
        NULL,
        NULL,

       
        hxcan_be_pair_x,
        hxget_extmreg_range,
        hxget_tempmreg_range,
        hxget_varmreg_range,
        hxget_argmreg_range,
        hxget_call_chg_range,
        hxget_def_retaloc,
        NULL,
       
        hxcombine_with_funcargsrange,
        NULL,
        hx_is_defcall,
        NULL,
        NULL,
       
        NULL,

        regnum_to_mreg,
        mreg_to_regnum,
        mreg_to_argloc,
        mregnum_align_down,
        NULL,

        hxis_fltmreg,
        hxcan_advance_reg,
        hxcan_be_regarg,
        NULL,

        hxis_use_reg,
        NULL,
        hxget_access_reg,
        hxis_segrg,
        NULL,

        NULL,
        NULL,

        NULL,
        NULL,
        NULL,
};

正常情况应该可以通过编译。

PS:活用Specify switch idiom,MIPS的宏指令可能会导致反编译失败,
2016-3-11 22:36
0
雪    币: 213
活跃值: (507)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
何不放一个编译好的BIN供大家一试
2016-3-12 22:09
0
雪    币: 95
活跃值: (55)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
http://pan.baidu.com/s/1jHc9pno

hxand_if_retfloat函数漏掉了,加上。
2016-3-13 10:19
0
雪    币: 130
活跃值: (71)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
hexray68.lib 哪来的?
2016-5-26 09:21
0
雪    币: 229
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢分享!
2016-6-12 22:46
0
雪    币: 210
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
谢谢xross

正在弄一个环境
2016-6-13 19:11
0
雪    币: 76
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
怎么使用的  大神
2016-7-4 12:44
0
雪    币: 2708
活跃值: (2128)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
牛逼,都不知道怎么玩。
2017-3-14 23:12
0
雪    币: 135
活跃值: (719)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
demo是mips的decompiler演示么?
2017-3-15 07:57
0
雪    币: 135
活跃值: (719)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
xross http://pan.baidu.com/s/1jHc9pno hxand_if_retfloat函数漏掉了,加上。
试用了一下,非常棒!虽然生成的代码没优化,但好歹生成了伪C代码。 楼主是通过逆向x86之类已有的decompiler得到的lib文件?很好奇怎么由二进制文件变成lib(.obj)文件呢?是先逆成C再编译的么? 基本插件的差异代码居然这么少!另外,头文件与6.8sdk头文件中,有个类多了一个成员函数?
2017-3-15 17:54
0
游客
登录 | 注册 方可回帖
返回
//