SONOTRI
  • Quiz: x86 Assembly 2
    2025년 03월 23일 04시 02분 56초에 업로드 된 글입니다.
    작성자: SONOTREE

    Q1.

    end로 점프하면 프로그램이 종료된다고 가정하자. 프로그램이 종료됐을 때, 0x400000부터 0x400019까지의 데이터를 대응되는 아스키 문자로 변환하면 어느 문자열이 나오는가?

    [Register]
    rcx = 0
    rdx = 0
    rsi = 0x400000
    =======================
    [Memory]
    0x400000 | 0x67 0x55 0x5c 0x53 0x5f 0x5d 0x55 0x10
    0x400008 | 0x44 0x5f 0x10 0x51 0x43 0x43 0x55 0x5d
    0x400010 | 0x52 0x5c 0x49 0x10 0x47 0x5f 0x42 0x5c
    0x400018 | 0x54 0x11 0x00 0x00 0x00 0x00 0x00 0x00
    =======================
    [code]
    1: mov dl, BYTE PTR[rsi+rcx]
    2: xor dl, 0x30
    3: mov BYTE PTR[rsi+rcx], dl
    4: inc rcx
    5: cmp rcx, 0x19
    6: jg end
    7: jmp 1

     

    내 풀이) - 정답(노가다)

    Code 1번째 라인 

    : [rsi+rcx] = [0x400000]이다. 따라서 0x400000주소의 1바이트 크기의 데이터를 dl에 대입하면 된다. 따라서 dl=0x67

     

    Code 2번째 라인 

    : dl=0x67과 0x30을 xor 연산한 값이 dl의 값이 된다. 따라서 dl=0x57

     

    Code 3번째 라인 

    : dl의 값을 0x400000주소로 대입한다. 이때 1바이트 크기만큼 대입한다. 따라서 0x400000주소의 값은 0x57(W)이 된다

     

    Code 4번째 라인

    : inc는 값을 1 증가시키는 명령어이다. 따라서 rcx=0x1이 된다

     

    Code 5번째 라인 

    : rcx-0x19 = 0x1-0x19이므로 음수의 값을 가진다. 따라서 SF=1이 된다

     

    Code 6번째 라인

    : rcx와 0x19 중 후자의 operand가 더 큰 상황이다. jg는 전자의 값이 더 클 end로 점프하므로, 현재는 점프하지 않는다. 

     

    Code 7번째 라인

    : Code 6을 만족하지 않아 Code 7까지 왔다. 이제 다시 Code 1로 돌아간다

     

     

     

     

    Code 1번째 라인

    : [rsi+rcx]=[0x400000+0x1] = [0x400001]. 따라서 0x400001 주소의 1바이트 크기의 데이터를 dl에 대입하면 된다. 따라서 dl=0x55

     

    Code 2번째 라인

    : dl=0x55와 0x30을 xor 연산. 따라서 dl=0x65

     

    Code 3번째 라인

    : dl=0x65를 0x400001 주소에 1바이트 크기만큼 대입한다. 따라서 0x400001주소의 값은 0x65(e)가 된다

    ...이게 반복되는 것 같다.

     

     

     

     

    => 따라서 

    (0x67 xor 0x30) + (0x55 xor 0x30) + (0x5c xor 0x30)...을 하면 된다. 따라서 57(W) + 65(e) + 6c(l) + 63(c)...을 하면 최종적으로 Welcome to assembly world!라는 문자열이 나온다.


    Python을 이용한 자동화 코드

    내 풀이) - 오류 발생

    memory_list = [0x67, 0x55, 0x5c, 0x53, 0x5f, 0x5d, 0x55, 0x10,
    0x44, 0x5f, 0x10, 0x51, 0x43, 0x43, 0x55, 0x5d,
    0x52, 0x5c, 0x49, 0x10, 0x47, 0x5f, 0x42, 0x5c,
    0x54, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    ]
    answer_list=[]
    answer=0
    for i in memory_list(32):
    answer[i] = memory_list[i]^0x30
    answer_list[i]=answer[i]
    for j in answer_list(32):
    print(answer_list[j])

    -> for i 구문에서 "'list' object is not callable"라는 오류가 발생한다.

    -> 여러모로 잘못된 부분이 많은 코드이다. 

     

     

    정답 코드)

    memory = [0x67, 0x55, 0x5c, 0x53, 0x5f, 0x5d, 0x55, 0x10,
    0x44, 0x5f, 0x10, 0x51, 0x43, 0x43, 0x55, 0x5d,
    0x52, 0x5c, 0x49, 0x10, 0x47, 0x5f, 0x42, 0x5c,
    0x54, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    ]
    for i in range(32):
    memory[i] = memory[i]^0x30
    for j in memory:
    print(chr(j), end="")
    //Welcome to assembly world!000000
    • end: 그 다음 출력값을 이어서 출력한다
    • ^(xor): Python에서 xor 연산자는 ^이다
    • chr(): 아스키코드를 문자열로 변환하는 함수이다. 하나의 정수를 인자로 받고, 해당 정수에 해당하는 유니코드 문자를 반환한다.

    'Dreamhack > Reverse Engineering' 카테고리의 다른 글

    Exercise: Helloworld  (0) 2025.03.24
    Quiz: x86 Assembly 1  (0) 2025.03.23
    x86 Assembly: Essential Part(2) [★]  (0) 2025.03.23
    x86 Assembly: Essential Part(1)  (0) 2025.03.22
    Background: Windows Memory Layout  (0) 2025.03.18
    댓글