Как выдать прерывание 0x2D в коде C на 64-битной Windows? - PullRequest
0 голосов
/ 03 сентября 2018

Я ищу способ выдачи прерывания 0x2D из кода C, так же, как вы можете выполнить int 3, используя __debugbreak()

На x86 я могу использовать встроенную сборку

__asm
{
    int 2dh
}

но мне нужно решение, которое будет работать для:

  • x64 и должен соответствовать Visual Studio (минимальное требование)
  • x86 и x64, независимый от компилятора (лучшее решение)

1 Ответ

0 голосов
/ 03 сентября 2018

Поскольку x64 Visual Studio вообще не поддерживает встроенную сборку (последнее, что я слышал, во всяком случае), ваше лучшее независимое от компилятора решение - написать файл .asm, который определяет функцию, назовем ее int_2d, которая просто выдает это прерывание, а затем возвращается. Вы компилируете файл .asm в объектный файл, связываете этот объектный файл с остальной частью вашего приложения, и затем вы можете записать extern void int_2d(void); в заголовочный файл и вызывать его обычно из C, когда вам нужно выполнить прерывание.

Для ассемблера, который поставляется с x64 Visual Studio , файл .asm должен выглядеть примерно так:

_TEXT segment 'CODE'

int_2d proc 
    xor eax,eax 
    int 2dh 
    nop
    ret 
int_2d endp 

_TEXT ENDS 
END

nop после int 2dh необходим, поскольку в зависимости от используемого кода операции и от того, подключен ли к процессу отладчик, обработчик INT 2D может вызывать или не вызывать один байт из код (не одна инструкция) сразу после пропуска int инструкции. Так что вам нужно поместить туда однобайтовый NOP.

INT 2D также ожидает код операции в регистре A; известные значения этого кода операции варьируются от 0 до 5, и мне не повезло найти документацию о том, что они на самом деле делают. В примере кода произвольно выбирается значение A, равное 0. (Вам не нужно сохранять и восстанавливать его, поскольку во всех соглашениях о вызовах Windows A является закрытым при вызове.) Если вы хотите передать код операции в качестве аргумента, вы может сделать это так:

_TEXT segment 'CODE'

int_2d proc 
    mov eax, ecx
    int 2dh 
    nop
    ret 
int_2d endp 

_TEXT ENDS 
END

но затем вы должны объявить функцию на стороне C как __fastcall void int_2d(uint32_t op); (__fastcall не нужно, но безвредно при компиляции в 64-битном режиме, я думаю.)

К сожалению, я не знаю, как написать «шаблон» (все, кроме фактических инструкций по сборке) для файла .asm, который должен работать с максимально возможным количеством различных наборов инструментов Windows. Вышеуказанное, вероятно, не будет неприемлемым, например, для NASM.

...