-
double fetch case 0
抓到的double fetch很多,只能一个一个看了。 留个记录。 DOUBLE FETCH: cr3 0x11067e000, syscall 0x88 eip 0xfffff80179ca0603, user_address 0xf5880ff360, user_data 0x1000, modrm 0x1, pc 0xfffff80179ca09c1 eip 0xfffff80179ca0603, user_address 0xf5880ff360, user_data 0x1000, modrm 0x1, pc 0xfffff80179ca09df LAB_1404169a5 XREF[1]: 140416ab1(j) 1404169a5 4d 85 c0 TEST param_3,param_3 1404169a8 0f 84 18 JZ LAB_140416ac6 01 00 00 1404169ae 49 8b...
-
接着搞double fetch
对qemu tcg了解的不够,env->eip并不是准确的当前指令的地址。 长的差不多的还有s->pc,s->pc_start,s->pc_next,GETPC()等等。 现在来看,pc_start有可能是。 之前我打印出了modrm的一个字节,发现env->eip和这个modrm总是不一一对应。这肯定不对,modrm是在指令里的。 用pc_start后,分析一条记录。 DOUBLE FETCH: cr3 0xa9774000, syscall 0x88 eip 0xfffff80179c9f8e1, user_address 0x13ee991bec8, user_data 0x7c000000, modrm 0x38, pc 0xfffff80179c9f9eb eip 0xfffff80179ca2b6e, user_address 0x13ee991bec8, user_data 0x7c000000, modrm 0x19, pc 0xfffff80179ca2bb8 DIFF EIP 在ghidra里搜memory,48 b8 38没有搜到,搜b8 38能搜到不少,是读32bit的。 然后在ghidra的搜索结果里面过滤9eb,只能按页面内偏移找了,说明x64上模块加载的基址和各个section的位值不能想当然的 认为会在64k或什么地方对齐。 LAB_1404159eb XREF[1]: 140415b0d(j) --> 1404159eb 8b 38 MOV EDI,dword ptr...
-
跟着看一个double fetch
之前qemu的ld范围太大了,连pop edx这样的指令因为有读栈的操作,都会用道ld。 现在改成只抓0x8b的mov,也就是mov Gv, Ev,从Ev往Gv(寄存器)里搬。 因为是64位系统,0x8b前可能会有prefix 0x48。 比如下面这条记录: DOUBLE FETCH: cr3 0x107c36000, syscall 0x42 eip 0xfffff8006a08a540, user_address 0xc93b1fed88, user_data 0xc93b1fed90, s->pc 0xfffff8006a08a8a8 eip 0xfffff8006a079030, user_address 0xc93b1fed88, user_data 0xc93b1fed90, s->pc 0xfffff8006a07911e DIFF EIP 因为不知道kernel的加载基址,所以只能用笨办法在ghidra里按最后4位的地址搜。 这会只需要找8b或者48 8b的,如果还不好找,可以考虑把modrm的这个字节也打印出来。 0xfffff8006a08a540 ************************************************************** * FUNCTION * ************************************************************** undefined FUN_1400ca52c() undefined AL:1 <RETURN> undefined8 Stack[0x18]:8 local_res18 XREF[2]:...