본문 바로가기
리버싱

리버싱 4

by 윤라경 2024. 8. 14.

[2024.08.13]

 

[데이터 전송 명령어]

 

01. mov

 

02. add

 

 

메모리와 메모리끼리는 더하기가 불가하다

 

 

03. sub

 

 

 

오늘은 지난 시간에 이어 사칙연산을 연습해 보는 실습 시간을 가진다

먼저 mov를 이용해 eax 레지스터에 10을 저장시키고 sub로 eax에서 5를 뺀다 

 

 

10에서 5를 빼면 5라는 결과값이 나오기 때문에 eax 레지스터 값은 5가 된다

 

 

다시 5를 빼서 6이라는 숫자를 저장하게 되고

 

 

현재 상태에서 3을 두 번 빼서 eax 레지스터 값을 0으로 만든다 

 

 

이번에는 eax에 10, ecx에 5, edx에 3이라는 값을 넣고,

[402000]의 메모리 주소 헥사값을 5로 만든다  

 

 

이미지에서 볼 수 있는 것처럼, 마지막 명령어 실행 이후 32비트의 음수 값으로 16진수 B로 표현된다

따라서 eax의 레지스터 값이 B로 나타나는 것은 위의 연산 과정에서 0에서 5를 빼는 연산을 수행한 결과로

이 값은 10진수로 -5에 해당하며, 16진수로는 0xFFFFFFFB이다

시스템은 이를 B로 표시하기 때문에 정상적으로 저장된 결과값은 B가 된다 

 

 

메모리 값을 0으로 만든 후 다시 10을 더하여 10을 저장하게 된다

그 상태에서 eax 레지스터 값에서 빼면 0이 되며,

다시 mov로 eax에 10이라는 레지스터 값을 저장하게 된다

 

 

04. inc/dec

 

 


inc의 경우 1씩 증가시키는 데이터 전송 명령어다

mov로 eax에 10의 레지스터 값을 저장시키고

 

 

실행시키면 레지스터 값이 11이 된 것을 확인할 수 있다

 

 

dec로 1씩 감소시키는 것도 확인할 수 있다

 

 

inc와 dec의 충분한 연습 시간을 가졌다

 

 

05. xor

 

 

 

xor 명령어의 경우 두 값이 같을 경우 0이 되고, 다른 값일 경우 1이 되는 전송 명령어다 

 

 

06. xchg

 

 

 

현재 mov를 이용해 eax에 10, ecx에 5를 넣은 다음

xchg를 이용하여 eax와 ecx의 값을 뒤바꿀 수 있다

10이었던 eax는 5가 되고, 5였던 ecx의 경우에는 10으로 변경된다

 

 

이 코드는 스택에 값을 PUSH한 다음, 그 값을 POP 명령어로 레지스터에 꺼내오는 구조다

스택에 10, 20, 30, 40이 차례대로 쌓이고, 가장 마지막에 들어간 값이 첫 번째로 꺼내진다

이 코드에서는 스택을 사용하여 값을 저장하고 나중에 그 값을 차례대로 레지스터에 꺼내오고 있다

스택 구조의 특성상, 먼저 PUSH된 값은 나중에 POP되고, 나중에 PUSH된 값은 먼저 POP된다

따라서 각 레지스터에 저장된 값이 이 순서대로 되어 있는 걸 확인할 수 있다

 

 

이 경우도 위의 실습과 더불어 연습을 진행했다

 

 

07. mul/imul

 

> 1 Byte x 1 Byte = 2 Bytes

> 2 Byte x 2 Byte = 4 Bytes

> 4 Byte x 4 Byte = 8 Bytes

 

> 형식

> mul [레지스터1],[레지스터2]

 

1과 2를 곱해서 1에 저장된다

 

*여기에서는 상수가 올 수가 없으며, 숫자가 올 수 없다

 

 

 

eax 레지스터 값 2, ecx 레지스터 값 3

 

 

이때 결과는 eax 레지스터에 저장되고,

edx 레지스터는 보통 결과의 상위 32비트 부분을 저장한다

eax는 결과를 저장하는 레지스터로 mul 명령어는 eax와 ecx의 값을 곱하여 그 결과를 eax에 저장한다

ecx는 곱셈의 두 번째 피연산자로 사용되며, 곱셈 후에는 값이 바뀌지 않는다

그렇기 때문에 ecx는 여전히 3을 가지며, eax는 6이 되는 것이다

 

 

 

08. div

 

 

 

나누기가 되어 메모리에는 3이 저장되고, 나머지는 eax나 ecx에 저장된다

 


몫은 eax에 나머지는 edx에 저장된다는 것을 알고 있으면 좋다

 

*edx의 경우에는 초기화를 시키고 진행하는 것이 좋다

 

 

Dev C++ 프로그램을 실행하여 소스 파일을 하나 생성하고,

F9번을 누른 다음 F10을 눌러 결과값을 확인한다

그런 다음 소스 파일을 저장하고 ollydbg로 넘어간다

 

 

ollydbg에서 Dev C++에서 생성한 소스 파일을 열게 되면 해당 화면과 같이 코드를 확인할 수 있다

 

 

이 부분에 실행 코드를 나타내는 곳이다

 

 

쓸데없는 소스 코드를 제외하고 PUSH를 찾으면 된다

현재 이것을 프롤로그로 PUSH가 시작 부분이며, 초기화를 진행 후 실행하게 된다

프롤로그에서는 시작 코드가 분명 존재한다

 

 

PUSH를 시작하게 되면 EBP-10의 줄을 실행한다는 뜻이다

 

 

현재의 화면이 우리가 DEV C++에서 실행한 구문을 실행하는 코드인데,

이 코드의 앞뒤로 필요하지 않은 데이터들도 무수히 많이 나타난다

 

 

F8로 실행 후에 Ctrl+F2로 초기화를 진행하고, 다시 F9을 누르게 되면 3이라는 결과값을 출력하게 된다

 

 

 

강의 소감

오늘 강의는 사칙연산의 연장선을 배웠고, Dev C++ 프로그램을 이용해

프로그래밍 언어로 소스 파일을 생성 후 ollydbg로 코드를 읽는 실습을 진행했다

a와 b를 더하는 간단한 소스를 만들었을 뿐인데 코드를 읽었을 때

쓸데없는 코드가 나오며 그 중에서도 실행 코드가 따로 있는 부분을 찾아야 했다

그 부분을 찾아서 설명해 주시는 걸 들으니까 이해가 되어 궁금증이 해결되었다

강의 내용에서도 설명했지만 push가 첫시작을 알리는 코드로 중요한 역할처럼 느껴졌다

아직 코드를 완전히 읽을 수는 없어서 헷갈리는 부분이 많지만

강의 도중 궁금한 부분은 질문하면서 얼른 익숙해져야겠다

'리버싱' 카테고리의 다른 글

리버싱 6  (0) 2024.08.16
리버싱 5  (0) 2024.08.14
리버싱 3  (0) 2024.08.13
리버싱 2  (0) 2024.08.09
리버싱 1  (0) 2024.08.08