Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v8에서 crash가 발생하는 특수한 상황 #2 #20

Closed
ParkHanbum opened this issue Jul 30, 2019 · 0 comments
Closed

v8에서 crash가 발생하는 특수한 상황 #2 #20

ParkHanbum opened this issue Jul 30, 2019 · 0 comments

Comments

@ParkHanbum
Copy link
Owner

앞에서 본 문제가 발생하는 것을 막기 위해 심플한 검증 로직을 추가하여,
RET에 주소가 실행가능한 영역이 아닌 경우에는 복귀주소 후킹을 하지 못하도록
코드를 추가했다.

하지만 이런 검증 로직에도 불구하고 여전히 문제가 발생하는데,
이 또한 역시 v8의 interpreting 로직의 특수성 때문이다.

문제가 발생하는 곳은 다음의 함수이다.

Dump of assembler code for function Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit:
0x00007ffff772ee24 <+100>:   mov    rcx,QWORD PTR [rbp+0x8]                                                                                                                                                                                  0x00007ffff772ee28 <+104>:   mov    rbp,QWORD PTR [rbp+0x0]                                                                                                                                                                                  0x00007ffff772ee2c <+108>:   lea    rsp,[r15+0x8]                                                                                                                                                                                            0x00007ffff772ee30 <+112>:   push   rcx                                                                                                                                                                                                   => 0x00007ffff772ee31 <+113>:   mov    rsi,QWORD PTR [r13+0x2f78]  

설명에 앞서 rcx에 적재되는 값의 주소는

Thread 2.1 "d8" hit Breakpoint 5, 0x00007ffff772ee24 in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit () from /home/m/git/v8/v8/out.gn/x64.debug/./libv8.so
$1 = 0x7fffffffcac8

0x7fffffffcac8 + 0x8 = 0x7fffffffcad0 이다.

왜 문제가 발생하는지 설명하자면,

0x00007ffff772ee24 <+100>:   mov    rcx,QWORD PTR [rbp+0x8]                                                                                                                                                                                  0x00007ffff772ee28 <+104>:   mov    rbp,QWORD PTR [rbp+0x0]   

이곳에서 복귀주소를 읽어,
다음 명령을 통해

0x00007ffff772ee30 <+112>:   push   rcx   

stack에 push하고 return한다.

0x00007ffff772ee38 <+120>:   mov    QWORD PTR [r13+0x2f78],0x1                                                                                                                                                                               0x00007ffff772ee43 <+131>:   mov    QWORD PTR [r13+0x2fd0],0x0                                                                                                                                                                               0x00007ffff772ee4e <+142>:   ret       

이 때 call stack은 uftrace에 의해 hooking 된 주소가 들어가 있다.

(gdb) call mcount_iterate_mtdp()
WARN: [IDX] [OFFSET] [PARENT_LOC](CURRENT_VALUE) [PARENT_VALUE](STORED) [CHILD]
WARN: [0] [0] 0x7fffffffcc18(value:0x7ffff6b4b58c)       0x7ffff6b4b58c  0x7ffff73bccc5
WARN: [1] [13] 0x7fffffffcbb0(value:0x7ffff73bcd38)      0x7ffff73bcd38  0x7ffff73bcf65
WARN: [2] [5] 0x7fffffffcb88(value:0x7ffff73bcfbd)       0x7ffff73bcfbd  0x7ffff73c75c5
WARN: [3] [23] 0x7fffffffcad0(value:0x7ffff7bbf4a3)      0x7ffff78faa1c  0x7ffff772edc5

(gdb) x/i 0x7ffff772edc5
   0x7ffff772edc5 <Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit+5>: nop

(gdb) p/x mtd->rstack[3]
$2 = {parent_loc = 0x7fffffffcad0, parent_ip = 0x7ffff78faa1c, child_ip = 0x7ffff772edc5, flags = 0x40, start_time = 0x216c8623942d9, end_time = 0x0, tid = 0x0, dyn_idx = 0xefefefef, filter_time = 0x0, depth = 0x3,
  filter_depth = 0x3fd, nr_events = 0x0, event_idx = 0x400, pd = 0x0, pargs = 0x0}

(gdb) x/i 0x7ffff73c75c5
   0x7ffff73c75c5 <Builtins_InterpreterEntryTrampoline+5>:      nop

호출은 Builtins_InterpreterEntryTrampoline -> Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit 순으로 이뤄지며, Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit 함수에서는 Builtins_InterpreterEntryTrampoline 의 리턴주소를 읽어들여 stack에 push하고 리턴하게 된다.

이것은 동일한 함수에서 이뤄지기 때문에, uftrace 입장에서는 정상적인 동작이나 v8에서는 그렇지 않다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant