Commit d15de8a1 authored by Haochen Gong's avatar Haochen Gong
Browse files

执行流:exec busybox正常返回,然后触发了时钟中断,再次trap,切换进程,进程wait4,换到2,然后死在user.

```
[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
Showing with 7 additions and 4 deletions
+7 -4
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment