4-1공부/리버스엔지니어링

[기말고사] 7. 제어문

KGW2027 2023. 6. 18. 03:11
728x90
반응형

Flag Register : 1비트로 쉽게 Boolean 값이다. 특정 상태 등을 알리기 위해 사용한다.
대표적으로...
CF(Carry Flag) : 연산 과정에서 발생되는 Carry, Borrow. 즉 덧셈 뺄셈에서 나오는 올림 및 내림.
PF(Parity Flag) : 결과 값의 1의 개수가 짝수면 1, 홀수면 0. 오류 검출에 사용됨
ZF(Zero Flag) : 연산 결과가 0이면 1, 아니면 0. 비교 연산에서 두 값이 같은지 확인
SF(Sign Flag) : 연산 결과의 부호를 나타냄. 음수면 1, 양수면 0.
OF(Overflow Flag) : 오버플로우가 발생했으면 1, 아니면 0

 이런 Flag Register들을 이용하는 주된 곳은 Jump Instruction이다.
Jump Instruction의 구조는 j[Operation] [Address] 이다.
이때, Address는 메모리 주소이며, 조건을 만족할 시 이동할 주소이다.
Operation은 검사할 조건의 약자를 사용한다.
 - O, NO (Overflow, Not Overflow) : 플래그 OF를 검사한다.
 - S, NS (Sign, Not Sign) : 플래그 SF를 검사한다.
 - E, Z (Equal, Zero) : 플래그 ZF를 검사한다. 
 이외에도 G, GE, L, LE (Greater/Less [Equals]) 등이 있다.
 이때, Jump Instruction은 플래그만 확인하며, 이 플래그를 셋하기 위해 점프 앞에 cmp, test 등의 플래그를 셋하기 위한 Instruction Code가 위치하게 된다는 것을 주의해야한다. 또한, 해당하는 Operation을 만족하는 경우에 점프를 한다.

 

 Flag를 이용하는게 Jump라면, Jump를 이용하는 건 무엇일까?
Jump를 주로 이용하는 프로그래밍 코드는 If, Switch와 같은 조건문for, while과 같은 반복문이다.

 먼저 조건문을 살펴보자.
If문의 경우, 매 조건을 검사하며 아니면 점프하는 방식을 가진다. 아래와 같은 방식이다.

cmp ~ ;				조건1 검사
jne line5;			조건1 불만족시 line5로 점프
(equals 일 때 실행)		조건1 만족할 때의 실행 코드
jmp line11;			if문 탈출
cmp ~ ;				조건2 검사
jne line9;			조건2 불만족시 line9로 점프
(equals 일 때 실행)		조건2 만족할 때의 실행 코드
jmp line11;			if문 탈출
(else 실행)			else코드
jmp line11;			if문 탈출
...

 

 Switch문의 경우 If문과 달리, 각 case에서 break;를 넣지 않으면 아래로 쭉 지속되던 것을 기억할 것이다.
그 이유를 여기서 알 수 있는데, If문의 비교-실행-비교-실행 구조가 아니라, 비교-비교..-실행-실행.. 의 구조이다.
특히, 간단한 1,2,3,.. 과 같은 연속된 case를 가진 Switch문의 경우, 테이블을 이용해 최적화된다. 그 구조는 아래와 같다.

코드가 case 1:, case 2:, case 3: default: 일 때,

mov rax, 입력값;
cmp rax, 3;
jg line16;		입력값이 3보다 크면 deafult로 이동
jmp line(6+rax);	입력값에 따라 line7~9 중에 이동
jmp line10;		입력값이 1이면, case 1 코드로 이동
jmp line12;		입력값이 2면, case 2 코드로 이동
jmp line14;		입력값이 3이면, case3 코드로 이동
(case1코드)
jmp line18;		break의 효과, default 다음으로 이동
(case2 코드)
jmp line18;		break의 효과, default 다음으로 이동
(case3 코드)
jmp line18;		break의 효과, default 다음으로 이동
(default 코드)
...

 이런 방식이 어려운 경우, 각각의 값에 대해 cmp를 걸 수도 있다.

코드가 위와 같을 때,

mov rax, 입력값;
cmp rax, 1;
je line11;		입력값이 1이면, 해당하는 line11로 이동
cmp rax, 1;
je line13;		입력값이 2면, 해당하는 line13으로 이동
cmp rax, 1;
je line15;		입력값이 3이면, 해당하는 line15로 이동
jmp line17;		case를 모두 지나왔으므로, default로 이동
(case1코드)
jmp line18;		break의 효과, default 다음으로 이동
(case2 코드)
jmp line18;		break의 효과, default 다음으로 이동
(case3 코드)
jmp line18;		break의 효과, default 다음으로 이동
(default 코드)
...

 

 

 다음으로 반복문에 대해 알아보자.
for문은 어셈블리에서 [변수 초기화-증감-비교-코드]으로 되어 있으며, 첫 반복에서는 증감 부분을 스킵한다.
그 구조는 아래와 같다.

for문을 for( state1(초기화) ; state2(비교) ; state3(증감) ) { state4(코드) } 라고 할 때,

...
state1;
jmp state2;
state3;
state2;
[jump]; // state2의 결과가 false면 for문 밖으로 점프
state4;
jmp state3;
...

while문은 for와 달리 구조도 단순하므로, [비교-코드]으로 되어있다.

while( cond ) { state }의 구조라고 할 때,

...
cond
[jump] // 만약 false라면 while 바깥으로 점프한다.
state
jmp cond
...

for문에 비해 간략한 모양새지만, 초기화 부분이 없는걸 감안하면 구조 자체에 큰 차이는 없다.

 

728x90
반응형

'4-1공부 > 리버스엔지니어링' 카테고리의 다른 글

[기말고사] 12. DLL & DLL Injection  (1) 2023.06.18
[기말고사] 10-11. PE & IAT  (1) 2023.06.18
[기말고사] 9. 호출 규약  (0) 2023.06.18
[중간고사] asm1  (0) 2023.04.16