前言
我们现在在构建好分页模式的基础上,来通过对mov指令的分析来实现对bochs的Non-PAE-4K分页机制的分析,在分析过程中,我们会看到关于对页属性的各种检查,之后再来总结。
注意,其中可能涉及缓存部分(TLB),这个我们决定放在后面分析,因此如果遇到TLB信息,我们暂且跳过,不做过多解读。
反汇编定位代码
我们现在先将ex11-2/protected.asm中测试二的代码注释掉,为分析直观,将mov[xx],0 改为 mov[xx],4. 然后按照我们上篇文章补充的Shell脚本来进行编译,内容如下:
; 测试二:在 CR0.WP=0时,在0级代码里写0x400000地址
mov DWORD [0x400000], 4
使用IDA来逆向这部分,定位其汇编地址,内容如下:
现在通过bochs来运行到bochs反汇编代码,内容如下:
堆栈分析-1
其核心代码在 BX_CPU_C::access_write_linear(...) 中,从cpu->execute1(...)到access_write_linear(...) 经过一系列函数,这些函数并没有什么核心代码,只是基本单纯地封装调用,我们直接展示其函数堆栈。
> bochs.exe!BX_CPU_C::access_write_linear(unsigned __int64 laddr, unsigned int len, unsigned int curr_pl, unsigned int xlate_rw, unsigned int ac_mask, void * data) Line 2402 C++
bochs.exe!BX_CPU_C::write_linear_dword(unsigned int s, unsigned __int64 laddr, unsigned int data) Line 102 C++
bochs.exe!BX_CPU_C::write_virtual_dword(unsigned int s, unsigned __int64 offset, unsigned int data) Line 200 C++
bochs.exe!BX_CPU_C::MOV_EdIdM(bxInstruction_c * i) Line 30 C++
bochs.exe!BX_CPU_C::cpu_loop() Line 109 C++
access_write_linear(...)函数分析
我们现在来分析access_write_linear(..)的代码,其函数定义如下:
int BX_CPU_C::access_write_linear(
bx_address laddr, // 线性地址 0x400000
unsigned len, // 数据长度 4
unsigned curr_pl, // 当前的CPL 0
unsigned xlate_rw, // 读写 BX_WRITE
Bit32u ac_mask, // 0x3
void *data // 写入数据的指针
){
....
}
在这部分函数中,有两个非常重要的代码,下面我们会重点分析这两部分代码。
translate_linear(...)函数是将线性地址转化为物理地址,其中有一个tlbEntry,这个是TLB页缓的,如果该地址在tlb中存在缓存,则优先从缓存中获取。
bx_bool user = (curr_pl == 3);
BX_CPU_THIS_PTR address_xlation.paddress1