[WinDbg] x64 security_cookie 사용(버퍼오버런을 진입점과 종료점에서 검사해서 틀리면 예외 발생)

x64에서는 콜스택을 볼때 #1, #2  매개변수는 rcx, rdx로 입력이 되기 때문에 기존의 콜스택처럼 매개변수 값을 확인할 수 없다.
다음은 FileTimeToSystemTime 호출될때의 과정을 기술한 거다.

rsp = 008f8ef8
rcx = 008f8f48
rdx = 008f8f60

rsp ->
00000000`008f8ef8  00007ff6`4d7e1fc2 01d3f629`e281c09d
00000000`008f8f08  00000000`00000000 00000000`00910072

위 RSP값은 rsp+18h = rbx를 넣은 상태이다.

push rbp ; rsp = 008f8ef0
{
00000000`008f8ef0  rbp 00007ff6`4d7e1fc2
   01d3f629`e281c09d 00000000`008f8f08
   00000000`00000000 00000000`00910072
}
mov rbp, rsp ; rbp는 이 함수내에서 로컬변수를 저장하기 위한 기준점이 된다. 보통 rbp-8 = security_cookie
sub rsp, 40h ; rsp = 008f8eb0
{
00000000`008f8eb0  0 0
   0 0
   0 0
   0 security_cookie
00000000`008f8ef0  rbp 00007ff6`4d7e1fc2
}

KERNELBASE!FileTimeToSystemTime:
00007ff9`3e283ba0 48895c2418      mov     qword ptr [rsp+18h],rbx
00007ff9`3e283ba5 55              push    rbp
00007ff9`3e283ba6 488bec          mov     rbp,rsp
00007ff9`3e283ba9 4883ec40        sub     rsp,40h
00007ff9`3e283bad 488b05ccd62000  mov     rax,qword ptr [KERNELBASE!_security_cookie (00007ff9`3e491280)]
00007ff9`3e283bb4 4833c4          xor     rax,rsp
00007ff9`3e283bb7 488945f8        mov     qword ptr [rbp-8],rax ; rbp-8 = rsp ^ security_cookie
00007ff9`3e283bbb 8b01            mov     eax,dword ptr [rcx] ; eax = 첫번째 매개변수
00007ff9`3e283bbd 488bda          mov     rbx,rdx ; rbx = 두번째 매개변수
00007ff9`3e283bc0 8945e0          mov     dword ptr [rbp-20h],eax
00007ff9`3e283bc3 8b4104          mov     eax,dword ptr [rcx+4]
00007ff9`3e283bc6 8945e4          mov     dword ptr [rbp-1Ch],eax
00007ff9`3e283bc9 48837de000      cmp     qword ptr [rbp-20h],0
00007ff9`3e283bce 0f8caac70600    jl      KERNELBASE!FileTimeToSystemTime+0x6c7de (00007ff9`3e2f037e)

KERNELBASE!FileTimeToSystemTime+0x34:
00007ff9`3e283bd4 488d55e8        lea     rdx,[rbp-18h]
00007ff9`3e283bd8 488d4de0        lea     rcx,[rbp-20h]
00007ff9`3e283bdc ff150e591500    call    qword ptr [KERNELBASE!_imp_RtlTimeToTimeFields (00007ff9`3e3d94f0)]
00007ff9`3e283be2 0fb745e8        movzx   eax,word ptr [rbp-18h]
00007ff9`3e283be6 668903          mov     word ptr [rbx],ax
00007ff9`3e283be9 0fb745ea        movzx   eax,word ptr [rbp-16h]
00007ff9`3e283bed 66894302        mov     word ptr [rbx+2],ax
00007ff9`3e283bf1 0fb745ec        movzx   eax,word ptr [rbp-14h]
00007ff9`3e283bf5 66894306        mov     word ptr [rbx+6],ax
00007ff9`3e283bf9 0fb745f6        movzx   eax,word ptr [rbp-0Ah]
00007ff9`3e283bfd 66894304        mov     word ptr [rbx+4],ax
00007ff9`3e283c01 0fb745ee        movzx   eax,word ptr [rbp-12h]
00007ff9`3e283c05 66894308        mov     word ptr [rbx+8],ax
00007ff9`3e283c09 0fb745f0        movzx   eax,word ptr [rbp-10h]
00007ff9`3e283c0d 6689430a        mov     word ptr [rbx+0Ah],ax
00007ff9`3e283c11 0fb745f2        movzx   eax,word ptr [rbp-0Eh]
00007ff9`3e283c15 6689430c        mov     word ptr [rbx+0Ch],ax
00007ff9`3e283c19 0fb745f4        movzx   eax,word ptr [rbp-0Ch]
00007ff9`3e283c1d 6689430e        mov     word ptr [rbx+0Eh],ax
00007ff9`3e283c21 b801000000      mov     eax,1

KERNELBASE!FileTimeToSystemTime+0x86:
00007ff9`3e283c26 488b4df8        mov     rcx,qword ptr [rbp-8] ; rcx = rsp ^ security_cookie
00007ff9`3e283c2a 4833cc          xor     rcx,rsp ; rcx = 위에서 저장한 rsp의 값을 가리키고 있어야 한다.
00007ff9`3e283c2d e82eea0500      call    KERNELBASE!_security_check_cookie (00007ff9`3e2e2660)
00007ff9`3e283c32 488b5c2460      mov     rbx,qword ptr [rsp+60h]
00007ff9`3e283c37 4883c440        add     rsp,40h
00007ff9`3e283c3b 5d              pop     rbp
00007ff9`3e283c3c c3              ret


GetVolInfo(g_csVolInfo, NULL) 호출되기 전
{
xor edx,edx ; edx=0
lea rbp, [Test!g_csVolInfo]
mov rcx,rbp ; rcx에 바로 g_csVolInfo를 넣지 않고 있음을 주목!
call Test!GetVolInfo
{
rbx=0000000000910072 rcx=00007ff64d7e6f88 rdx=0000000000000000 rsp=00000000008f8ef8

push rbx ; rsp=00000000'008f8ef0
{
00000000`008f8ef0  00000000`00910072 00007ff6`4d7e1fd3 <- 00910072는 rbx값이고
00000000`008f8f00  01d3f629`e281c09d 00000000`00000000
}

sub rsp,520h ; rsp=00000000'008f89d0
mov rax,security_cookie ; rax=0000f2d7319c4124
xor rax,rsp ; rax=0000f2d73113c8f4
mov qword ptr[rsp+510h],rax ; 아래와 같이 rsp+510h 위치에 security_cookie값 들어감
{
00000000`008f8ee0  rax 00001d88`4b41a09b
00000000`008f8ef0  00000000`00910072 00007ff6`4d7e1fd3
}

여기는 내가 만든 명령문들로 채워져 있고

return TRUE;
{
mov eax,1
mov rcx,qword ptr[rsp+510h] ; rcx=0000f2d73113c8f4
xor rcx,rqp ; rcx=0000f2d7319c4124
call __security_check_cookie
add rsp,520h ; rsp=00000000'008f8ef0
pop rbx; ;   rsp=00000000'008f8ef8 rbx=00000000`00910072
}
}
}


댓글

댓글 쓰기

이 블로그의 인기 게시물

[WinAPI] 모달리스 다이얼로그 설명

[WinDbg] Debugging a stack overflow

[WinDbg] first-chance, second-chance Exception