| 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;
- }
- }
- }
|