- Quiz: x86 Assembly 22025년 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 다음글이 없습니다.이전글이 없습니다.댓글