본문 바로가기

REVERSING

[SWING] Reversing 01

과제 1

 

어셈블리 언어 명령어

 

 

1. 비트연산 : shift 연산

 

1) 부호가 없는 연산

- 왼쪽으로 이동 : shl

- 오른쪽으로 이동 : shr

 

2) 부호가 있는 연산 (MSB를 유지)

- 왼쪽으로 이동 : sal

- 오른쪽으로 이동 : sar

 

2. 제어

 

명령 설명 사용 예
cmp 두 개의 오퍼랜드 비교 (뺄셈 연산 후 플래그 설정) cmp ecx, 0
test 두 개의 오퍼랜드 비교 (AND 연산을 수행 후 플래그 설정) test eax, eax
call 해당되는 주소의 함수를 호출하여 수행 코드 위치를 옮김 call 0x12345678
int 오퍼랜드로 지정된 예외 처리 수행 (0xcd)
중단점으로 디버그용 소프트웨어 트랩 (0xcc)
오버플로우 예외 상황시 발생하는 트랩 (0xce)
하드웨어 디버그 트랩 (0x90)
int 3
int3
int0
int1
leave 함수에서 사용한 지역변수 스택을 비움 leave
ret 스택에서 저장된 주소로 복귀 ret
nop 아무 동작도 수행하지 않음 nop

 

3. 분기

 

명령어   설명
CALL Call 프로시저 호출
JMP Unconditional Jump 무조건 분기
RET Return from CALL CALL로 스택에 PUSH된 주소로 복귀
JE/JZ Jump on Equal / Zero 결과가 0이면 분기
JL/JNGE Jump on Less / not Greater or Equal 결과가 작으면 분기 (부호화된 수)
JB/JNAE Jump on Below / not Above or Equal 결과가 작으면 분기 (부호화 안 된 수)
JBE/JNA Jump on Below or Equal / not Above 결과가 작거나 같으면 분기 (부호화 안 된 수)
JP/JPE Jump on Parity / Parity Even 패리티 플레그가 1이면 분기
JO Jump on Overflow 오버플로가 발생하면 분기
JS Jump on Sign 부호 플레그가 1이면 분기
JNE/JNZ Jump on not Equal / not Zero 결과가 0이 아니면 분기
JNL/JGE Jump on not Less / Greater or Equal 결과가 크거나 같으면 분기 (부호화된 수)
JNLE/JG Jump on not Less or Equal / Greater 결과가 크면 분기 (부호화된 수)
JNB/JAE Jump on not Below / Above or Equal 결과가 크거나 같으면 분기 (부호화 안 된 수)
JNBE/JA Jump on not Below or Equal / Above 결과가 크면 분기 (부호화 안 된 수)
JNP/JPO Jump on not Parity / Parity odd 패리티 플레그가 0이면 분기
JNO Jump on not Overflow 오버플로우가 아닌 경우 분기
JNS Jump on not Sign 부호 플레그가 0이면 분기
LOOP Loop CX times CX를 1감소하면서 0이 될 때까지 지정된 라벨로 분기
LOOPZ/LOOPE Loop while Zero / Equal 제로 플레그가 1이고 CX≠0이면 지정된 라벨로 분기
LOOPNZ/LOOPNE Loop while not Zero / not Equal 제로 플레그가 0이고 CX≠0이면 지정된 라벨로 분기
JCXZ Jump on CX Zero CX가 0이면 분기
INT Interrupt 인터럽트 실행
INTO Interrupt on Overflow 오버플로우가 발생하면 인터럽트 실행
IRET Interrupt Return 인터럽트 복귀 (리턴)

 

4. 반복

 

           mov ecx, 반복 횟수
라벨 : 
           반복 내용
           loop 라벨

 

Hello World!
리버싱

 

1. 프로그램 옵션 설정 사항

 

빌드 -> 구성 관리자 -> Release

 

프로젝트 -> HelloWorld 속성 -> 링커 -> 고급 -> 임의 기준 주소 -> 아니요 (/DYNAMICBASE:NO)

 

 

컴파일 시 나타나는 화면

 

2. 빌드 -> 일괄 빌드

 

응용 프로그램을 다운받은 Immunity Debugger의 텅 빈 검은 4분할 화면으로 드래그해준다.

 

Immunity Debugger 다운로드 :

https://www.immunityinc.com/products/debugger/

 

 

 

제 1사분면 : Register window : 레지스터가 어떻게 변하는지 볼 수 있다.

