DrC*_*ore 1 x86 assembly interrupt
我想在 NASM 中有一个中断,它调用的不是硬编码中断而是 int。在一个寄存器中。给你一个例子:
mov al, 0x10
int al ; you can't do this for some reason
Run Code Online (Sandbox Code Playgroud)
因此,如果我将 0x10 存储在寄存器 al 中,那么我可以根据该寄存器中的内容调用中断。
有什么办法可以做到这一点吗?
有什么办法可以做到这一点吗?
在没有自修改代码的 16 位“实模式”中:
大多数用于 DOS 的 C 编译器都提供了一个库函数,允许执行等效的int al.
这以以下方式工作:
在实模式下,一条int指令等于 apushf后跟一个远call到中断处理程序。
但是,“远”call只不过是将下一条指令的“远”地址(cs和ip)压入堆栈并执行跳转。(“near”调用只会压入ip。) Aretf将从堆栈中弹出ip和cs并跳转到该地址。
中断处理程序的地址存储在地址 0:(4*n)。
所以要进入中断,首先要执行以下代码:
pushf
push cs # Leave this line out if "call helper" is a "far" call
call helper
Run Code Online (Sandbox Code Playgroud)
进入函数时helper,堆栈如下所示:
Address (IP) of the instruction after "call helper"
Segment (CS) of the program
Flags
...
Run Code Online (Sandbox Code Playgroud)
这三个元素在一条int指令之后在堆栈上。
该程序helper看起来像这样。
helper:
# Calculate BX = 4*AX
# (This can be done with less instructions on a modern CPU)
mov bl,al
mov bh,0
add bx,bx
add bx,bx
# Set DS to 0
xor ax,ax
mov ds,ax
# Push the segment part of the interrupt handler address
# to the stack
push word [bx+4]
# Push the offset part
push word [bx]
# Load all registers with the desired values
# TODO: Ensure all registers have the correct values
# Enter the interrupt
retf
Run Code Online (Sandbox Code Playgroud)
在retf堆栈之前将如下所示:
Address (IP) of the interrupt routine
Segment (CS) of the interrupt routine
Address (IP) of the instruction after "call helper"
Segment (CS) of the program
Flags
...
Run Code Online (Sandbox Code Playgroud)
该retf指令的行为方式与前两个字已被“远”call指令压入一样:它将从堆栈中删除前两个字并跳转到这两个字所描述的地址 - 这意味着:进入中断处理程序。
在中断处理程序结束时,最后 3 个字将从堆栈中弹出,并在 之后的指令处继续执行call helper。
在带有自修改代码的 16 位“实模式”中:
这很简单:
# AL contains the interrupt number
# Modify the "int" instruction, so "int 42" becomes
# "int 31" if the value of AL is 31.
mov cs:[theIntInstruction+1], al
# Load all registers with the desired values
# TODO: Ensure all registers have the correct values
# Now perform the "int" instruction
theIntInstruction:
int 42
Run Code Online (Sandbox Code Playgroud)
自修改代码可能会产生负面影响。这意味着可能有问题......
在(16 位或 32 位)“保护模式”中:
根据内存保护设置,您有机会写入“可执行”的内存。在这种情况下,您可能会使用自修改代码。
如果您无法使用自修改代码,则无法执行等效的操作,int al除非您想执行以下操作:
performInt0:
int 0
ret
performInt1:
int 1
ret
performInt2:
int 2
ret
...
performInt255:
int 255
ret
Run Code Online (Sandbox Code Playgroud)
...然后call对所需的标签执行a 。
这当然总是可能的。
| 归档时间: |
|
| 查看次数: |
334 次 |
| 最近记录: |