1. Overview
<shell />(gdb) disas phase_6
phase_6 함수의 구성을 살펴보자.
2. Defusing phase 6
입력한 숫자 a b c d e f g h. a가 가장 앞에 오는 순서로 stack에 저장됨.
test input : 1 2 3 4 5 6 7 8
r13 0으로 만들고 82로 이동
r12 즉 rsp를 rbp에 저장
eax에 a 저장후 1 빼기
eax는 7 이하. 즉 a는 8 이하
r13에 1 더하고 r13 == 8이면 112로 이동
r13 8 아니면 ebx에 r13 저장 후 60으로 이동
rax에 ebx 저장
stack에서 4 * rax의 index에 있는 값 eax로 이동
eax와 a는 달라야함. 52로 이동
ebx에 1 더하고 7보다 크면 78로 이동
7 이하면 rax에 ebx 저장
stack에서 4 * rax의 index에 있는 값 eax로 이동
eax와 a는 달라야함. 52로 이동
쭉 반복. a와 다른 7개의 숫자 같은 것 없는지 체크과정. 통과하면 78로 이동
r12에 4 더하고 rbp에 이동 (즉 rbp 4 늘림)
eax에 b 저장후 1 빼기
eax는 7 이하. 즉 b는 8 이하
r13에 1 더하고 8이면 112로 이동
8 아니면 ebx에 r13 저장 후 60으로 이동
쭉 반복. b와 이후의 6개의 숫자 체크, c와 5개 체크, d와 4개 체크, ... 8개의 숫자 모두 다른지 체크.
종료조건은 r13 == 8 (7번 시행 완료. 즉 7개의 숫자에 대해 모두 마쳤음)
ebx에 0 저장후 134로 이동
stack에서 rbx의 index에 있는 값(a) eax로 이동
edx에 eax 옮기고 edx logical right shift 31칸
eax에 edx 더하고 eax & 0x1
eax에서 edx 빼면 1이어야 함
stack에서 rbx + 0x4의 index에 있는 값(b) 짝수여야 함. 124로 이동
rbx 0x8 더하고 0x20 되었으면 168 이동, 아니면 134로
쭉 반복. rbx가 0에서 0x8씩 늘어나므로 eax에 저장되는 숫자는 a, c, e, g
어차피 1 ~ 8 중 하나이므로 edx logical right shift 31칸하면 0일거고.
eax 그대로에 0x1과 &해서 0x1이 되어야하므로 a, c, e, g는 홀수여야 함. (1, 3, 5 ,7 중 아무거나)
매번 rbx + 0x4의 index에 있는 값(각각 b, d, f, h)가 짝수인지 check한다. b, d, f, h는 짝수.
{
홀 짝 번갈아 나오는지 체크하고 168 이동
ecx에 0 저장후 r8에 rsp 저장
stack 0x4 index r9에 저장
stack 가장 앞 값(a) eax에 저장
esi에 eax 저장하고 esi logical right shift 31칸
esi에 eax 더하고 esi arith right shift 1칸
edi에 esi 저장하고 eax 0으로 만듦
esi 0이면 222로 이동, 아니면 211로 이어짐
211. rdx에 해당 node 0x8 index의 값(다음 노드 주소) 저장
eax에 1 더하고 eax와 같으면 222, 다르면 211.
222. stack의 2 * rcx + 0x20 index에 rdx 저장 (해당 노드 주소)
edx에 r9 + rcx 즉 stack 0x4 + rcx index 값(b) 저장
eax에 edx 저장하고 eax logical right shift 31칸
eax에 edx 더하고 eax arith right shift 1칸
esi에 eax 저장하고 rdx에 node2의 주소 0x555555758250 저장
eax가 1 이하면 270으로 이동
아니면 eax에 1 저장하고 rdx에 다음 node 주소 저장
eax 1 더하고 esi와 비교
270. stack의 2 * rcx + 0x28 index에 rdx 저장 (해당 노드 주소)
rcx에 0x8 더하고 0x20 아직 안됐으면 180으로 이동
stack rcx index(0x8) 값(c) eax에 저장
}
쭉 반복. rcx가 0에서 0x8씩 늘어나므로 eax에 저장되는 숫자는 a, c, e, g
어차피 1, 3, 5, 7중 하나이므로 esi shr 31하면 0
esi에 eax 더하면 원래값, sar 1 하면 1은 0, 3은 1, 5는 3, 7은 5가 됨.
edx는 b, d, f, h 저장됨
node 1, 2, 3, 4, 5, 6, 7, 8의 주소가 stack의 0x20 index부터 한칸씩 띄고(index 0x8차이) 순서대로 저장됨.
node 1의 주소를 rbp, node 2의 주소를 rbx, node 3의 주소를 rcx에 저장
rbp+0x8 즉 node 1 세번째 칸에 node 3 주소 저장
node 4의 주소를 rdx에 저장, rbx+0x8 즉 node 2 세번째 칸에 node 4 주소 저장
node 5의 주소를 rax에 저장, rcx+0x8 즉 node 3 세번째 칸에 node 5 주소 저장
node 6의 주소를 rcx에 저장, rdx+0x8 즉 node 4 세번째 칸에 node 6 주소 저장
node 7의 주소를 rdx에 저장, rax+0x8 즉 node 5 세번째 칸에 node 7 주소 저장
node 8의 주소를 rax에 저장, rcx+0x8 즉 node 6 세번째 칸에 node 8 주소 저장
node 7, 8 세번째 칸은 0으로 만들고 r12에 3 저장. 399로 이동.
rax에 node 1 세번째 칸에 저장된 node 3 주소 저장
node1 ~ 8 첫번째 칸의 값은 653, 400, 543, 299, 962, 627, 204, 739
node 3 첫번째 칸의 값 543 eax에 저장
node 1 첫번째 칸의 값 653보다 eax가 더 작거나 같아야 함. 즉 1 >= 3
node 4 첫번째 칸의 값 299 eax에 저장
node 2 첫번째 칸의 값 400보다 eax가 더 크거나 같아야 함. 즉 2 <= 4.
r12에서 1 빼기. r12가 0이 될때까지 총 세 번을 무사히 돌면 defuse.
rbp를 node 3의 주소로 만듦. 위에서 1~4에 대해 한 내용을 이번엔 3~6에 대해.
rbp를 node 5의 주소로 만듦. 이번엔 5~8에 대해.
종합하면 a b c d e f g h에 1~8을 입력하는데
a, c, e, g에는 홀수, b, d, f, h에는 짝수.
1~8은 각각 653, 400, 543, 299, 962, 627, 204, 739과 대응되고
대응하는 숫자 끼리의 대소관계가 a >= c >= e >= g, b <= d <= f <= h이어야 함.
따라서 1(653), 3(543), 5(962), 7(204)끼리의 대소관계와
2(400), 4(299), 6(627), 8(739)끼리의 대소관계를 각각 생각해보면
답은 5 4 1 2 3 6 7 8
'Study > CS' 카테고리의 다른 글
Lab3: Attacklab (phase 1) (0) | 2023.10.29 |
---|---|
Lab2: Bomblab (secret phase) (1) | 2023.10.08 |
Lab2: Bomblab (phase 5) (0) | 2023.10.08 |
Lab2: Bomblab (phase 4) (0) | 2023.10.08 |
Lab2: Bomblab (phase 3) (1) | 2023.10.08 |