Computer Science/System Programming
[시스템 프로그래밍] Malloc Lab Explicit (2)
[시스템 프로그래밍] Malloc Lab Explicit (2)
2023.01.167. free 함수 구현 할당된 메모리를 가용 가능한 상태로 만드는 free 함수를 구현하자. free 함수는 반환할 블록의 위치를 인자로 받고 해당 블록의 가용 상태로 바꾸는 역할을 한다. 이제 다시 테스트를 돌려 보자. 성능에 변화가 없다 -_- 아마도 free로 블록을 가용 상태로 만들었지만 coalescing 작업을 수행하지 않아 가용 리스트에 free 된 블록이 들어가지 않아 아무 효과를 얻지 못하는 것 같다. 8. place 함수 수정 + free 함수 수정 free 함수에 coalesce 작업을 추가해 가용 리스트에 가용 블록을 넣어 주자. implicit에서 작성한 것처럼 place 함수를 수행할 때 블록을 나눌 수 있는 경우 나눠서 공간을 확보하자. implicit 때와 다르게 가용 리스..
[시스템 프로그래밍] Malloc Lab Explicit (1)
[시스템 프로그래밍] Malloc Lab Explicit (1)
2023.01.14explicit 방식은 implicit 방식의 단점을 보완한다. 가용블록을 위와 같이 디자인한다. header 4바이트 / pred + succ 16바이트 / footer 4바이트로 총 24바이트의 크기를 가진다. pred와 succ 포인터를 통해 힙 공간 중 가용 가능한 공간들만 linked list 형태로 관리하는 방식을 사용한다. 할당된 블록은 위와 같이 디자인한다. (implicit과 동일) 가용 가능 블록들에 대해서는 prev와 succ포인터를 추가해야 해서 메모리를 조금 더 사용해야 하지만 그만큼의 이점이 있다. implicit 방식으로 first fit을 구현할 때는 최악의 경우 전체 블록을 모두 조사해야 가용 블록을 찾을 수 있지만, explicit 방식을 사용하면 조사 대상을 전체 블록 ..
[시스템 프로그래밍] Malloc Lab Implicit (2)
[시스템 프로그래밍] Malloc Lab Implicit (2)
2023.01.116. coalesce() 함수 구현 사용하는 이유는 위에서 살펴봤고.. 바로 구현해보자. 1. 이전 블록과 다음 불록이 모두 할당 된 상태 -> 합칠 수 없으니 그대로 반환한다. 2. 다음 블록이 가용 상태 -> 다음 블록과 합치고 반환한다. 3. 이전 블록이 가용 상태 -> 이전 블록과 합치고 반환한다. 4. 이전과 다음 모두 가용 상태 -> 둘 모두 합치고 반환한다. extend_heap 함수를 사용할 때 coalesce 함수를 호출하도록 설정했다. 다시 한 번 테스트 해 보자. 점수가 정말 낮지만 오류는 발생하지 않았다. 가용 블록을 합치지 않아 크기가 제대로 정렬되지 않았다고 생각한 게 맞았나보다. 이제 성능을 끌어올려보자. 7. place 함수 수정 place 함수로 블록을 할당할 때 할당할 크..
[시스템 프로그래밍] Malloc Lab Implicit (1)
[시스템 프로그래밍] Malloc Lab Implicit (1)
2023.01.10이론에서 배운 것들을 활용해 Malloc Lab을 해결해보자. WSIZE : 메모리 블록의 header와 footer 크기이다. (word 크기) DSIZE : WSIZE의 두 배 크기. CHUNKSIZE : 초기 가용 블록의 크기와 힙을 확장할 때 사용되는 값이다. OVERHEAD : header와 footer를 더한 크기이다. MAX, MIN : 말 그대로.. 두 수를 비교한다. PACK : 크기(size)와 할당 비트(alloc)을 통합해 하나의 워드로 묶는다. header와 footer에 값을 저장 할 때 사용한다. GET : 포인터 p가 가리키는 위치에서 word 크기의 값을 읽어온다. PUT : 포인터 p가 가리키는 위치에서 word 크기의 값을 val 만큼 쓴다. GET_SIZE : head..
[시스템 프로그래밍] Bomb Lab Phase Secret
[시스템 프로그래밍] Bomb Lab Phase Secret
2022.12.30phase_defused 함수에서 secret_phase를 해결할 수 있다. disas phase_defused 명령어로 어셈블리어를 조사하자. +184줄에서 secret_phase를 호출함을 찾을 수 있다. 이제 어떻게 secret_phase 함수를 호출할지 생각해보자. +30 : 6과 어떤 값을 비교해서 같으면 +64줄로 점프한다. 여기서 비교하는 값은 각 페이즈를 defuse 할 때 마다 1씩 증가한다. phase_6까지 defuse 했으니 secret_phase로 접근하는 조건을 갖췄다. +79줄과 +86줄에서 뭔가 입력받는 것 같다. 레지스터를 출력해서 어떤 형식으로 입력받는지 알아보자. 정수 두 개와 문자열 하나를 입력받는다. 아래에서 string_not_equal 함수를 호출하고 있다. ph..
[시스템 프로그래밍] Bomb Lab Phase 6
[시스템 프로그래밍] Bomb Lab Phase 6
2022.12.27disas phase_6 명령어로 phase_6의 어셈블리어를 조사하자. phase_6은 마지막 페이즈라서 그런지 어셈블리 코드가 정말 길다. 일단 익숙한 함수인 read_six_numbers가 보인다. 이번에도 6개의 정수를 입력받는 것 같다. 항상 하던대로 phase_6에 브레이크를 설정하고 아무 숫자나 입력해보자. 대충 3 4 5 6 7 8을 입력했다. 이제 어셈블리어의 흐름을 쭉 따라가보자. +34 : read_six_numbers 함수를 호출해 6개의 정수를 읽는다. +42 : r14d에 0을 저장한다. +48 : +87줄로 점프한다. r13에는 처음 입력한 숫자인 3이 저장돼있다. +87과 +90줄에서 r13값을 rbp와 eax에 저장한다. +94 : eax에서 1을 뺀다. +97 : eax에..
[시스템 프로그래밍] Bomb Lab Phase 5
[시스템 프로그래밍] Bomb Lab Phase 5
2022.12.25disas phase_5 명령어로 phase_5의 어셈블리어를 조사하자. +4줄에서 string_length 함수를 호출한다. 문자열의 길이? 어떤 함수일까? 뭔가 조건이 만족 될 때 까지 반복하는 함수 인 것 같다. 입력받은 문자열 내부를 순회하면서 문자열에 따라 특정 값을 계속해서 더하는 것 같은데.. 우선은 phase_5를 계속 조사하자. 다시 phase_5로 돌아와서, +9줄에서 string_length 함수의 반환값이 6과 같은지 검사하고, 6이 아니면 폭탄을 터뜨림을 확인할 수 있다. 그러면 phase_5의 입력 양식은 길이가 6인 문자열 일텐데.. 일단 길이가 6인 아무 문자열이나 입력하고 디버깅해보자. 대충 aaaccc를 입력했다. rdi 레지스터에 입력 값이 저장됨을 확인할 수 있다. +..
[시스템 프로그래밍] Bomb Lab Phase 4
[시스템 프로그래밍] Bomb Lab Phase 4
2022.12.24항상 하던대로 먼저 phase_4의 어셈블리어를 조사하자. +35줄에서 입력받는 부분이 바로 보인다. phase_2와 phase_3에서 한 것처럼 입력 형식을 살펴보자. 이번에도 두 개의 정수를 입력받는다. 두 개의 정수이니, 대충 1 2를 입력하고 한 줄 씩 진행해보자. +40 줄에서 eax값과 2를 비교하고, +43에서 두 값이 다른 경우 폭탄을 터뜨린다. +40줄에서 레지스터의 값을 확인해보니 rax에 2가 저장돼있었다. 따라서 43줄에서 폭탄은 터지지 않는다. 아마 두 개의 입력이 잘 들어왔는지 확인하는 부분 인 것 같다. 이후 +45줄에서 0xe와 rsp에 있는 값을 비교한다. rsp에는 입력한 값인 1과 2가 저장돼있다. +49줄에서 +45줄의 결과에 따라 폭탄을 터뜨린다. 0xe는 10진수로..
[시스템 프로그래밍] Bomb Lab Phase 3
[시스템 프로그래밍] Bomb Lab Phase 3
2022.12.23disas phase_3로 phase_3 함수를 어셈블리어로 조사해보자. +35줄에서 정수를 입력받는 것 같다. phase_2처럼 +28의 source 부분에 입력값의 형태가 저장돼 있을 것 같다. 어떤 형식으로 입력받는지 살펴보자. ni 명령어로 한 줄 씩 읽어가면서 source 부분을 확인해봤다. 정수 2개를 입력받는 것 같다. 적당히 break를 설정하고 두 개의 숫자를 입력해서 다시 실행해보자. 대충 3 4로 입력했다. +40줄에서 1과 eax의 값을 비교한다. 그러면 eax의 값을 알아야 하는데.. 다시 한 줄 씩 실행하면서 확인해보자. +40줄 까지 진행한 후 레지스터의 상태를 확인해보니 rax 레지스터에는 2가 저장돼있음을 확인할 수 있다. +43줄에서 jle 명령어가 실행된다. 2는 1보다..
[시스템 프로그래밍] Bomb Lab Phase 2
[시스템 프로그래밍] Bomb Lab Phase 2
2022.12.22disas phase_2 명령어로 phase_2 함수를 어셈블리어로 살펴보자. +25줄에서 함수를 호출한다. 이름 그대로 6개의 숫자를 입력받는 것 같은데.. 어셈블리어로 살펴보자. +41줄에 scanf 함수를 볼 수 있는데, 역시 숫자를 입력받는게 맞는 것 같다. 레지스터를 열어 보니 확실히 6개의 정수를 입력받는다. 나머지 내용은 잘 모르겠고.. 일단 read_six_numbers 함수에서 여섯 개의 정수를 입력받는다는 사실을 알아냈다. 다시 phase_2 함수로 돌아오자. +30줄에서 스택의 첫 번째 수가 1인지 확인하고 있다. +34줄에서 zero flag가 0이면 +45줄로 가서 폭탄을 터뜨린다. 아하! 스택의 첫 번째 값은 1이구나! 즉, 6개의 정수를 입력받을 때 첫 번째로 입력받는 정수는 ..
[시스템 프로그래밍] Bomb Lab Phase 1
[시스템 프로그래밍] Bomb Lab Phase 1
2022.12.21gdb bomb 명령어로 디버깅 모드에 진입한 후 disas phase_1 명령어로 phase_1 함수가 어셈블리어로 어떻게 작성된 지 확인해봤다. +11 : 함수를 호출한다. +16 : %eax 레지스터를 test한다. +18 : 결과가 같지 않으면 +25로 점프한다. +25 폭탄이 터진다. 음.. +11줄에서 문자열 두 개를 비교하고 %eax 레지스터에 결과를 넣게 되고, 이 결과에 따라서 폭탄이 터지거나 안 터지게 되는 것 같다. 좀 더 자세하게 살펴보자. test 명령어는 두 피연산자를 and 연산한다. jne 명령어는 ZF가 0일 경우 실행된다. 즉, +11줄에서의 결과가 1이면 폭탄이 터지지 않고, 0이면 폭탄이 터지게 됨을 알 수 있다. 그렇다면 당연히 +11줄에서 두 개의 문자열이 같은 경..
[시스템 프로그래밍] Data Lab
[시스템 프로그래밍] Data Lab
2022.12.201. bitNor int bitNor(int x, int y) { return (~x) & (~y); // use de morgan law to use able operands. } 드모르간 법칙을 사용해 사용 가능한 연산자만으로 bitNor를 구현하자. ~(x | y) => (~x) & (~y) 2. float_neg unsigned float_neg(unsigned uf) { int res = (0x80