| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903 | using System;using System.Runtime.InteropServices;namespace DotNetDetour{    /// <summary>    /// 用于计算汇编指令长度,使用的是BlackBone的LDasm.c中的算法,我把他翻译成C#了    /// </summary>    public unsafe class LDasm    {        const int F_INVALID = 0x01;        const int F_PREFIX = 0x02;        const int F_REX = 0x04;        const int F_MODRM = 0x08;        const int F_SIB = 0x10;        const int F_DISP = 0x20;        const int F_IMM = 0x40;        const int F_RELATIVE = 0x80;        const int OP_NONE = 0x00;        const int OP_INVALID = 0x80;        const int OP_DATA_I8 = 0x01;        const int OP_DATA_I16 = 0x02;        const int OP_DATA_I16_I32 = 0x04;        const int OP_DATA_I16_I32_I64 = 0x08;        const int OP_EXTENDED = 0x10;        const int OP_RELATIVE = 0x20;        const int OP_MODRM = 0x40;        const int OP_PREFIX = 0x80;        struct ldasm_data        {            public byte flags;            public byte rex;            public byte modrm;            public byte sib;            public byte opcd_offset;            public byte opcd_size;            public byte disp_offset;            public byte disp_size;            public byte imm_offset;            public byte imm_size;        }        static byte[] flags_table =        {            /* 00 */    OP_MODRM,            /* 01 */    OP_MODRM,            /* 02 */    OP_MODRM,            /* 03 */    OP_MODRM,            /* 04 */    OP_DATA_I8,            /* 05 */    OP_DATA_I16_I32,            /* 06 */    OP_NONE,            /* 07 */    OP_NONE,            /* 08 */    OP_MODRM,            /* 09 */    OP_MODRM,            /* 0A */    OP_MODRM,            /* 0B */    OP_MODRM,            /* 0C */    OP_DATA_I8,            /* 0D */    OP_DATA_I16_I32,            /* 0E */    OP_NONE,            /* 0F */    OP_NONE,                /* 10 */    OP_MODRM,            /* 11 */    OP_MODRM,            /* 12 */    OP_MODRM,            /* 13 */    OP_MODRM,            /* 14 */    OP_DATA_I8,            /* 15 */    OP_DATA_I16_I32,            /* 16 */    OP_NONE,            /* 17 */    OP_NONE,            /* 18 */    OP_MODRM,            /* 19 */    OP_MODRM,            /* 1A */    OP_MODRM,            /* 1B */    OP_MODRM,            /* 1C */    OP_DATA_I8,            /* 1D */    OP_DATA_I16_I32,            /* 1E */    OP_NONE,            /* 1F */    OP_NONE,                /* 20 */    OP_MODRM,            /* 21 */    OP_MODRM,            /* 22 */    OP_MODRM,            /* 23 */    OP_MODRM,            /* 24 */    OP_DATA_I8,            /* 25 */    OP_DATA_I16_I32,            /* 26 */    OP_PREFIX,            /* 27 */    OP_NONE,            /* 28 */    OP_MODRM,            /* 29 */    OP_MODRM,            /* 2A */    OP_MODRM,            /* 2B */    OP_MODRM,            /* 2C */    OP_DATA_I8,            /* 2D */    OP_DATA_I16_I32,            /* 2E */    OP_PREFIX,            /* 2F */    OP_NONE,                /* 30 */    OP_MODRM,            /* 31 */    OP_MODRM,            /* 32 */    OP_MODRM,            /* 33 */    OP_MODRM,            /* 34 */    OP_DATA_I8,            /* 35 */    OP_DATA_I16_I32,            /* 36 */    OP_PREFIX,            /* 37 */    OP_NONE,            /* 38 */    OP_MODRM,            /* 39 */    OP_MODRM,            /* 3A */    OP_MODRM,            /* 3B */    OP_MODRM,            /* 3C */    OP_DATA_I8,            /* 3D */    OP_DATA_I16_I32,            /* 3E */    OP_PREFIX,            /* 3F */    OP_NONE,                /* 40 */    OP_NONE,            /* 41 */    OP_NONE,            /* 42 */    OP_NONE,            /* 43 */    OP_NONE,            /* 44 */    OP_NONE,            /* 45 */    OP_NONE,            /* 46 */    OP_NONE,            /* 47 */    OP_NONE,            /* 48 */    OP_NONE,            /* 49 */    OP_NONE,            /* 4A */    OP_NONE,            /* 4B */    OP_NONE,            /* 4C */    OP_NONE,            /* 4D */    OP_NONE,            /* 4E */    OP_NONE,            /* 4F */    OP_NONE,                /* 50 */    OP_NONE,            /* 51 */    OP_NONE,            /* 52 */    OP_NONE,            /* 53 */    OP_NONE,            /* 54 */    OP_NONE,            /* 55 */    OP_NONE,            /* 56 */    OP_NONE,            /* 57 */    OP_NONE,            /* 58 */    OP_NONE,            /* 59 */    OP_NONE,            /* 5A */    OP_NONE,            /* 5B */    OP_NONE,            /* 5C */    OP_NONE,            /* 5D */    OP_NONE,            /* 5E */    OP_NONE,            /* 5F */    OP_NONE,            /* 60 */    OP_NONE,                /* 61 */    OP_NONE,            /* 62 */    OP_MODRM,            /* 63 */    OP_MODRM,            /* 64 */    OP_PREFIX,            /* 65 */    OP_PREFIX,            /* 66 */    OP_PREFIX,            /* 67 */    OP_PREFIX,            /* 68 */    OP_DATA_I16_I32,            /* 69 */    OP_MODRM | OP_DATA_I16_I32,            /* 6A */    OP_DATA_I8,            /* 6B */    OP_MODRM | OP_DATA_I8,            /* 6C */    OP_NONE,            /* 6D */    OP_NONE,            /* 6E */    OP_NONE,            /* 6F */    OP_NONE,                /* 70 */    OP_RELATIVE | OP_DATA_I8,            /* 71 */    OP_RELATIVE | OP_DATA_I8,            /* 72 */    OP_RELATIVE | OP_DATA_I8,            /* 73 */    OP_RELATIVE | OP_DATA_I8,            /* 74 */    OP_RELATIVE | OP_DATA_I8,            /* 75 */    OP_RELATIVE | OP_DATA_I8,            /* 76 */    OP_RELATIVE | OP_DATA_I8,            /* 77 */    OP_RELATIVE | OP_DATA_I8,            /* 78 */    OP_RELATIVE | OP_DATA_I8,            /* 79 */    OP_RELATIVE | OP_DATA_I8,            /* 7A */    OP_RELATIVE | OP_DATA_I8,            /* 7B */    OP_RELATIVE | OP_DATA_I8,            /* 7C */    OP_RELATIVE | OP_DATA_I8,            /* 7D */    OP_RELATIVE | OP_DATA_I8,            /* 7E */    OP_RELATIVE | OP_DATA_I8,            /* 7F */    OP_RELATIVE | OP_DATA_I8,                /* 80 */    OP_MODRM | OP_DATA_I8,            /* 81 */    OP_MODRM | OP_DATA_I16_I32,            /* 82 */    OP_MODRM | OP_DATA_I8,            /* 83 */    OP_MODRM | OP_DATA_I8,            /* 84 */    OP_MODRM,            /* 85 */    OP_MODRM,            /* 86 */    OP_MODRM,            /* 87 */    OP_MODRM,            /* 88 */    OP_MODRM,            /* 89 */    OP_MODRM,            /* 8A */    OP_MODRM,            /* 8B */    OP_MODRM,            /* 8C */    OP_MODRM,            /* 8D */    OP_MODRM,            /* 8E */    OP_MODRM,            /* 8F */    OP_MODRM,                /* 90 */    OP_NONE,            /* 91 */    OP_NONE,            /* 92 */    OP_NONE,            /* 93 */    OP_NONE,            /* 94 */    OP_NONE,            /* 95 */    OP_NONE,            /* 96 */    OP_NONE,            /* 97 */    OP_NONE,            /* 98 */    OP_NONE,            /* 99 */    OP_NONE,            /* 9A */    OP_DATA_I16 | OP_DATA_I16_I32,            /* 9B */    OP_NONE,            /* 9C */    OP_NONE,            /* 9D */    OP_NONE,            /* 9E */    OP_NONE,            /* 9F */    OP_NONE,                /* A0 */    OP_DATA_I8,            /* A1 */    OP_DATA_I16_I32_I64,            /* A2 */    OP_DATA_I8,            /* A3 */    OP_DATA_I16_I32_I64,            /* A4 */    OP_NONE,            /* A5 */    OP_NONE,            /* A6 */    OP_NONE,            /* A7 */    OP_NONE,            /* A8 */    OP_DATA_I8,            /* A9 */    OP_DATA_I16_I32,            /* AA */    OP_NONE,            /* AB */    OP_NONE,            /* AC */    OP_NONE,            /* AD */    OP_NONE,            /* AE */    OP_NONE,            /* AF */    OP_NONE,                /* B0 */    OP_DATA_I8,            /* B1 */    OP_DATA_I8,            /* B2 */    OP_DATA_I8,            /* B3 */    OP_DATA_I8,            /* B4 */    OP_DATA_I8,            /* B5 */    OP_DATA_I8,            /* B6 */    OP_DATA_I8,            /* B7 */    OP_DATA_I8,            /* B8 */    OP_DATA_I16_I32_I64,            /* B9 */    OP_DATA_I16_I32_I64,            /* BA */    OP_DATA_I16_I32_I64,            /* BB */    OP_DATA_I16_I32_I64,            /* BC */    OP_DATA_I16_I32_I64,            /* BD */    OP_DATA_I16_I32_I64,            /* BE */    OP_DATA_I16_I32_I64,            /* BF */    OP_DATA_I16_I32_I64,                /* C0 */    OP_MODRM | OP_DATA_I8,            /* C1 */    OP_MODRM | OP_DATA_I8,            /* C2 */    OP_DATA_I16,            /* C3 */    OP_NONE,            /* C4 */    OP_MODRM,            /* C5 */    OP_MODRM,            /* C6 */    OP_MODRM | OP_DATA_I8,            /* C7 */    OP_MODRM | OP_DATA_I16_I32,            /* C8 */    OP_DATA_I8 | OP_DATA_I16,            /* C9 */    OP_NONE,            /* CA */    OP_DATA_I16,            /* CB */    OP_NONE,            /* CC */    OP_NONE,            /* CD */    OP_DATA_I8,            /* CE */    OP_NONE,            /* CF */    OP_NONE,                /* D0 */    OP_MODRM,            /* D1 */    OP_MODRM,            /* D2 */    OP_MODRM,            /* D3 */    OP_MODRM,            /* D4 */    OP_DATA_I8,            /* D5 */    OP_DATA_I8,            /* D6 */    OP_NONE,            /* D7 */    OP_NONE,            /* D8 */    OP_MODRM,            /* D9 */    OP_MODRM,            /* DA */    OP_MODRM,            /* DB */    OP_MODRM,            /* DC */    OP_MODRM,            /* DD */    OP_MODRM,            /* DE */    OP_MODRM,            /* DF */    OP_MODRM,                /* E0 */    OP_RELATIVE | OP_DATA_I8,            /* E1 */    OP_RELATIVE | OP_DATA_I8,            /* E2 */    OP_RELATIVE | OP_DATA_I8,            /* E3 */    OP_RELATIVE | OP_DATA_I8,            /* E4 */    OP_DATA_I8,            /* E5 */    OP_DATA_I8,            /* E6 */    OP_DATA_I8,            /* E7 */    OP_DATA_I8,            /* E8 */    OP_RELATIVE | OP_DATA_I16_I32,            /* E9 */    OP_RELATIVE | OP_DATA_I16_I32,            /* EA */    OP_DATA_I16 | OP_DATA_I16_I32,            /* EB */    OP_RELATIVE | OP_DATA_I8,            /* EC */    OP_NONE,            /* ED */    OP_NONE,            /* EE */    OP_NONE,            /* EF */    OP_NONE,                /* F0 */    OP_PREFIX,            /* F1 */    OP_NONE,            /* F2 */    OP_PREFIX,            /* F3 */    OP_PREFIX,            /* F4 */    OP_NONE,            /* F5 */    OP_NONE,            /* F6 */    OP_MODRM,            /* F7 */    OP_MODRM,            /* F8 */    OP_NONE,            /* F9 */    OP_NONE,            /* FA */    OP_NONE,            /* FB */    OP_NONE,            /* FC */    OP_NONE,            /* FD */    OP_NONE,            /* FE */    OP_MODRM,            /* FF */    OP_MODRM        };        static byte[] flags_table_ex =        {            /* 0F00 */    OP_MODRM,            /* 0F01 */    OP_MODRM,            /* 0F02 */    OP_MODRM,            /* 0F03 */    OP_MODRM,            /* 0F04 */    OP_INVALID,            /* 0F05 */    OP_NONE,            /* 0F06 */    OP_NONE,            /* 0F07 */    OP_NONE,            /* 0F08 */    OP_NONE,            /* 0F09 */    OP_NONE,            /* 0F0A */    OP_INVALID,            /* 0F0B */    OP_NONE,            /* 0F0C */    OP_INVALID,            /* 0F0D */    OP_MODRM,            /* 0F0E */    OP_INVALID,            /* 0F0F */    OP_MODRM | OP_DATA_I8,        //3Dnow                /* 0F10 */    OP_MODRM,            /* 0F11 */    OP_MODRM,            /* 0F12 */    OP_MODRM,            /* 0F13 */    OP_MODRM,            /* 0F14 */    OP_MODRM,            /* 0F15 */    OP_MODRM,            /* 0F16 */    OP_MODRM,            /* 0F17 */    OP_MODRM,            /* 0F18 */    OP_MODRM,            /* 0F19 */    OP_INVALID,            /* 0F1A */    OP_INVALID,            /* 0F1B */    OP_INVALID,            /* 0F1C */    OP_INVALID,            /* 0F1D */    OP_INVALID,            /* 0F1E */    OP_INVALID,            /* 0F1F */    OP_NONE,                /* 0F20 */    OP_MODRM,            /* 0F21 */    OP_MODRM,            /* 0F22 */    OP_MODRM,            /* 0F23 */    OP_MODRM,            /* 0F24 */    OP_MODRM | OP_EXTENDED,        //SSE5            /* 0F25 */    OP_INVALID,            /* 0F26 */    OP_MODRM,            /* 0F27 */    OP_INVALID,            /* 0F28 */    OP_MODRM,            /* 0F29 */    OP_MODRM,            /* 0F2A */    OP_MODRM,            /* 0F2B */    OP_MODRM,            /* 0F2C */    OP_MODRM,            /* 0F2D */    OP_MODRM,            /* 0F2E */    OP_MODRM,            /* 0F2F */    OP_MODRM,                /* 0F30 */    OP_NONE,            /* 0F31 */    OP_NONE,            /* 0F32 */    OP_NONE,            /* 0F33 */    OP_NONE,            /* 0F34 */    OP_NONE,            /* 0F35 */    OP_NONE,            /* 0F36 */    OP_INVALID,            /* 0F37 */    OP_NONE,            /* 0F38 */    OP_MODRM | OP_EXTENDED,             /* 0F39 */    OP_INVALID,            /* 0F3A */    OP_MODRM | OP_EXTENDED | OP_DATA_I8,            /* 0F3B */    OP_INVALID,            /* 0F3C */    OP_INVALID,            /* 0F3D */    OP_INVALID,            /* 0F3E */    OP_INVALID,            /* 0F3F */    OP_INVALID,                /* 0F40 */    OP_MODRM,            /* 0F41 */    OP_MODRM,            /* 0F42 */    OP_MODRM,            /* 0F43 */    OP_MODRM,            /* 0F44 */    OP_MODRM,            /* 0F45 */    OP_MODRM,            /* 0F46 */    OP_MODRM,            /* 0F47 */    OP_MODRM,            /* 0F48 */    OP_MODRM,            /* 0F49 */    OP_MODRM,            /* 0F4A */    OP_MODRM,            /* 0F4B */    OP_MODRM,            /* 0F4C */    OP_MODRM,            /* 0F4D */    OP_MODRM,            /* 0F4E */    OP_MODRM,            /* 0F4F */    OP_MODRM,                /* 0F50 */    OP_MODRM,            /* 0F51 */    OP_MODRM,            /* 0F52 */    OP_MODRM,            /* 0F53 */    OP_MODRM,            /* 0F54 */    OP_MODRM,            /* 0F55 */    OP_MODRM,            /* 0F56 */    OP_MODRM,            /* 0F57 */    OP_MODRM,            /* 0F58 */    OP_MODRM,            /* 0F59 */    OP_MODRM,            /* 0F5A */    OP_MODRM,            /* 0F5B */    OP_MODRM,            /* 0F5C */    OP_MODRM,            /* 0F5D */    OP_MODRM,            /* 0F5E */    OP_MODRM,            /* 0F5F */    OP_MODRM,                /* 0F60 */    OP_MODRM,            /* 0F61 */    OP_MODRM,            /* 0F62 */    OP_MODRM,            /* 0F63 */    OP_MODRM,            /* 0F64 */    OP_MODRM,            /* 0F65 */    OP_MODRM,            /* 0F66 */    OP_MODRM,            /* 0F67 */    OP_MODRM,            /* 0F68 */    OP_MODRM,            /* 0F69 */    OP_MODRM,            /* 0F6A */    OP_MODRM,            /* 0F6B */    OP_MODRM,            /* 0F6C */    OP_MODRM,            /* 0F6D */    OP_MODRM,            /* 0F6E */    OP_MODRM,            /* 0F6F */    OP_MODRM,                /* 0F70 */    OP_MODRM | OP_DATA_I8,            /* 0F71 */    OP_MODRM | OP_DATA_I8,            /* 0F72 */    OP_MODRM | OP_DATA_I8,            /* 0F73 */    OP_MODRM | OP_DATA_I8,            /* 0F74 */    OP_MODRM,            /* 0F75 */    OP_MODRM,            /* 0F76 */    OP_MODRM,            /* 0F77 */    OP_NONE,            /* 0F78 */    OP_MODRM,            /* 0F79 */    OP_MODRM,            /* 0F7A */    OP_INVALID,            /* 0F7B */    OP_INVALID,            /* 0F7C */    OP_MODRM,            /* 0F7D */    OP_MODRM,            /* 0F7E */    OP_MODRM,            /* 0F7F */    OP_MODRM,                /* 0F80 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F81 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F82 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F83 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F84 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F85 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F86 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F87 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F88 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F89 */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F8A */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F8B */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F8C */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F8D */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F8E */    OP_RELATIVE | OP_DATA_I16_I32,            /* 0F8F */    OP_RELATIVE | OP_DATA_I16_I32,                /* 0F90 */    OP_MODRM,            /* 0F91 */    OP_MODRM,            /* 0F92 */    OP_MODRM,            /* 0F93 */    OP_MODRM,            /* 0F94 */    OP_MODRM,            /* 0F95 */    OP_MODRM,            /* 0F96 */    OP_MODRM,            /* 0F97 */    OP_MODRM,            /* 0F98 */    OP_MODRM,            /* 0F99 */    OP_MODRM,            /* 0F9A */    OP_MODRM,            /* 0F9B */    OP_MODRM,            /* 0F9C */    OP_MODRM,            /* 0F9D */    OP_MODRM,            /* 0F9E */    OP_MODRM,            /* 0F9F */    OP_MODRM,                /* 0FA0 */    OP_NONE,            /* 0FA1 */    OP_NONE,            /* 0FA2 */    OP_NONE,            /* 0FA3 */    OP_MODRM,            /* 0FA4 */    OP_MODRM | OP_DATA_I8,            /* 0FA5 */    OP_MODRM,            /* 0FA6 */    OP_INVALID,            /* 0FA7 */    OP_INVALID,            /* 0FA8 */    OP_NONE,            /* 0FA9 */    OP_NONE,            /* 0FAA */    OP_NONE,            /* 0FAB */    OP_MODRM,            /* 0FAC */    OP_MODRM | OP_DATA_I8,            /* 0FAD */    OP_MODRM,            /* 0FAE */    OP_MODRM,            /* 0FAF */    OP_MODRM,                /* 0FB0 */    OP_MODRM,            /* 0FB1 */    OP_MODRM,            /* 0FB2 */    OP_MODRM,            /* 0FB3 */    OP_MODRM,            /* 0FB4 */    OP_MODRM,            /* 0FB5 */    OP_MODRM,            /* 0FB6 */    OP_MODRM,            /* 0FB7 */    OP_MODRM,            /* 0FB8 */    OP_MODRM,            /* 0FB9 */    OP_MODRM,            /* 0FBA */    OP_MODRM | OP_DATA_I8,            /* 0FBB */    OP_MODRM,            /* 0FBC */    OP_MODRM,            /* 0FBD */    OP_MODRM,            /* 0FBE */    OP_MODRM,            /* 0FBF */    OP_MODRM,                /* 0FC0 */    OP_MODRM,            /* 0FC1 */    OP_MODRM,            /* 0FC2 */    OP_MODRM | OP_DATA_I8,            /* 0FC3 */    OP_MODRM,            /* 0FC4 */    OP_MODRM | OP_DATA_I8,            /* 0FC5 */    OP_MODRM | OP_DATA_I8,            /* 0FC6 */    OP_MODRM | OP_DATA_I8,            /* 0FC7 */    OP_MODRM,            /* 0FC8 */    OP_NONE,            /* 0FC9 */    OP_NONE,            /* 0FCA */    OP_NONE,            /* 0FCB */    OP_NONE,            /* 0FCC */    OP_NONE,            /* 0FCD */    OP_NONE,            /* 0FCE */    OP_NONE,            /* 0FCF */    OP_NONE,                /* 0FD0 */    OP_MODRM,            /* 0FD1 */    OP_MODRM,            /* 0FD2 */    OP_MODRM,            /* 0FD3 */    OP_MODRM,            /* 0FD4 */    OP_MODRM,            /* 0FD5 */    OP_MODRM,            /* 0FD6 */    OP_MODRM,            /* 0FD7 */    OP_MODRM,            /* 0FD8 */    OP_MODRM,            /* 0FD9 */    OP_MODRM,            /* 0FDA */    OP_MODRM,            /* 0FDB */    OP_MODRM,            /* 0FDC */    OP_MODRM,            /* 0FDD */    OP_MODRM,            /* 0FDE */    OP_MODRM,            /* 0FDF */    OP_MODRM,                /* 0FE0 */    OP_MODRM,            /* 0FE1 */    OP_MODRM,            /* 0FE2 */    OP_MODRM,            /* 0FE3 */    OP_MODRM,            /* 0FE4 */    OP_MODRM,            /* 0FE5 */    OP_MODRM,            /* 0FE6 */    OP_MODRM,            /* 0FE7 */    OP_MODRM,            /* 0FE8 */    OP_MODRM,            /* 0FE9 */    OP_MODRM,            /* 0FEA */    OP_MODRM,            /* 0FEB */    OP_MODRM,            /* 0FEC */    OP_MODRM,            /* 0FED */    OP_MODRM,            /* 0FEE */    OP_MODRM,            /* 0FEF */    OP_MODRM,                /* 0FF0 */    OP_MODRM,            /* 0FF1 */    OP_MODRM,            /* 0FF2 */    OP_MODRM,            /* 0FF3 */    OP_MODRM,            /* 0FF4 */    OP_MODRM,            /* 0FF5 */    OP_MODRM,            /* 0FF6 */    OP_MODRM,            /* 0FF7 */    OP_MODRM,            /* 0FF8 */    OP_MODRM,            /* 0FF9 */    OP_MODRM,            /* 0FFA */    OP_MODRM,            /* 0FFB */    OP_MODRM,            /* 0FFC */    OP_MODRM,            /* 0FFD */    OP_MODRM,            /* 0FFE */    OP_MODRM,            /* 0FFF */    OP_INVALID,        };        static byte cflags(byte op)        {            return flags_table[op];        }        static byte cflags_ex(byte op)        {            return flags_table_ex[op];        }        /// <summary>        /// 计算大于等于 size 字节的最少指令的长度        /// </summary>        /// <param name="code"></param>        /// <returns></returns>        public static uint SizeofMinNumByte(void* code, int size)        {            if (IsARM())                return (uint)((size + 3) / 4) * 4; // 此为 jit 模式下的长度,不再支持 thumb            uint Length;            byte* pOpcode;            uint Result = 0;            ldasm_data data = new ldasm_data();            bool is64 = IntPtr.Size == 8;            do            {                Length = ldasm(code, data, is64);                pOpcode = (byte*)code + data.opcd_offset;                Result += Length;                if (Result >= size)                    break;                if ((Length == 1) && (*pOpcode == 0xCC))                    break;                code = (void*)((ulong)code + Length);            } while (Length>0);            return Result;        }        static bool? s_isArm;        public static bool IsARM()        {            if(s_isArm.HasValue)                return s_isArm.Value;            var arch = RuntimeInformation.ProcessArchitecture;            s_isArm = arch == Architecture.Arm || arch == Architecture.Arm64;            return s_isArm.Value;        }        public static bool IsArm32()        {            return IsARM() && IntPtr.Size == 4;        }        public static bool IsArm64()        {            return IsARM() && IntPtr.Size == 8;        }        static bool? s_isiOS;        public static bool IsiOS()        {            if(s_isiOS.HasValue)                return s_isiOS.Value;            s_isiOS = UnityEngine.SystemInfo.operatingSystem.ToLower().Contains("ios");            return s_isiOS.Value;        }        static bool? s_isIL2CPP;        public static bool IsIL2CPP()        {            if (s_isIL2CPP.HasValue)                return s_isIL2CPP.Value;            try            {                byte[] ilBody = typeof(LDasm).GetMethod("IsIL2CPP").GetMethodBody().GetILAsByteArray();                if (ilBody == null || ilBody.Length == 0)                    s_isIL2CPP = true;                else                    s_isIL2CPP = false;            }            catch            {                s_isIL2CPP = true;            }            return s_isIL2CPP.Value;        }        public static bool IsThumb(IntPtr code)        {            return IsArm32() &&  ((long)code & 0x1) == 0x1;        }        /// <summary>        /// 计算 thumb 指令长度        /// </summary>        /// <param name="code"></param>        /// <param name="size"></param>        /// <returns></returns>        public static uint CalcARMThumbMinLen(void* code, int size)        {            uint len = 0;            ushort* ins = (ushort*)code;            while (true)            {                if (len >= size)                    return len;                if (((*ins >> 13) & 3) == 3)                {                    ins += 2;                    len += 4;                }                else                {                    ins++;                    len += 2;                }            }        }        static uint ldasm(void* code, ldasm_data ld, bool is64)        {            byte* p = (byte*)code;            byte s, op, f;            byte rexw, pr_66, pr_67;            s = rexw = pr_66 = pr_67 = 0;            /* dummy check */            if ((int)code==0)                return 0;            /* init output data */            //memset(ld, 0, sizeof(ldasm_data));            /* phase 1: parse prefixies */            while ((cflags(*p) & OP_PREFIX)!=0)            {                if (*p == 0x66)                    pr_66 = 1;                if (*p == 0x67)                    pr_67 = 1;                p++; s++;                ld.flags |= F_PREFIX;                if (s == 15)                {                    ld.flags |= F_INVALID;                    return s;                }            }            /* parse REX prefix */            if (is64 && *p >> 4 == 4)            {                ld.rex = *p;                rexw = (byte)((ld.rex >> 3) & 1);                ld.flags |= F_REX;                p++; s++;            }            /* can be only one REX prefix */            if (is64 && *p >> 4 == 4)            {                ld.flags |= F_INVALID;                s++;                return s;            }            /* phase 2: parse opcode */            ld.opcd_offset = (byte)(p - (byte*)code);            ld.opcd_size = 1;            op = *p++; s++;            /* is 2 byte opcode? */            if (op == 0x0F)            {                op = *p++; s++;                ld.opcd_size++;                f = cflags_ex(op);                if ((f & OP_INVALID)!=0)                {                    ld.flags |= F_INVALID;                    return s;                }                /* for SSE instructions */                if ((f & OP_EXTENDED)!=0)                {                    op = *p++; s++;                    ld.opcd_size++;                }            }            else {                f = cflags(op);                /* pr_66 = pr_67 for opcodes A0-A3 */                if (op >= 0xA0 && op <= 0xA3)                    pr_66 = pr_67;            }            /* phase 3: parse ModR/M, SIB and DISP */            if ((f & OP_MODRM)!=0)            {                byte mod = (byte)(*p >> 6);                byte ro = (byte)((*p & 0x38) >> 3);                byte rm = (byte)(*p & 7);                ld.modrm = *p++; s++;                ld.flags |= F_MODRM;                /* in F6,F7 opcodes immediate data present if R/O == 0 */                if (op == 0xF6 && (ro == 0 || ro == 1))                    f |= OP_DATA_I8;                if (op == 0xF7 && (ro == 0 || ro == 1))                    f |= OP_DATA_I16_I32_I64;                /* is SIB byte exist? */                if (mod != 3 && rm == 4 && !(!is64 && pr_67!=0))                {                    ld.sib = *p++; s++;                    ld.flags |= F_SIB;                    /* if base == 5 and mod == 0 */                    if ((ld.sib & 7) == 5 && mod == 0)                    {                        ld.disp_size = 4;                    }                }                switch (mod)                {                    case 0:                        if (is64)                        {                            if (rm == 5)                            {                                ld.disp_size = 4;                                if (is64)                                    ld.flags |= F_RELATIVE;                            }                        }                        else if (pr_67!=0)                        {                            if (rm == 6)                                ld.disp_size = 2;                        }                        else {                            if (rm == 5)                                ld.disp_size = 4;                        }                        break;                    case 1:                        ld.disp_size = 1;                        break;                    case 2:                        if (is64)                            ld.disp_size = 4;                        else if (pr_67!=0)                            ld.disp_size = 2;                        else                            ld.disp_size = 4;                        break;                }                if (ld.disp_size>0)                {                    ld.disp_offset = (byte)(p - (byte*)code);                    p += ld.disp_size;                    s += ld.disp_size;                    ld.flags |= F_DISP;                }            }            /* phase 4: parse immediate data */            if (rexw!=0 && (f & OP_DATA_I16_I32_I64)!=0)                ld.imm_size = 8;            else if ((f & OP_DATA_I16_I32)!=0 || (f & OP_DATA_I16_I32_I64)!=0)                ld.imm_size = (byte)(4 - (pr_66 << 1));            /* if exist, add OP_DATA_I16 and OP_DATA_I8 size */            ld.imm_size += (byte)(f & 3);            if ((ld.imm_size)!=0)            {                s += ld.imm_size;                ld.imm_offset = (byte)(p - (byte*)code);                ld.flags |= F_IMM;                if ((f & OP_RELATIVE)!=0)                    ld.flags |= F_RELATIVE;            }            /* instruction is too long */            if (s > 15)                ld.flags |= F_INVALID;            return s;        }    }}
 |