- 11 Aug, 2021 1 commit
-
-
Xiangyu,Ren authored
-
- 05 Aug, 2021 18 commits
-
-
Haochen Gong authored
-
-
LoanCold authored
-
-
-
LoanCold authored
-
Haochen Gong authored
-
LoanCold authored
-
LoanCold authored
-
-
Haochen Gong authored
-
LoanCold authored
-
LoanCold authored
-
LoanCold authored
-
LoanCold authored
-
LoanCold authored
-
-
LoanCold authored
-
- 04 Aug, 2021 2 commits
-
-
Haochen Gong authored
-
Xiangyu,Ren authored
-
- 03 Aug, 2021 9 commits
-
-
Xiangyu,Ren authored
-
LoanCold authored
-
LoanCold authored
-
-
LoanCold authored
-
Haochen Gong authored
-
Haochen Gong authored
``` [trap] syscall [sys_exec] [sys_exec] get all data [exec] entry point = 0xF530 [exec] finish [sys_exec] ret [trap_ret] [trap_ret] enter trampoline [trap] [trap] timer [trap_ret] [trap_ret] enter trampoline [trap] [trap] syscall (260-wait4) [trap_ret] [trap_ret] enter trampoline ******** hit 0xf530 ******** [trap] [kernel] IllegalInstruction in application, core dumped. [kernel] Exception(IllegalInstruction) in application, bad addr = 0x0, bad instruction = 0x0, pid = 2, core dumped. ``` entry: 0x1059c 执行流:1059c->105c4 cb5c4->cb608 ```assembly 1059c: ef 00 e0 02 jal 46 <.text+0x1ca> 105a0: aa 87 add a5, zero, a0 105a2: 17 15 00 00 auipc a0, 1 105a6: 13 05 65 23 addi a0, a0, 566 105aa: 82 65 ld a1, 0(sp) 105ac: 30 00 addi a2, sp, 8 105ae: 13 71 01 ff andi sp, sp, -16 105b2: 97 b6 0b 00 auipc a3, 187 105b6: 93 86 e6 4a addi a3, a3, 1198 105ba: 17 b7 0b 00 auipc a4, 187 105be: 13 07 67 53 addi a4, a4, 1334 105c2: 0a 88 add a6, zero, sp 105c4: ef b0 0b 00 jal 765952 <.text+0xbb1c4> cb5c4: 29 71 addi sp, sp, -320 cb5c6: 22 fa sd s0, 304(sp) cb5c8: 26 f6 sd s1, 296(sp) cb5ca: 4a f2 sd s2, 288(sp) cb5cc: 32 e8 sd a2, 16(sp) #传参 * cb5ce: 06 fe sd ra, 312(sp) cb5d0: 13 03 00 00 mv t1, zero cb5d4: 2a ec sd a0, 24(sp) #传参 cb5d6: 2e e4 sd a1, 8(sp) #传参 * cb5d8: 36 84 add s0, zero, a3 cb5da: ba 84 add s1, zero, a4 cb5dc: 3e 89 add s2, zero, a5 cb5de: 01 46 mv a2, zero cb5e0: 63 06 03 00 beqz t1, 12 <.text+0xbb1ec> | cb5e4: 03 26 00 00 lw a2, 0(zero) | cb5e8: 13 36 16 00 seqz a2, a2 cb5ec: a2 67 ld a5, 8(sp) #arg1 cb5ee: 13 85 17 00 addi a0, a5, 1 cb5f2: c2 67 ld a5, 16(sp) #arg2 cb5f4: 0e 05 slli a0, a0, 3 cb5f6: 3e 95 add a0, a0, a5 cb5f8: 23 ac c1 d6 sw a2, -648(gp) cb5fc: 23 b8 a1 02 sd a0, 48(gp) cb600: b7 b7 1a 00 lui a5, 427 cb604: 23 b8 07 fb sd a6, -80(a5) cb608: 10 61 ld a2, 0(a0) # crash cb60a: 21 05 addi a0, a0, 8 cb60c: 75 fe bnez a2, -4 <.text+0xbb208> ``` 出错指令地址:0x1326ae ```assembly 108b90: b3 07 80 40 neg a5, s0 108b94: 33 85 84 00 add a0, s1, s0 108b98: e3 e5 f4 fc bltu s1, a5, -54 <.text+0xf8762> cb626: ef 00 60 29 jal 662 <.text+0xbb4bc> | cba26: 01 45 mv a0, zero cba28: ef a0 f4 2e jal 305902 <.text+0x106116> | 116516: 79 71 addi sp, sp, -48 116518: 26 ec sd s1, 24(sp) 11651a: 01 46 mv a2, zero 11651c: 2c 00 addi a1, sp, 8 11651e: aa 84 add s1, zero, a0 116520: 01 45 mv a0, zero 116522: 06 f4 sd ra, 40(sp) 116524: 22 f0 sd s0, 32(sp) 116526: ef 00 70 22 jal 2598 <.text+0x106b4c> cb940: 13 89 fb ff addi s2, s7, -1 cb944: b3 57 a9 03 <unknown> cb948: 6e 99 add s2, s2, s11 cb94a: 33 8c a7 03 <unknown> cb94e: 62 e4 sd s8, 8(sp) cb950: 03 b5 81 d9 ld a0, -616(gp) cb954: 36 e0 sd a3, 0(sp) cb956: 13 05 05 71 addi a0, a0, 1808 cb95a: 6e 95 add a0, a0, s11 cb95c: 66 95 add a0, a0, s9 cb95e: 62 95 add a0, a0, s8 #here cb960: ef d0 c3 1d jal 250332 <.text+0xf873c> | 108b3c: 01 11 addi sp, sp, -32 108b3e: 4a e0 sd s2, 0(sp) 108b40: 26 e4 sd s1, 8(sp) 108b42: 83 b4 81 3c ld s1, 968(gp) 108b46: 22 e8 sd s0, 16(sp) 108b48: 06 ec sd ra, 24(sp) 108b4a: 2a 84 add s0, zero, a0 108b4c: 95 c8 beqz s1, 52 <.text+0xf8780> | 108b80: 01 45 mv a0, zero 108b82: ef 90 92 30 jal 170760 <.text+0x12228a> | 13268a: aa 87 add a5, zero, a0 13268c: 93 08 60 0d addi a7, zero, 214 132690: 73 00 00 00 ecall 132694: 23 b4 a1 3c sd a0, 968(gp) 132698: 63 64 f5 00 bltu a0, a5, 8 <.text+0x1222a0> 13269c: 01 45 mv a0, zero 13269e: 82 80 ret | 108b86: 63 4f 05 00 bltz a0, 30 <.text+0xf87a4> 108b8a: 83 b4 81 3c ld s1, 968(gp) 108b8e: d9 b7 j -58 <.text+0xf8754> | 108b54: 19 cc beqz s0, 30 <.text+0xf8772> 108b56: 63 5d 80 02 blez s0, 58 <.text+0xf8790> 108b5a: 33 85 84 00 add a0, s1, s0 108b5e: 63 7f 95 02 bgeu a0, s1, 62 <.text+0xf879c> | 108b9c: ef 90 f2 2e jal 170734 <.text+0x12228a> | 1326a0: 97 a7 07 00 auipc a5, 122 #a5 = 0x1ac6a0 1326a4: 83 b7 07 56 ld a5, 1376(a5) #addr = 0x1acc00 1326a8: 31 47 addi a4, zero, 12 1326aa: 7d 55 addi a0, zero, -1 1326ac: 92 97 add a5, a5, tp 1326ae: 98 c3 sw a4, 0(a5) # crash here 1326b0: 82 80 ret ``` 0x1acc00位于 .got段,该段用于存储全局变量的地址 .got和.data实际上都有数据,但是gdb发现,程序运行时这段内存没数据。 在from_elf插桩如下: ```rust if let Some(sec) = elf.find_section_by_name(".got"){ println!("{:#?}", sec.raw_data(&elf)); //打印.got的数据 } ``` 发现存在数据且正确,证明ELF无误,且被载入内存。 继续插桩,发现向用户map的时候,复制了elf.input的[0x0 .. 0x10BE68],以及[0x10cd10 .. 0x110500],.got位于elf.input的[0x110328 .. 0x110328+0x1d8] 有一点需要注意,got恰好在最后 .got实际上在 0x121328 进一步插桩,copy_data时第二段的虚地址范围是 0x11DD10..0x122D18, 检查发现,写入的虚拟页框包括11d,11e,11f,120,并没有121 0x122D18-0x11DD10 = 0x5008, 0x110500 - 0x10cd10 = 0x37F0 二者不一致,说明存在间隙,写虚拟页框使用了后者(即长度0x37F0),未能覆盖到121页框。 阅读代码发现,copy_data默认对齐页框: ```rust pub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8]) { assert_eq!(self.map_type, MapType::Framed); let mut start: usize = 0; //start实际上描述了长度,是页对齐的,但是data并不是页对齐的 let mut current_vpn = self.vpn_range.get_start(); let len = data.len(); loop { let src = &data[start..len.min(start + PAGE_SIZE)]; let dst = &mut page_table //这里写数据是页对齐的 .translate(current_vpn) .unwrap() .ppn() .get_bytes_array()[..src.len()]; dst.copy_from_slice(src); start += PAGE_SIZE; if start >= len { break; } current_vpn.step(); } } ``` 这就导致,整段程序都放偏了。 解决方案很简单,加一个offset。 ```assembly 6f6de: ee 97 add a5, a5, s11 # a5=0x10cdb0 6f6e0: 98 6b ld a4, 16(a5) 6f6e2: 63 0f 57 07 beq a4, s5, 126 <__run_exit_handlers+0x134> 6f6e6: e3 1d 27 fb bne a4, s2, -70 <__run_exit_handlers+0x74> 6f6ea: 98 6f ld a4, 24(a5) #0x10cdc8:0x0006afcc, in bss 6f6ec: 88 73 ld a0, 32(a5) 6f6ee: 23 b8 07 00 sd zero, 16(a5) 6f6f2: da 85 add a1, zero, s6 6f6f4: 02 97 jalr a4 # not gg ``` __libc_csu_fini 0x6afcc ... ```assembly 6f6de: ee 97 add a5, a5, s11 # a5=0x10cd90 6f6e0: 98 6b ld a4, 16(a5) 6f6e2: 63 0f 57 07 beq a4, s5, 126 <__run_exit_handlers+0x134> 6f6e6: e3 1d 27 fb bne a4, s2, -70 <__run_exit_handlers+0x74> 6f6ea: 98 6f ld a4, 24(a5) #0x10cda8:0x00000001, in bss 6f6ec: 88 73 ld a0, 32(a5) 6f6ee: 23 b8 07 00 sd zero, 16(a5) 6f6f2: da 85 add a1, zero, s6 6f6f4: 02 97 jalr a4 # a4 = 1, crash ``` 经过gdb检查,发现__internal_atexit把这个地址的值改了 \_\_cxa_atexit调用了 \__internal_atexit,功能为注册析构函数 exit时执行 追踪返回地址,发现 LIBC_START_MAIN 调用了\_\_cxa_atexit, ```assembly 6ab7a: 81 45 mv a1, zero 6ab7c: 4a 85 add a0, zero, s2 #a0 == 1 6ab7e: ef 40 50 61 jal 19988 <__cxa_atexit> #此处调用 ``` 上述调用以a0传参,__cxa_atexit的第一个参数为函数地址,也就导致之后跳转到这个地址 进一步追踪,s2实际上就是LIBC_START_MAIN 的第六个参数,由a5传递给S2 LIBC_START_MAIN 由_start调用,也就是程序的入口,发现\_start中,a0被传递给a5 ```assembly 105d4: aa 87 add a5, zero, a0 # a0 == 1 ``` 这里的a0实际上由syscall返回时将返回值填于用户上下文,而这个返回值就是sys_exec的返回值,之前的处理是返回参数个数,也就是1。 将返回值改为0,成功运行。 Merge branch 'master' of https://gitlab.eduxiji.net/ultrateam/ultraos
-
Haochen Gong authored
-
Haochen Gong authored
-
- 02 Aug, 2021 2 commits
-
-
Xiangyu,Ren authored
-
Haochen Gong authored
-
- 01 Aug, 2021 1 commit
-
-
Haochen Gong authored
-
- 31 Jul, 2021 7 commits
-
-
-
LoanCold authored
-
Haochen Gong authored
-
LoanCold authored
-
LoanCold authored
-
LoanCold authored
-
-