2. 목차
◦ 흔히 사용되는 패턴
◦ 조건문
◦ If, if-else, if-else if, if-else if-else
◦ Switch
◦ 심화된 조건문
◦ 대소 비교(<. <=, >, >=)
◦ AND, OR (&&, ||)
◦ 중첩된 조건문
◦ Return이 들어간 경우
◦ 무조건 실행/무시
◦ 반복문
◦ For
◦ While
◦ Do-while
◦ 심화된 반복문
◦ 무조건 실행/무시
◦ Break
◦ Continue
◦ Return이 들어간 경우
◦ 함수
◦ 기본적인 구조
◦ 함수 호출 규약
◦ cdecl
◦ Stdcall
◦ Fastcall
◦ Thiscall
◦ 문자열
◦ 문자열 선언/정의
◦ 배열
◦ 포인터
3. 흔히 사용되는 패턴
◦ 고급 언어 컴파일 시 흔히 나오는 어셈블리어 패턴을 공부
◦ 익숙해지면 디버거에서 디스어셈블한 어셈블리어 코드를 보고 고급 언어 형태를 추측할 수 있다.
◦ 컴파일러에 따라 디테일이 다를 수 있지만 대체로 비슷
◦ 법이라고 생각하지 말고 유연하게생각할 것
20. 흔히 사용되는 패턴 - 조건문 - switch - no default
조건문 탈출 Default가 없을 시/default가 중간에
있을 시 위와 같은 패턴이 나옴
21. 흔히 사용되는 패턴 - 조건문 - switch - no break
중간에 JMP가 없음
22. 흔히 사용되는 패턴 - 조건문 – switch – jump table
Switch에 case가 많고, 그
case가 연속된 숫자일 경우
점프 테이블을 이용하도록
컴파일 된다. (최적화의 일종)
조건문 탈출
23. 흔히 사용되는 패턴 - 조건문 – switch – jump table
Switch에 넣는 변수 a의
값이 switch case에서 가장
높은 값(5)보다 큰지 체크
크다면 switch 나옴
조건문 탈출
24. 흔히 사용되는 패턴 - 조건문 – switch – jump table
점프 테이블 참조
변수 a * 4를 오프셋으로 이용
(주소가 4바이트이기 때문)
25. 흔히 사용되는 패턴 - 조건문 – switch – jump table
404090 + a*4 주소에 저장된
값(점프할 주소) 이용
a == 0일 경우 0040165D로 점프한다.
26. 흔히 사용되는 패턴 - 조건문 – switch – jump table
404090 + a*4 주소에 저장된
값(점프할 주소) 이용
a == 1일 경우 0040166B로 점프한다.
27. 흔히 사용되는 패턴 - 조건문 – switch – jump table
주소 내용
404090 40165D
404094 40166B
404098 401679
40409C 401687
4040A0 401695
4040A4 4016A3
<점프 테이블>404090 + a*4 주소에 저장된
값(점프할 주소) 이용
a == 0
a == 1
a == 2
a == 3
a == 4
a == 5
28. 흔히 사용되는 패턴 - 조건문 - 심화 - 대소 비교
조건에 맞지 ‘않는’경우인지를 cmp
(a>=5를 체크하지 않고 a<=4인지를 체크했다. )
(a<=10인지를 체크하지 않고 a>10인지 체크했다.)
29. 흔히 사용되는 패턴 - 조건문 - 심화 - &&
앞 조건을 체크 – 조건에 맞지 않는 경우 조건문 탈출
30. 흔히 사용되는 패턴 - 조건문 - 심화 - &&
앞 조건이 충족되어 점프하지 않으면 뒤 조건을 체크
-조건에 맞지 않는 경우 조건문 탈출
31. 흔히 사용되는 패턴 - 조건문 - 심화 - ||
앞 조건이 충족되면 코드로 점프
충족되지 않으면 점프하지 않고 뒤 조건을 체크
뒤 조건이 충족되지 않으면 조건문 밖으로 점프
33. 흔히 사용되는 패턴 - 조건문 - 심화 - return
EAX에 retur값을 설정한 뒤 leave(ESP, EBP를 정리하는 instruction이다)
Return 하는 부분에서 스택 정리가 따로 일어나지 않고
return값을 설정한 뒤 스택 정리 코드로 이동함
34. 흔히 사용되는 패턴 - 조건문 - 심화 - 무조건 실행/무시
어셈블리 코드에는 아무 조건도 걸려있지 않다.
무조건 실행되지 않는 if(0) 코드는 아예 생성되지 않았다.
35. 흔히 사용되는 패턴 - 조건문 - 심화 - 무조건 실행/무시
어셈블리 코드에는 아무 조건도 걸려있지 않다.
36. 반복문
• F O R
• W H I L E
• D O - W H I L E
• 심 화 된 반 복 문
56. 함수
◦ 기본적인 구조
사용 준비
인자 전달
레지스터 값 백업
지역변수 공간 확보
코드 실행 함수 종료
레지스터 값 복구
스택 정리
함수 호출 규약
57. 함수 – 기본적인 구조
지역변수 스택 확보
ESP, EBP 백업/셋업
기능 수행
ESP, EBP 복구
(함수 지역변수 스택 해제)
함수 인자 스택 해제
함수 인자 PUSH
58. 함수 – 함수 호출 규약
◦ 함수 호출 규약에 따라 스택을 정리함
◦ 크게 호출자 정리, 피호출자 정리로 나눌 수 있음
◦ 대표적 종류
◦ 호출자 정리
◦ Cdecl
◦ 피호출자 정리
◦ Stdcall
◦ Fastcall
◦ 상황에 따라 다른 경우(컴파일러에 따름)
◦ Thiscall
◦ 고급 언어에서도 호출 규약을 명시하면 원하는 호출규약을 이용할 수 있음
◦ 명시한 호출 규약대로 컴파일 함
◦ 32bit에서는 위의 호출규약을 이용, 64bit는 다른 형식 이용. (추후 진행)
59. 함수 – 함수 호출 규약 – cdecl
◦ C declaration의 약자. C 프로그래밍 언어가 기원
◦ X86 아키텍처용의 수많은 C 컴파일러가 사용
◦ 일반적으로 x86 C컴파일러의 기본 호출 규약
◦ Parameter
◦ 역순으로 스택에 PUSH
◦ Func(1, 2, 3)일 시 3, 2, 1 순서로 PUSH
◦ 스택 프레임 반환 작업
◦ 호출자(Caller : 함수를 호출한 프로시저)가 함
60. 함수 – 함수 호출 규약 – cdecl
함수 인자를 PUSH하며 사용한
스택을 정리한다.
함수 인자를
역순으로 PUSH한다.
61. 함수 – 함수 호출 규약 – cdecl
지역변수 스택 정리는 하지만
함수 인자 스택은 정리하지 않는다.
62. ◦ Win32 API 표준 호출 규약
◦ Win API : Windows 고유의 API. 직접 OS와 상호작용 할 수 있음
◦ Parameter
◦ 역순으로 스택에 PUSH
◦ Func(1, 2, 3)일 시 3, 2, 1 순서로 PUSH
◦ 스택 프레임 반환 작업
◦ 피호출자(Callee : 호출 받은 함수)가 함
함수 – 함수 호출 규약 – stdcall
64. 복귀 주소로 돌아가며
인자를 위해 사용한 스택을
정리한다.
Ret instruction은 call instruction에서 스택에 저장한 주소를 이용하여 되돌아가는 instruction이다.
Ret instruction의 인자로 숫자 X를 넣어주면 되돌아감과 동시에 ESP에 X만큼 더한다.
함수 – 함수 호출 규약 – stdcall
65. ◦ 표준화된 규약은 아님
◦ 컴파일러 업체에 따라 다르게 처리
◦ 일반적으로 함수 인자 전달에 레지스터를 이용
◦ 메모리 접근 수를 줄임
◦ MS, GCC는 맨 앞 두 개의 인수를 ECX, EDX에 넣음
◦ Parameter
◦ 앞 두개를 제외하고 역순으로 스택에 PUSH
◦ Func(1, 2, 3, 4, 5)일 시 5, 4, 3 순서로 PUSH, 2는 EDX에, 1은 ECX에 넣음
◦ 스택 프레임 반환 작업
◦ 피호출자(Callee : 호출 받은 함수)가 함
함수 – 함수 호출 규약 – fastcall
66. 함수 인자가 하나일 시
ECX에 넣고 함수를 호출한다
함수 인자가 두 개일 시
ECX와 EDX에 넣고
함수를 호출한다
함수 인자가 다섯 개일 시
뒤에서부터 세 개 스택에 PUSH
앞의 두 개는 ECX와 EDX에 넣고 함수를 호출한다
함수 – 함수 호출 규약 – fastcall
67. 복귀 주소로 돌아가며
함수 인자를 위해 사용한 스택을 정리한다.
함수 인자를 위해 사용한 스택이 없으므로 숫자가 없음
함수 – 함수 호출 규약 – fastcall
68. 복귀 주소로 돌아가며
함수 인자를 위해 사용한 스택을 정리한다.
Int 3개를 스택으로 받았음 -> 0xC = 12 만큼 정리
함수 – 함수 호출 규약 – fastcall
69. ◦ C++에서 사용
◦ C++의 this 포인터를 넘기고 call을 한다는 의미
◦ GCC에서는 cdecl와 유사
◦ MS에서는 stdcall과 유사
◦ MS 기준, ECX에 this 포인터를 넣음
함수 – 함수 호출 규약 – thiscall
70. 함수 – 함수 호출 규약
◦ 왜 여러 형식이 있나?
◦ 각각의 장단점이 있음
◦ 호출자가 스택을 정리하는 경우
◦ 장점 : 가변 인자를 갖는 함수를 만들 수 있음 (ex. printf)
◦ 단점 : 함수를 호출하는 코드마다 스택 정리 코드를 생성해야 함
◦ 피호출자가 스택을 정리하는 경우
◦ 장점 : 반복적으로 스택 정리 코드를 만들지 않으므로 코드의 양을 줄임, 프로시저의 독립성 확보
◦ 단점 : 가변 인자를 가질 수 없음
◦ 이외에 특정 형식은 속도가 더 빠르다는 등의 특징이 있음
72. 문자열
◦ 문자열을 정의하는 방법은 배열을 이용하는 경우와 포인터를 이용하는 경우로 나누어진다.
◦ 각 경우에 어떤 패턴이 나오는지 알아보자
73. 문자열 – 선언/정의 – 배열
한 번에 4바이트 씩
문자열을 스택 영역으로 복사
(문자열은 메모리의
data영역에 저장되어 있다)
나머지는 eax를 0으로 만든 뒤
4바이트 씩 채워 넣음(NULL)
30바이트 크기의 배열이므로
남은 2바이트는 word로 채워 넣음
74. 문자열 – 선언/정의 – 배열
buf는 내용이 없으므로
스택만 확보해둔 채
아무 동작 하지 않음
스택 확보는 함수의
맨 앞부분에서 미리 했음