Что такое эмуляция ?

Тема в разделе "WASM.RESEARCH", создана пользователем Entropy, 15 фев 2026.

  1. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    410
    Набросал небольшой прототип учебного эмулятора на 4 регистра. Память выделил, но для упрощения понимания принципа работы, пока не задействовал. Критика и замечания приветствуются.
    Код (C):
    1. #include <stdio.h>
    2. #include <stdint.h>
    3.  
    4. #define MEMORY_SIZE 0x1000  // 4 Кб памяти
    5. #define NUM_REGS 4          // Количество регистров
    6.  
    7. typedef struct {
    8.     uint8_t memory[MEMORY_SIZE];  // Память
    9.     uint32_t regs[NUM_REGS];      // Регистры
    10. } bdshemu_context;
    11.  
    12. void print_registers(bdshemu_context* ctx) {
    13.     printf("Registers:\n");
    14.     for (int i = 0; i < NUM_REGS; i++) {
    15.         printf("R%d = 0x%08X\n", i, ctx->regs[i]);
    16.     }
    17. }
    18.  
    19. void process_instructions(bdshemu_context* ctx, uint8_t* code, size_t code_size) {
    20.     size_t ip = 0;  // Instruction pointer
    21.  
    22.     while (ip < code_size) {
    23.         uint8_t opcode = code[ip++];
    24.  
    25.         switch (opcode) {
    26.         case 0x01:  // MOV
    27.             // MOV <reg>, <value>
    28.         {
    29.             uint8_t reg = code[ip++];
    30.             uint8_t value = code[ip++];
    31.             ctx->regs[reg] = value;
    32.             printf("MOV R%d, 0x%02X\n", reg, value);
    33.         }
    34.         break;
    35.  
    36.         case 0x02:  // ADD
    37.             // ADD <reg>, <value>
    38.         {
    39.             uint8_t reg = code[ip++];
    40.             uint8_t value = code[ip++];
    41.             ctx->regs[reg] += value;
    42.             printf("ADD R%d, 0x%02X\n", reg, value);
    43.         }
    44.         break;
    45.  
    46.         case 0x03:  // SUB
    47.             // SUB <reg>, <value>
    48.         {
    49.             uint8_t reg = code[ip++];
    50.             uint8_t value = code[ip++];
    51.             ctx->regs[reg] -= value;
    52.             printf("SUB R%d, 0x%02X\n", reg, value);
    53.         }
    54.         break;
    55.  
    56.         case 0x90:  // NOP
    57.             // No operation
    58.             printf("NOP\n");
    59.             break;
    60.  
    61.         case 0x04:  // JMP
    62.             // JMP <address>
    63.         {
    64.             uint8_t low = code[ip++];
    65.             uint8_t high = code[ip++];
    66.             uint16_t address = (high << 8) | low;
    67.             printf("JMP to address: 0x%04X\n", address);
    68.         }
    69.         break;
    70.  
    71.         default:
    72.             // Unknown byte
    73.             printf("Unknown byte encountered: 0x%02X\n", opcode);
    74.             break;
    75.         }
    76.     }
    77.  
    78.     // Print all registers after execution
    79.     print_registers(ctx);
    80. }
    81.  
    82. int main() {
    83.     bdshemu_context ctx = { 0 };  // Initialize context, all registers are 0
    84.  
    85.     // Example machine code to run on the emulator
    86.     uint8_t code[] = {
    87.         0x01, 0x00, 0x10,  // MOV R0, 0x10
    88.         0x66,              // Undefined instruction
    89.         0x02, 0x00, 0x05,  // ADD R0, 0x5
    90.         0x03, 0x00, 0x03,  // SUB R0, 0x3
    91.         0x90,              // NOP
    92.         0x04, 0x20, 0x00,  // JMP 0x20
    93.         0x01, 0x01, 0x28,  // MOV R1, 0x28
    94.         0x01, 0x02, 0x68,  // MOV R2, 0x68
    95.         0x77,              // Undefined instruction
    96.         0x03, 0x01, 0x03,  // SUB R1, 0x3
    97.         0x01, 0x03, 0x88  // MOV R3 0x88
    98.     };
    99.  
    100.     size_t code_size = sizeof(code) / sizeof(code[0]);
    101.  
    102.     // Process the instructions and print registers
    103.     process_instructions(&ctx, code, code_size);
    104.  
    105.     return 0;
    106. }
     
    Последнее редактирование: 24 фев 2026
    Application нравится это.
  2. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    497
    GRAFik

    Это байт-кодовый интерпретатор, штатный цикл fetch-decode-execute и формально циклический поток наследования через указатель в байткод.

    Всем известная printf - хороший пример простой байткодовой вирты.
     
  3. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    255
    MaKsIm, я сделал вывод понятными мне словами
     
  4. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    497
    Entropy

    wtf, все по теме не просто формулировано, а введены годные понятия, теория наследования.

    Та трудность с введением дельты в modrm, IDP, разобрана. Что такое кодовый анклав.

    Позже выложу кодес.
     
  5. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    579
    Мой эмулятор вымышленной 16-битной машины с экстремально простой системой команд - SimpX:
    Попробовать в онлайн: https://aa-dav.github.io/
    Эмуляция работает сразу из ассемблерного кода - он транслируется в виртуальный образ машины при запуске и эмулятор включается на только что оттранслированный образ.
    Файлы с исходниками есть библиотечные и их бесполезно транслировать, надо выделить в левом списке файл с названием вида test-0X.asm и нажать меню Compile and Run.
    Исходники и описание архитектуры процессора тут: https://github.com/aa-dav/SimpX/blob/master/README_simpleton_ru.md
    Очень простая 16-битная трёхоперандная машина - каждая инструкция выполняет шаблон "назначение = операнд1 операция операнд2" с небольшими вариациями для оптимизации процесса.
     
    Application нравится это.
  6. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    255
    я хотел сказать мне в общих чертах понятно что такое эмуляция,а если углубляться, это надо разбирать исходники эмуляторов
     
  7. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    389
    https://github.com/mrexodia/sogen

    preview.jpg
     
  8. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    497
    Research

    Unicorn Engine

    Обработка системных событий в обычных фильтрах примитивна - ядро выполняет выборку аргументов, видимую в юзер.
     
  9. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    389
    А как надо?
     
  10. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    497
    При выборке аргумента, его проверке try-fetch-except или ProbeFor() происходит дереференс ссылки, это приводит к прокидыванию #guard и разблокировки страницы. Отсутствие этого механизма делает детект эмуляции сервисов элементарным, можно автоматикой накопить размеры всех аргументов любого сискола.

    Тупо фильтрация это бесполезная шляпа, юзер апи эмулируют обычно адресными ловушками if rIp = *Api: emulate(Api). В таком виде тела функции нет - его нельзя прочитать/переместить. Более продвинутая аверская метода это вставить шлюз(атом) if [rIp] = SignatureId(Api): emulate(Id).