前言
上篇我们分析了bochs对于int产生的interrupt事件的模拟处理流程,只是我们还没看看其返回如何实现的,我们这篇文章来分析一下。
虽然源代码还没看,但我估计这篇文章有点短,昨晚失眠到两点多,今天早上还是七点起来,中午竟然睡不着,我人麻了,早写完回家洗个澡休息。
bochs-dbg定位
这个之间按上篇文章 int 指令往前jmp几条指令后就很容易看见,不用ida来逆向分析了,因为其还要逆向lib32库挺麻烦的。

代码分析
其iret与int一样,在不同模式下其行为不一样,因此iret指令一上来就需要做当前CPU模式判断,在保护模式中,之后其按顺序出栈,加载段选择子,这些很好理解,在上篇文章中这些具体操作我们都分析过了,这里就不过多解释了。
值得注意的是,好像无论trap还是interrupt,其iret时执行的行为方式没有差别,在分析过程中没有看到对此的区分,之后我们还会对trap再来一轮分析。
BX_CPU_C::iret_protected(bxInstruction_c *i)
{
/* 16bit opsize | 32bit opsize
* ==============================
* SS eSP+8 | SS eSP+16
* SP eSP+6 | ESP eSP+12
* -------------------------------
* FLAGS eSP+4 | EFLAGS eSP+8
* CS eSP+2 | CS eSP+4
* IP eSP+0 | EIP eSP+0
*/
temp_ESP = ESP;
new_eflags = stack_read_dword(temp_ESP + 8);
raw_cs_selector = (Bit16u) stack_read_dword(temp_ESP + 4);
new_eip = stack_read_dword(temp_ESP + 0);
parse_selector(raw_cs_selector, &cs_selector);
fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION);
parse_descriptor(dword1, dword2, &cs_descriptor);
// check code-segment descriptor
check_cs(&cs_descriptor, raw_cs_selector, 0, cs_selector.rpl);
raw_ss_selector = stack_read_word(temp_ESP + 16);
parse_selector(raw_ss_selector, &ss_selector);
fetch_raw_descriptor(&ss_selector, &dword1, &dword2, BX_GP_EXCEPTION);
parse_descriptor(dword1, dword2, &ss_descriptor);
new_esp = stack_read_dword(temp_ESP + 12);
// 加载cs段选择子,修改RIP
branch_far(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl);
writeEFlags(new_eflags, changeMask);
// load SS:eSP from stack
// load the SS-cache with SS descriptor
load_ss(&ss_selector, &ss_descriptor, cs_selector.rpl);
if (ss_descriptor.u.segment.d_b)
ESP = new_esp;
else
SP = new_esp;
validate_seg_reg(BX_SEG_REG_ES);
validate_seg_reg(BX_SEG_REG_DS);
validate_seg_reg(BX_SEG_REG_FS);
validate_seg_reg(BX_SEG_REG_GS);
}
// stack
> bochs.exe!BX_CPU_C::iret_protected(bxInstruction_c * i) Line 318 C++
bochs.exe!BX_CPU_C::IRET32(bxInstruction_c * i) Line 569 C++
bochs.exe!BX_CPU_C::cpu_loop() Line 109 C++
bochs.exe!bx_dbg_stepN_command(int cpu, unsigned int count) Line 2083 C++
总结
iret指令本身没什么复杂的,就是出栈修改cs,ss,esp,eip,eflag这个几个值。我们之后如果遇见retf来在进行对比一番,并不复杂。
1021



被折叠的 条评论
为什么被折叠?