제 2사분면 : Code window : 코드 주소 -> 어셈블리어 -> 주석 순으로 볼 수 있다.

제 3사분면 : Dump window : 코드 주소, 헥사 코드, 아스키 코드를 볼 수 있다.

제 4사분면 : Stack window : 함수를 실행하면 stack에서 실행 중인 함수의 변화를 관찰할 수 있고 함수가 종료되면 초기화된다.

 

Ctrl + F2 : 다시 처음부터 디버깅 시작 (Restart)

 

EP (Entry Point) : Windows 실행 파일(exe)의 코드 시작점

(실습에서는 아래와 같다.)

 

 

Code window

제 2사분면 - 코드 주소 -> 어셈블리어 -> 주석 순으로 볼 수 있다.

 

CALL HelloWor.wmain 이 메인함수이다.

main() 함수에는 MessageBoxW() API 를 호출하는 코드가 있다.

 

F7 (Step Into) 명령어로 CALL 의 함수 안으로 따라들어갈 수 있다.

 

 

CALL : 특정 주소의 함수를 호출하는 명령어

JMP : 특정 주소로 점프하는 명령어

RETN : 스택에 저장된 복귀 주소로 점프하는 명령어

 

F2 : BP (Break Point) 설정

F9 : BP 까지 실행

Space bar : 명령어 수정

 

Register window

제 1사분면 - 레지스터가 어떻게 변하는지 볼 수 있다.

Dump window

제 3사분면 - 코드 주소, 헥사 코드, 아스키 코드를 볼 수 있다.

 

Stack window

제 4사분면 - 함수를 실행하면 stack에서 실행 중인 함수의 변화를 관찰할 수 있고 함수가 종료되면 초기화된다.

 

 

 

 

< 원하는 코드를 빨리 찾아내는 세 가지 방법 >

 

1. F8 (Step Over) 으로 코드를 실행한다.

 

2. 문자열을 검색한다. 마우스 우클릭 -> Search for -> All referenced text strings

 

3. API 를 검색한다. 마우스 우클릭 -> Search for -> All intermodular calls

 

 

 

 < 문자열을 패치하는 두 가지 방법 >

 

 

1. 문자열 버퍼를 직접 수정한다.

 

1) 문자열 검색으로 "Hello World!" 가 있는 곳으로 이동

( "Hello World!" 부분 더블 클릭하면 이동함 )

 

문자열을 입력받는게 아니라 그냥 전부 뽑아주는 모양이다.

 

 

2) Dump 창에서 Ctrl + G 를 입력 후 주소를 입력

( 리틀 엔디언 표기법으로 주소를 거꾸로 입력해야함 28217500 -> 00752128 )

 

 

3) 아스키 코드 드래그한 뒤 Ctrl + E 를 입력 후 World -> Swing 변경하여 실행

 

 

 

2. 다른 메모리 영역에 새로운 문자열을 생성하여 전달한다.

 

1) 문자열 검색으로 "Hello World!" 가 있는 곳으로 이동

2) Dump 창에서 프로그램에서 사용되지 않는 NULL padding 영역으로 이동

3) 필요한 부분을 선택 후 Ctrl + E 으로 "Hello Security World!" 작성

 

 

4) 코드 창에서 주소 변경한 후 실행

( 코드 창에서 문자열 주소 부분 00751007 에 커서 놓고 Assemble 명령 [Space] bar 누르고

나오는 창에 PUSH 753020 입력 )

 

 

 

< 파일로 생성하기 >

 

 

1. Dump 창에서 변경된 문자열을 선택하여 마우스 우클릭 -> Copy to executable file

 

 

2. 나오는 창에서 마우스 우클릭 -> Save file

 

3. 파일 저장 후 실행시켜 결과 확인

( F9 으로도 메시지 창을 띄울 수 있다. )

 

 

 

어셈블리 명령어 출처)

[SYSTEM SECURITY]7.어셈블리(비트 연산, 논리연산, 형변환) - 컴공돌이 (tistory.com)

[Assembly] 어셈블리어 명령어 총정리 (tistory.com)

정보보안 아카이브 :: 어셈블리어 명령어 (assembler language) (tistory.com)

[어셈블리] 반복문 :: K4keye (tistory.com)

'REVERSING' 카테고리의 다른 글

[SWING] Reversing 06  (0) 2023.03.26
[SWING] Reversing 05  (0) 2022.08.26
[SWING] Reversing 04  (0) 2022.08.22
[SWING] Reversing 03  (0) 2022.08.13
[SWING] Reversing 02  (0) 2022.08.06