Написание дизассемблера длин

Тема в разделе "WASM.BEGINNERS", создана пользователем Aoizora, 9 май 2019.

  1. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Хочу написать дизассемблер длин от простого к сложному. В идеале вижу дизассемблер таким, что можно просто заменить какие-нибудь таблицы и можно будет дизасмить любой набор инструкций, например, инструкции для своего виртуального процессора.

    У меня есть такой шеллкод:

    Код (Text):
    1. format binary
    2. use32
    3.  
    4. start:
    5.     pushad
    6.     call get_delta_offset
    7. get_delta_offset:
    8.     pop ebp
    9.     sub ebp, get_delta_offset
    10.     lea eax, [ebp + dllPath]
    11.     push eax
    12.     mov eax, 0EEEEEEEEh
    13.     call eax
    14.     popad
    15.     push 0EEEEEEEEh
    16.     retn
    17.  
    18. dllPath:
    19.     db "C:\windows\system32\pe.dll", 0
    И он же, пропущенный через bin2h:

    Код (Text):
    1. #pragma once
    2.  
    3. const char shellcode[] = {
    4.     0x60,0xe8,0x00,0x00,0x00,0x00,0x5d,0x83,
    5.     0xed,0x06,0x8d,0x45,0x1c,0x50,0xb8,0xee,
    6.     0xee,0xee,0xee,0xff,0xd0,0x61,0x68,0xee,
    7.     0xee,0xee,0xee,0xc3,0x43,0x3a,0x5c,0x77,
    8.     0x69,0x6e,0x64,0x6f,0x77,0x73,0x5c,0x73,
    9.     0x79,0x73,0x74,0x65,0x6d,0x33,0x32,0x5c,
    10.     0x70,0x65,0x2e,0x64,0x6c,0x6c,0x00 };
    Хочу этот шеллкод дизассемблировать, а потом обобщить алгоритм дизассемблирования. Но мне непонятно, как выделять инструкции по префиксам. Есть однобайтовые инструкции, двухбайтовые. Есть инструкции, составленные из кода операции (один байт) и значения (4 байта). В некоторых наборах инструкций значения можно закодировать в каждом полубайте. Как сгруппировать однобайтовые инструкции в одну таблицу, однобайтовые опкоды со значениями в другую и т.д.? А может, я неправильно понимаю принцип, и делать надо по-другому:

    Вот что я читаю:

    http://z0mbie.daemonlab.org/disasme.txt

    https://github.com/greenbender/lend/blob/master/ld32.h

    http://www.rohitab.com/discuss/topic/36031-defs-lde/

    Что за сжатие опкодов по последней ссылке? Наверное, чтобы разобраться в последнем алгосе, надо понять, почему там используется выражение dict[packed[*src/4] + *src%4]; для индексации массивов.
     
    Последнее редактирование: 9 май 2019
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
  3. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Почитаю про формат.

    Код (Text):
    1. seg000:00000000 60                                pusha
    2. seg000:00000001 E8 00 00 00 00                    call    $+5
    3. seg000:00000006 5D                                pop     ebp
    4. seg000:00000007 83 ED 06                          sub     ebp, 6
    5. seg000:0000000A 8D 45 1C                          lea     eax, [ebp+1Ch]
    6. seg000:0000000D 50                                push    eax
    7. seg000:0000000E B8 EE EE EE EE                    mov     eax, 0EEEEEEEEh
    8. seg000:00000013 FF D0                             call    eax
    9. seg000:00000015 61                                popa
    10. seg000:00000016 68 EE EE EE EE                    push    0EEEEEEEEh
    11. seg000:0000001B C3                                retn
    Кодирование E8, B8 и 68 для пятибайтовых инструкций не случайно? В них меняется только первый полубайт.
     
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Aoizora,

    Смотрите в таблицах:

    E8 Jz(A.2) -> z: смещение 16/32 бит.
    B8 Iv -> W/D/Q соотвественно.
    68 Iz
    8D Gv, M -> MODR/M.reg: R(может быть опкодом в других случаях). MODR/M произвольной длины(те зависит от её формата) и так же имеет свою кодировку(зависит от режима): 2.1.3
     
  5. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.955
    Про любой набор инструкций ты загнул. У интела последовательно выбираются префиксы (если есть), опкод, modrm и sib если есть. Алгоритм, который ты привел, специфический для интела.

    ЗЫ: своему воображаемому ассемблеру ты можешь помочь кодируя длину инструкции 1-3 битами самого опкода, тогда весь дизассемблер длин будет проверкой этих бит.
     
  6. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Стало понятнее. Интел мануал читаю. Хочу дизассемблировать в уме инструкцию B8 EE EE EE EE, mov eax, 0EEEEEEh.

    Ищем префиксы. Это может быть lock-prefix F0, rep, repne префиксы F2 и F3, другие префиксы. Их нет.

    Каким образом определяются префиксы в коде https://github.com/greenbender/lend/blob/master/ld32.h ?

    Код (Text):
    1. /* CHECK_PREFIX */
    2. #if defined(USE_T) && (USE_T & PREFIX_T)
    3. const static unsigned int prefix_t[] = {
    4.            /* 0 1 2 3 4 5 6 7  8 9 a b c d e f */
    5.     BITMASK32(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  /* 0 */
    6.               0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0), /* 1 */
    7.     BITMASK32(0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0,  /* 2 */
    8.               0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0), /* 3 */
    9.     BITMASK32(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  /* 4 */
    10.               0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0), /* 5 */
    11.     BITMASK32(0,0,0,0,1,1,1,1, 0,0,0,0,0,0,0,0,  /* 6 */
    12.               0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0), /* 7 */
    13.     BITMASK32(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  /* 8 */
    14.               0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0), /* 9 */
    15.     BITMASK32(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  /* a */
    16.               0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0), /* b */
    17.     BITMASK32(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  /* c */
    18.               0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0), /* d */
    19.     BITMASK32(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  /* e */
    20.               1,0,1,1,0,0,0,0, 0,0,0,0,0,0,0,0)  /* f */
    21. };
    22. #define CHECK_PREFIX(v) CHECK_TABLE(prefix_t, v)
    23. #else
    24. #define CHECK_PREFIX(v)                                                        \
    25.     (((v)&0xe7)==0x26||((v)&0xfc)==0x64||(v)==0xf0||(v)==0xf2||(v)==0xf3)
    26. #endif
    Из 32 битов формируется префикс и помещается в массив, по которому делается проверка?

    Далее в опкоде может быть что-то из ModR/M, SIB, Displacement, Immediate. В данной инструкции из перечисленного есть только immediate константа 0EEEEEEEEh. На этом разбор инструкции закончен, так?

    Самый простой случай это когда есть только опкод и константа. А как вычислить длину инструкции по таблицам, если есть префиксы и другие опциональные байты?
    --- Сообщение объединено, 9 май 2019 ---
    Для дизассемблирования моего шеллкода таблицу префиксов можно сделать проще и определить как

    Код (Text):
    1. const static unsigned int prefix_t[128] = {
    2.     // Group 1 prefixes
    3.     0xF0,    // Lock-prefix
    4.     0xF2,    // repne prefix
    5.     0xF3    // repe
    6. };
    Правильно понимаю принцип создания таких таблиц?
    --- Сообщение объединено, 9 май 2019 ---
    Как происходит проверка по таблицам? Что означают эти магические числа?

    Код (Text):
    1. #define CHECK_TABLE(t, v) ((t[(v)>>5]>>((v)&0x1f))&1)
     
  7. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.955
    После префикса идет опкод инструкции, в зависимости от опкода может быть modrm, в зависимости от modrm может быть sib, в зависимости от modrm и sib может быть immediate или displacement, их длина может зависеть от префиксов.
    --- Сообщение объединено, 9 май 2019 ---
    Макрос BITMASK32 выстраивает эти биты в линеечку от младшего к старшему (они разделены на байты, но в байтах биты наоборот), макрос CHECK_TABLE берет определенный бит из всей таблицы (>>5 это деление на 32, 32 бита в каждой записи BITMASK32). Это дико байтодрочерский алгоритм, его надо с микроскопом изучать.
    --- Сообщение объединено, 9 май 2019 ---
    32*8=256 очевидно это таблица для 1-байтного опкода, где каждый бит означает префикс или не префикс этот опкод.
     
    Последнее редактирование: 9 май 2019
  8. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Сделал дизассемблер очень тупо, но на моем шеллкоде он работает:

    Код (Text):
    1. int main()
    2. {
    3.     const unsigned char* src = shellcode;
    4.  
    5.     while (unsigned length = disasm(src)) {
    6.         std::cout << "OP length: " << length << std::endl;
    7.         src += length;
    8.     }
    9.  
    10.     return 0;
    11. }
    Код (Text):
    1. unsigned int disasm(const unsigned char* opcode) {
    2.  
    3.     switch (*opcode) {
    4.     case 0x60: case 0x5D: case 0x50:
    5.     case 0x51: case 0xC3:
    6.         return 1;
    7.     case 0xFF:
    8.         return 2;
    9.     case 0x83: case 0x8D:
    10.         return 3;
    11.     case 0xE8: case 0xB8: case 0x68:
    12.         return 5;
    13.     default:
    14.         return 0;
    15.     }
    16. }
    Есть дизассемблеры без битового хардкора, по которым можно освоить базовые принципы разбора инструкций? В одном из выпусков Inception, вроде, был дизасм. Надо пересмотреть. Есть еще статьи?
     
  9. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.955
    Мне понравился дизасм в qemu, там такой хрени нету.
     
  10. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Здесь в таблице написано, что есть только 1- и 2-байтовые опкоды, а в интел мануале, который кинул Инде, говорится о 3-байтовых опкодах.

    http://ref.x86asm.net/geek32.html

    Работая с ассемблером для современных интелов, можно не закладываться на то, что все опкоды будут короче 3 байт?
    --- Сообщение объединено, 10 май 2019 ---
    Сложнаа. По книге "Дизассемблирование в уме" написал код, который собирает инструкцию mov с двумя разными битами направления:

    Код (Text):
    1. #define BITMASK8(b7, b6, b5, b4, b3, b2, b1, b0)                \
    2. (                                                                \
    3.     (b0 << 0x00) | (b1 << 0x01) | (b2 << 0x02) | (b3 << 0x03) | \
    4.     (b4 << 0x04) | (b5 << 0x05) | (b6 << 0x06) | (b7 << 0x07)    \
    5. )
    6.  
    7. int main()
    8. {
    9.     const unsigned char* src = shellcode;
    10.  
    11.     while (unsigned length = disasm(src)) {
    12.         std::cout << "OP length: " << length << std::endl;
    13.         src += length;
    14.     }
    15.  
    16.     std::ofstream out("dump.bin");
    17.  
    18.     unsigned char mov_l[] = { 0x00, 0xDA };
    19.     mov_l[0] = BITMASK8(1, 0, 0, 0, 1, 0, 1, 1);
    20.  
    21.     unsigned char mov_r[] = { 0x00, 0xDA };
    22.     mov_r[0] = BITMASK8(1, 0, 0, 0, 1, 0, 0, 1);
    23.  
    24.     out.write((const char *)mov_l, 2);
    25.     out.write((const char *)mov_r, 2);
    26.     out.close();
    27.  
    28.     return 0;
    29. }
    30.  
    31. Посмотрел в иде - работает.
    --- Сообщение объединено, 10 май 2019 ---
    Дизассемблер из журнала Inception сделан слишком примитивно. Очень много проверок условий вместо того, чтобы написать макросы или constexpr-функции, которые позволят работать на максимальном уровне абстракции, учитывая требования и ограничения

    Код (Text):
    1. /***********************************************************************************************************************\
    2. *                                                                                                                        *
    3. *                                                                                                                        *
    4. *                 xxxxxxxx      xxxxxxxx   xxxxxxxxx     xxxxxxx     xxxx   xxxx   xxxxxxxx   xxxx    xxxx              *
    5. *                 xxxxxxxxxx    xxxxxxxx   xxxxxxxxx    xxxxxxxxx    xxxx   xxxx   xxxxxxxx    xxxx  xxxx               *
    6. *                 xxxx   xxxx     xxxx         xxxx    xxxx   xxxx   xxxx   xxxx   xxxx         xxxxxxxx                *
    7. *                 xxxx   xxxx     xxxx       xxxx      xxxx   xxxx   xxxxxxxxxxx   xxxxxxx       xxxxxx                 *
    8. *                 xxxx   xxxx     xxxx      xxxx       xxxxxxxxxxx   xxxxxxxxxxx   xxxxxxx       xxxxxx                    *
    9. *                 xxxx   xxxx     xxxx     xxxx        xxxxxxxxxxx   xxxx   xxxx   xxxx         xxxxxxxx                *
    10. *                 xxxxxxxxxx    xxxxxxxx   xxxxxxxxx   xxxx   xxxx   xxxx   xxxx   xxxxxxxx    xxxx  xxxx               *
    11. *                 xxxxxxxx      xxxxxxxx   xxxxxxxxx   xxxx   xxxx   xxxx   xxxx   xxxxxxxx   xxxx    xxxx              *
    12. *                                                                                                                       *
    13. *                                                                                                                        *
    14. *************************************************************************************************************************
    15. *                                                                                                                        *
    16. *                                                        xxx xxxx                                                        *
    17. *                                                        xxx xxxxx                                                        *
    18. *                                                            xx  xx                                                        *
    19. *                                                            xx  xx                                                        *
    20. *                                                        xxx xxxxx                                                        *
    21. *                                                        xxx xxxx                                                        *
    22. *                                                                                                                        *
    23. *************************************************************************************************************************
    24. *                                                                                                                        *
    25. *                                              DIZAHEX DISASSEMBLER ENGINE                                                 *
    26. *                                                                                                                        *
    27. * [+] Дизассемблер инструкций x86/x86-64 (+ 16 bits):                                                                    *
    28. *      general-purpose, system, fpu, mmx, sse, sse2, sse3, 3dnow!, undocumented;                                            *
    29. * [+] пригоден для пермутации (тогда массив dizahex_table перенести в функу dizahex_disasm());                            *
    30. * [+] лёгкость добавления новых инструкций;                                                                                *
    31. * [+] дока по дизасму в файле man.txt;                                                                                     *
    32. * [+] пример использования смотри в man.txt и в test.c;                                                                    *
    33. * [+] дизассемблирование инструкции и её сборка (dizahex_disasm(), dizahex_asm());                                        *
    34. * [+] etc;                                                                                                                *
    35. *                                                                                                                        *
    36. \***********************************************************************************************************************/
    37. //v1.0;
    38.  
    39.  
    40.  
    41.                                                                             //pr0mix
    42.                                                                             //pr0mix@mail.ru
    43.                                                                             //вирмэйкинг для себя - искусство вечно
    44.  
    45.  
    46.  
    47. #include "dizahex.h"
    48. #include "dh_tbl.h"
    49.  
    50.  
    51.  
    52. #define get_flags(table, code)    (table[table[code / 4] + (code % 4)])
    53.  
    54.  
    55.  
    56.  
    57.  
    58. /**********************************************************************************\
    59. *    Функция dizahex_disasm
    60. *    Дизассемблирование инструкции x86/x86-64 (+ 16 bits);
    61. *    ВХОД:
    62. *        pcode            -        адрес инструкции;
    63. *        pdiza            -        указатель на объект структы DIZAHEX_STRUCT;
    64. *        pdiza->mode        -        DISASM_MODE_32 или DISASM_MODE_64;
    65. *    ВЫХОД:
    66. *        (+)                -        в случае успеха: заполненная структура DIZAHEX_STRUCT,
    67. *                                а также функа вернёт длину разобранной инструкции.
    68. *                                Иначе вернёт 0;
    69. *    ЗАМЕТКИ:
    70. *        [+]    данная функа вначале обнулит почти все поля структуры DIZAHEX_STRUCT (кроме
    71. *            pdiza->mode), поэтому делать это самостоятельно не требуется;
    72. *        [+]    если pdiza->mode == DISASM_MODE_32, то будет разбор x86 инструкции. Иначе,
    73. *            если указан режим DISASM_MODE_64, то разбор x86-64 инструкции;
    74. \**********************************************************************************/
    75. int dizahex_disasm(uint8_t *pcode, DIZAHEX_STRUCT *pdiza)
    76. {
    77.     uint32_t i, opcode;
    78.     uint8_t mod, reg, rm, ch, disp_size, pfx_66, pfx_67, data_64;
    79.     uint8_t flags, *pdt = dizahex_table, *pc = pcode;
    80.  
    81.     opcode = disp_size = pfx_66 = pfx_67 = data_64 = 0;                                    //обнуление нужных переменных;
    82.  
    83.     for(i = sizeof(uint8_t); i < sizeof(DIZAHEX_STRUCT); i++)                            //обнуление структы (кроме первого элемента, pdiza->mode);
    84.         *((char *)pdiza + i) = 0;
    85.  
    86.     while((get_flags(pdt, *pc) & C_PREFIX) && ((pc - pcode) < 15))                        //обработка префиксов;
    87.     {
    88.         ch = *pc++;
    89.  
    90.         if(ch == 0x66)                                                                    //0x66
    91.         {
    92.             pfx_66 = 1;
    93.             pdiza->pfx_66 = ch;
    94.             pdiza->flags |= F_PFX_66;
    95.         }
    96.  
    97.         if(ch == 0x67)                                                                    //0x67
    98.         {
    99.             pfx_67 = 1;
    100.             pdiza->pfx_67 = ch;
    101.             pdiza->flags |= F_PFX_67;
    102.         }
    103.  
    104.         if(ch == 0xF0)                                                                    //LOCK
    105.         {
    106.             pdiza->pfx_lock = ch;
    107.             pdiza->flags |= F_PFX_LOCK;
    108.         }
    109.  
    110.         if((ch == 0xF2) || (ch == 0xF3))                                                //REPE / REPNE
    111.         {
    112.             pdiza->pfx_rep = ch;
    113.             pdiza->flags |= F_PFX_REP;
    114.         }
    115.  
    116.         if((ch == 0x26) || (ch == 0x2E) || (ch == 0x36) ||
    117.             (ch == 0x3E) || (ch == 0x64) || (ch == 0x65))                                //SEGMENTS
    118.         {
    119.             pdiza->pfx_seg = ch;
    120.             pdiza->flags |= F_PFX_SEG;
    121.         }
    122.     }
    123.  
    124.     ch = *pc++;
    125.  
    126.     if(pdiza->mode & DISASM_MODE_64)                                                    //если включён режим x64,
    127.     {
    128.         if((ch & 0xF0) == 0x40)                                                            //то проверим наличие префикса REX;
    129.         {
    130.             pdiza->flags |= F_PFX_REX;
    131.             pdiza->pfx_rex = ch;
    132.             ch = *pc++;
    133.  
    134.             if((pdiza->pfx_rex & 0x08) && ((ch & 0xF8) == 0xB8))                        //если REX есть, REX.W есть и опкод = [0xb8..0xbf]
    135.                 data_64 = 1;                                                            //то будет imm64;
    136.         }
    137.     }
    138.  
    139.     pdiza->opcode = ch;                                                                    //обработка опкодов;
    140.  
    141.     if(ch == 0x0F)                                                                        //2opcode;
    142.     {
    143.         pdiza->opcode_2 = ch = *pc++;
    144.         opcode |= C_OP_EXTENDED;
    145.     }
    146.     else if((ch >= 0xA0) && (ch <= 0xA3))
    147.     {
    148.         pfx_66 = pfx_67;
    149.  
    150.         if(pdiza->mode & DISASM_MODE_64)                                                //если x64 и опкод = [0xa0..0a3];
    151.         {
    152.             data_64 = !pfx_66;
    153.             pfx_66 = 0;
    154.         }
    155.     }
    156.  
    157.     opcode |= ch;
    158.     flags = get_flags(pdt, opcode);                                                        //получение характеристик опкода;
    159.  
    160.     if(flags & C_MODRM)                                                                    //обработка modrm;
    161.     {
    162.         pdiza->flags |= F_MODRM;
    163.         pdiza->modrm = ch = *pc++;
    164.         mod = ch >> 6;
    165.         reg = (ch & 0x38) >> 3;
    166.         rm = ch & 7;
    167.  
    168.         if(reg <= 1)
    169.         {
    170.             if(opcode == 0xF6)
    171.                 flags |= C_DATA_8;
    172.             if(opcode == 0xF7)
    173.                 flags |= C_DATA_PFX_66_67;
    174.         }
    175.  
    176.         if(!mod)                                                                        //mod = 0;
    177.         {
    178.             if(pfx_67)
    179.             {
    180.                 if((rm == 6) && !(pdiza->mode & DISASM_MODE_64))
    181.                     disp_size = 2;                                                        //disp = 16bits только в 16-битном режиме; в 32 и 64 disp = 32bits;
    182.             }
    183.             else
    184.             {
    185.                 if(rm == 5)
    186.                     disp_size = 4;
    187.             }
    188.         }
    189.         else if(mod == 1)                                                                //mod = 1;
    190.         {
    191.             disp_size = 1;
    192.         }
    193.         else if(mod == 2)                                                                //mod = 2;
    194.         {
    195.             if(pfx_67 && !(pdiza->mode & DISASM_MODE_64))  
    196.                 disp_size = 2;
    197.             else      
    198.                 disp_size = 4;
    199.         }
    200.  
    201.         if((mod != 3) && (rm == 4) && (!pfx_67 || (pdiza->mode & DISASM_MODE_64)))        //обработка SIB; SIB отсутствует только в 16-разрядном режиме;
    202.         {
    203.             pdiza->flags |= F_SIB;
    204.             pdiza->sib = ch = *pc++;
    205.  
    206.             if(((ch & 7) == 5) && !(mod & 1))
    207.             {
    208.                 disp_size = 4;
    209.             }
    210.         }
    211.  
    212.         if(disp_size == 1)                                                                //обработка смещения (DISP);
    213.         {
    214.             pdiza->flags |= F_DISP_8;
    215.             pdiza->disp.disp_8 = *pc;
    216.         }
    217.         else if(disp_size == 2)
    218.         {
    219.             pdiza->flags |= F_DISP_16;
    220.             pdiza->disp.disp_16 = *(uint16_t *)pc;
    221.         }
    222.         else if(disp_size == 4)
    223.         {
    224.             pdiza->flags |= F_DISP_32;
    225.             pdiza->disp.disp_32 = *(uint32_t *)pc;
    226.         }
    227.  
    228.         pc += disp_size;
    229.     }
    230.  
    231.     if(flags & C_DATA_PFX_66_67)                                                        //обработка операнда (IMM);
    232.     {
    233.         if(data_64)
    234.         {
    235.             pdiza->flags |= F_IMM_64;
    236.             pdiza->imm.imm_64 = *(uint64_t *)pc;
    237.             pc += 8;
    238.         }
    239.         else if(pfx_66)
    240.         {
    241.             pdiza->flags |= F_IMM_16;
    242.             pdiza->imm.imm_16 = *(uint16_t *)pc;
    243.             pc += 2;
    244.         }
    245.         else
    246.         {
    247.             pdiza->flags |= F_IMM_32;
    248.             pdiza->imm.imm_32 = *(uint32_t *)pc;
    249.             pc += 4;
    250.         }
    251.     }
    252.  
    253.     if(flags & C_DATA_16)
    254.     {
    255.         if(pdiza->flags & (F_IMM_32 | F_IMM_16))
    256.         {
    257.             pdiza->flags |= (F_DISP_16 | F_COP_IMM_DISP);
    258.             pdiza->disp.disp_16 = *(uint16_t *)pc;
    259.         }
    260.         else
    261.         {
    262.             pdiza->flags |= F_IMM_16;
    263.             pdiza->imm.imm_16 = *(uint16_t *)pc;
    264.         }
    265.  
    266.         pc += 2;
    267.     }
    268.  
    269.     if(flags & C_DATA_8)
    270.     {
    271.         if(pdiza->flags & (F_IMM_32 | F_IMM_16))
    272.         {
    273.             pdiza->flags |= (F_DISP_8 | F_COP_IMM_DISP);
    274.             pdiza->disp.disp_8 = *pc++;
    275.         }
    276.         else
    277.         {
    278.             pdiza->flags |= F_IMM_8;
    279.             pdiza->imm.imm_8 = *pc++;
    280.         }
    281.     }
    282.  
    283.     if(flags & (C_REL_32 | C_REL_8))
    284.         pdiza->flags |= F_REL;
    285.  
    286.     pdiza->len = pc - pcode;                                                            //вычисляем длину инструкции;
    287.  
    288.     return pdiza->len;
    289. }
    290. /**********************************************************************************\
    291. *    конец функи dizahex_disasm;
    292. \**********************************************************************************/
    293.  
    294.  
    295.  
    296.  
    297.  
    298. /**********************************************************************************\
    299. *    вспомогательная внутренняя функа disp_asm;
    300. *    ассемблирование значений полей disp*;
    301. *    ВХОД:
    302. *        pcode        -        адрес инструкции;
    303. *        pdiza        -        указатель на объект структы DIZAHEX_STRUCT;
    304. *    ВЫХОД:
    305. *        (+)            -        адрес для дальнейшего ассемблирования;
    306. \**********************************************************************************/
    307. uint8_t *disp_asm(uint8_t *pcode, DIZAHEX_STRUCT *pdiza)
    308. {
    309.     if(pdiza->flags & F_DISP_8)      
    310.         *pcode++ = pdiza->disp.disp_8;
    311.    
    312.     if(pdiza->flags & F_DISP_16)
    313.     {
    314.         *(uint16_t *)pcode = pdiza->disp.disp_16;
    315.         pcode += 2;
    316.     }
    317.  
    318.     if(pdiza->flags & F_DISP_32)
    319.     {
    320.         *(uint32_t *)pcode = pdiza->disp.disp_32;
    321.         pcode += 4;
    322.     }
    323.  
    324.     return pcode;
    325. }
    326. /**********************************************************************************\
    327. *    конец функи disp_asm;
    328. \**********************************************************************************/
    329.  
    330.  
    331.  
    332.  
    333.  
    334. /**********************************************************************************\
    335. *    вспомогательная внутренняя функа imm_asm;
    336. *    ассемблирование значений полей imm*;
    337. *    ВХОД:
    338. *        pcode        -        адрес инструкции;
    339. *        pdiza        -        указатель на объект структы DIZAHEX_STRUCT;
    340. *    ВЫХОД:
    341. *        (+)            -        адрес для дальнейшего ассемблирования;
    342. \**********************************************************************************/
    343. uint8_t *imm_asm(uint8_t *pcode, DIZAHEX_STRUCT *pdiza)
    344. {
    345.     if(pdiza->flags & F_IMM_8)      
    346.         *pcode++ = pdiza->imm.imm_8;
    347.  
    348.     if(pdiza->flags & F_IMM_16)
    349.     {
    350.         *(uint16_t *)pcode = pdiza->imm.imm_16;
    351.         pcode += 2;
    352.     }
    353.  
    354.     if(pdiza->flags & F_IMM_32)
    355.     {
    356.         *(uint32_t *)pcode = pdiza->imm.imm_32;
    357.         pcode += 4;
    358.     }
    359.  
    360.     if(pdiza->flags & F_IMM_64)
    361.     {
    362.         *(uint64_t *)pcode = pdiza->imm.imm_64;
    363.         pcode += 8;
    364.     }
    365.  
    366.     return pcode;
    367. }
    368. /**********************************************************************************\
    369. *    конец функи imm_asm;
    370. \**********************************************************************************/
    371.  
    372.  
    373.  
    374.  
    375.  
    376. /**********************************************************************************\
    377. *    функа dizahex_asm;
    378. *    сборка инструкции из структуры DIZAHEX_STRUCT;
    379. *    ВХОД:
    380. *        pcode        -        адрес инструкции;
    381. *        pdiza        -        указатель на объект структы DIZAHEX_STRUCT;
    382. *    ВЫХОД:
    383. *        (+)            -        длина собранной инструкции;
    384. \**********************************************************************************/
    385. int dizahex_asm(uint8_t *pcode, DIZAHEX_STRUCT *pdiza)
    386. {
    387.     uint8_t *pc = pcode;
    388.  
    389.     if(pdiza->flags & F_PFX_66)        *pc++ = pdiza->pfx_66;
    390.     if(pdiza->flags & F_PFX_67)        *pc++ = pdiza->pfx_67;
    391.     if(pdiza->flags & F_PFX_LOCK)    *pc++ = pdiza->pfx_lock;
    392.     if(pdiza->flags & F_PFX_REP)    *pc++ = pdiza->pfx_rep;
    393.     if(pdiza->flags & F_PFX_SEG)    *pc++ = pdiza->pfx_seg;
    394.     if(pdiza->flags & F_PFX_REX)    *pc++ = pdiza->pfx_rex;
    395.  
    396.     *pc++ = pdiza->opcode;
    397.  
    398.     if(pdiza->opcode == 0x0F)        *pc++ = pdiza->opcode_2;
    399.     if(pdiza->flags & F_MODRM)        *pc++ = pdiza->modrm;
    400.     if(pdiza->flags & F_SIB)        *pc++ = pdiza->sib;
    401.  
    402.     if(pdiza->flags & F_COP_IMM_DISP)                                    //если данный флаг установлен, тогда меняем порядок обработки IMM и DISP: Change Order of Processing (COP);
    403.     {
    404.         pc = imm_asm(pc, pdiza);
    405.         pc = disp_asm(pc, pdiza);
    406.     }
    407.     else
    408.     {
    409.         pc = disp_asm(pc, pdiza);
    410.         pc = imm_asm(pc, pdiza);
    411.     }
    412.  
    413.     return (pc - pcode);
    414. }
    415. /**********************************************************************************\
    416. *    конец функи dizahex_asm;
    417. \**********************************************************************************/
     
  11. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.955
    А ты ассемблер, дизассемблер или дизассемблер длин хочешь сделать?) Можешь попробовать дизасм гидры в свой адаптировать, там основной принцип - обработка одного токена (порции данных) за раз (разделены на фазы) и сохранение флагов в контексте. Примерно то же самое, что в первом приведенном дизассемблере длин.
     
  12. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Хочу пока что написать дизассемблер длин, но ассемблер и дизассемблер тоже будет нужен. Я хочу пермутировать свой шеллкод, но для начала просто его дизассемблировать без помощи библиотек.
     
  13. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775