안 쓰던 블로그
어셈블리 코드 C코드로 변환하기 본문
main코드부터 본다
push rbp
mov rbp, rsp
sub rsp, 16
먼저 main 시작 전의 rbp레지스터 주소를 push로 스택에 넣는다. 이제부터 main함수에서 rbp가 베이스 포인터 역할을 하게 될 것이기 때문에 원래 가지고 있던 이전 rbp주소를 미리 저장해 두는 용도이다
mov로 현재 스택 포인터 rsp값을 rbp에 복사한다. rbp는 main의 스택 베이스 포인터로, main의 스택 프레임을 생성하는 부분이다
sub로 rsp에서 16을 뺀다. 스택에서 16바이트를 확보한다
mov DWORD PTR [rbp-4], 1
mov eax, DWORD PTR [rbp-4]
mov edi, eax
mov eax, 0
call sequare
스택의 rbp-4 에 1를 넣는다. 4바이트 변수를 1로 할당한다
다음 mov로 eax에 위에 rbp-4의 값인 1을 넣는다
그리고 eax의 값 1을 edi에 다시 넣고 eax는 0으로 초기화 한다
edi는 임시 저장소로 함수에 해당 값이 매개변수로 넘어갈 것이다
sequare 함수를 호출한다
push rbp
mov rbp, rsp
rbp에 저장되어 있는 main의 베이스 포인터 값을 스택에 넣는다
그리고 현재 함수의 포인터 값을 rbp에 넣으면서 sequare함수의 스택 프레임을 생성한다
이제 이 rbp로 함수 파라미터나 로컬 변수에 접근한다
mov DWORD PTR [rbp-4], edi
mov eax, DWORD PTR [rbp-4]
imul eax, eax
pop rbp
ret
아까 main에서 보낸 edi값을 여기서 가져온다. rbp-4에 edi값 1을 넣는다
rbp-4에 있는 1값을 eax에 넣는다
imul은 부호가 있는 곱셈 명령어다. eax에 있는 값1을 제곱하고 다시 eax에 저장한다
rbp를 pop하여 main()함수로 복귀한다
mov DWORD PTR [rbp-8], eax
mov eax, 0
leave
ret
스택의 rbp-8에 eax값을 넣는다. eax에는 아까 제곱 계산한 1이 있었다. 즉 함수에서 반환한 값을 저장한다
근데 처음에 rbp-4주소값을 썼으므로 다음 변수 자리인 rbp-8자리에다가 저장하는 모습이다
eax에 정상 exit코드라는 의미의 0을 넣는다
leave는 현재까지 쓴 메모리 스택을 비우는 명령어다. main()함수를 호출했던 메모리의 베이스 주소를 ebp에 다시 가져온다
ret명령어로 main()함수를 종료한다
c언어로 변환한 코드
#include <stdio.h>
int square(int a) {
return a * a;
}
int main() {
int a = 1;
a = square(a);
return 0;
}
'CTF > Reversing' 카테고리의 다른 글
dreamhack rev-basic-3 풀이 (0) | 2020.09.17 |
---|---|
dreamhack rev-basic-0 풀이 (0) | 2020.09.14 |
Register (0) | 2020.09.01 |
리버싱-전역/지역 변수 초기화 (0) | 2020.09.01 |
[리버싱] 메모리 구조, 함수 호출 과정, Stack Frame (0) | 2020.08.30 |