23_어셈블리(JE&JZ)
- 분석 환경 : Windows7(32bit)
- 분석 도구 : OllyDbg, VS2008
1. if 구문
- 조건에 만족되면 코드가 실행되는 조건문이다.
- 만약, 조건에 만족하지 않으면 다른 코드를 실행하거나 프로그램을 종료한다.
- if 구문 형식은 다음과 같다.
if (조건 1)
{
// 조건1이 만족하면 실행하는 코드
// 만약, 조건1이 만족하지 않으면 'else if'로 넘어간다.
}
else if (조건 2)
{
// 조건2이 만족하면 실행하는 코드
// 만약, 조건2이 만족하지 않으면 'else'로 넘어간다.
}
else
{
// 조건2이 만족하지 않으면 실행하는 코드
// 만약, 여기 조건도 만족하지 않으면 종료한다.
}
2. JE/JZ
- 형식 : JZ [Code Address]
- 내용 : 비교 결과 값이 '0'이면(ZF=1 설정된 경우), 해당 주소로 점프한다.
- 예제 : JZ 401140
- 해석 : ZF=1 인 경우, 401140으로 점프한다.
- 조건 : Operand 1 == Operand 2
1) VS 2008을 이용하여 'je.exe' 파일을 제작한다.
- 파일 -> 새로 만들기 -> 프로젝트 -> 빈 프로젝트 -> 위치(04_테스트) & 이름(je) -> 확인
- '소스 파일' 우클릭 -> 추가 -> 새 항목 -> 'C++ 파일(.cpp)' 선택 -> 이름(je) -> 추가
- 파일 -> 모두 저장 -> 닫기
2) 'cl' 명령어를 이용한 최적화 컴파일 실시
2. ' je.exe' 파일을 'IDA Pro'를 이용하여 고급 정적 분석을 실시한다.
- CMP eax, [ebp-4]하여 eax - [ebp-4]한 값이 0인지 확인한 후, JZ 401032 에 의하여 비교 결과값이 0이면 해당 주소로 점프하고, 그렇지 않으면 다음 코드가 실행되는 것을 볼 수 있다.
3. 올리디버거를 이용한 'je.exe' 분석
- 메모리 주소, 레지스터 저장 값, 스택 내용, 메모리 덤프 내용, 비교 및 분기 내용 확인
1) Main함수 찾기(F8)
Main함수를 call하기 직전의 모습이다. Main함수의 주소는 401000임을 확인할 수 있다.
2) Main함수 진입(F7) – 함수 프롤로그, 함수본체, 함수 에필로그 확인
함수 프롤로그를 진행한 후, 함수 본체를 분석해보자.
조건이 두개인 if문이므로 아이다와 올리디버거로 분석한 위의 사진과 같이 두갈래로 나누어지는걸 볼 수 있다.
< 함수 프롤로그 >
00401000 /$ 55 PUSH EBP
00401001 |. 8BEC MOV EBP,ESP
_________________________________________________________________________________
< 함수 본체 >
00401003 |. 83EC 08 SUB ESP,8
- 다음과 같이 지역변수 num1,num2를 위한 공간 4byte * 2 만큼 ESP 를 위로 올려 공간을 마련해주는 작업을 한다.
00401006 |. C745 F8 06000>MOV DWORD PTR SS:[EBP-8],6
0040100D |. C745 FC 06000>MOV DWORD PTR SS:[EBP-4],6
00401014 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
- 다음과 같이 [EBP-8]의 값을 EAX에 대입한 후
00401017 |. 3B45 FC CMP EAX,DWORD PTR SS:[EBP-4]
- EAX와 [EBP-4] 를 비교하는 과정을 거친다.
EAX의 값과 [EBP-4]값 둘 다 6이라는 값을 가지고 있으므로, 비교결과값은 ‘0’이되고, 아래와 같이 ZF=1이 된다.
// 참고
-플래그:AF, CF, OF, PF, SF, ZF
대소 관계 CF SF ZF
op1>op2 0 0 0
op1=op2 0 0 1
op1<op2 1 1 0
0040101A |. 74 16 JE SHORT je.00401032
- 따라서 JE에 의해 비교결과값이 ‘0’이고, ZF = 1 이므로, 401032 로 분기하게 된다.
< 401032_분기 2 >
00401032 |> \6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401034 |. 68 78814000 PUSH je.00408178 ; |Title = "JE 명령어(점프O)"
00401039 |. 68 8C814000 PUSH je.0040818C ; |Text = "Operand1 == Operand2(ZF=1) -> Jump"
0040103E |. 6A 00 PUSH 0 ; |hOwner = NULL
00401040 |. FF15 E8804000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
- 위와 같이 분기2에 해당되는 코드들을 실행하고, 메시지박스가 실행되며, ‘Operand1 == Operand2(ZF=1) -> Jump’가 출력된 것을 확인할 수 있다.
이후, XOR을 통해 EAX를 0으로 초기화 시켜준 후, 함수에필로그가 수행되며 main함수는 종료된다.
00401046 |> \33C0 XOR EAX,EAX
_______________________________________________________________________________________
< 함수에필로그 >
00401048 |. 8BE5 MOV ESP,EBP
0040104A |. 5D POP EBP
____________________________________ main함수 소멸
0040104B \. C2 1000 RETN 10 ---> main함수 다음주소로 리턴
'정보보안 > 리버싱' 카테고리의 다른 글
reverse_assembly 기본명령어 JLE (0) | 2022.09.02 |
---|---|
reverse_assembly 기본명령어 JNE&JNZ (0) | 2022.09.02 |
reverse_assembly 기본명령어 IDIV (0) | 2022.09.02 |
reverse_assembly 기본명령어 MOV (0) | 2022.09.02 |
reverse_assembly 함수 (0) | 2022.09.02 |