치트엔진 튜토리얼 실행
우선 치트엔진 튜토리얼을 하기 위해서, 치트엔진과 튜토리얼 프로그램을 켜보도록 하겠습니다.
치트엔진 튜토리얼 - STEP 5
우선, 아래와 같은 사진의 프로그램이 실행되었다면 Process Attach를 해보도록 하겠습니다.
여러가지 프로세스 중에서 아래 사진과 같이 Tutorial-x86_64 를 Open 해 줍니다.
STEP 5 설명
Step5는 아래 사진에서 볼 수 있듯이 <100>이라고 써져있는 값이 있습니다 .
이 값은 Change value 버튼을 눌렀을 때 임의의 숫자로 변경됩니다.
Step 5의 미션은 <Change Value>버튼을 눌렀을 때, 숫자가 변경이 안되게 어셈 코드를 수정하는 것 입니다.
(어셈 = 어셈블리어)
스텝5는 어셈블리어 코드를 수정하는 과정을 거칩니다.
이 어셈블리어를 간단하게 이해하기 위하여 아래 예제를 통해 설명을 하겠습니다.
설명에 앞서, 어셈블리 안에있는 레지스터라는 개념을 아셔야합니다.
쉽게 얘기해서 우리가 프로그래밍 언어에서 변수를 선언하면 그 선언한 변수의 자료형만큼의 저장공간이 생깁니다.
그런 저장공간이 어셈블리어에서는 변수선언이 따로 없기 때문에 대체되는 저장공간이 미리 마련되어있습니다.
그 저장공간을 범용 레지스터라고 부릅니다. 레지스터는 CPU내에 존재하여 매우 빠르다는 장점이 있습니다.
( 범용 레지스터의 예 : eax, ebx, ecx, edx, ebp, esp, edi, esi, eip 등등.. )
mov EAX, 2 // 2를 EAX에 넣는다.
mov EAX, [0x00412345] // 주소 00412345를 EAX에 넣는다.
이 예제를 해석해보면 숫자 2를 EAX라는 레지스터 공간에 넣겠다는 얘기입니다.
두번째 줄은 대괄호[] 안에 있는 주소를 EAX에 넣겠다는 뜻인데, 여기서 대괄호를 쓰게 되면
메모리의 주소를 넣겠다는 얘기가 됩니다. 메모리에는 여러 주소가 존재하고 그 주소를 EAX에 넣어준다는 얘긴거죠.
이 행위를 담당하는 아이는 mov입니다. mov를 우리는 명령어라고 부릅니다
이 어셈블리어를 C언어로 표현하게 되면 아래와 같습니다.
(틀린 코드일수도 있어요...! 정말 저의 이론상으로 표현한 코드입니다..)
int eax = 2; // 이해를 돕기 위해 변수이름을 레지스터 이름으로 선언하였습니다.
int* EAX = &eax; // 두번째 줄을 표현해보았습니다.
이제 MOV명령어와 함께 어셈블리에 숟가락정도를 얹어보았다고 말할 수 있습니다!
다시 튜토리얼로 돌아와서, 먼저 100이라는 값을 찾아주겠습니다
63개의 메모리가 검색이 되었습니다. 우리가 찾을 메모리는 하나이기때문에 값을 바꿔주고 다시한번 검색을 하겠습니다.
튜토리얼에 <Change value>버튼을 눌러 값을 바꿔줍니다.
578로 값이 변경되었기 때문에 578을 Value에 두고 Next Scan을 해줍시다
578 입력후 Next Scan을 하였더니 한개의 메모리가 검색되었습니다.
검색된 메모리를 테이블로 가져오겠습니다.
여기서 우리는 <Change value> 버튼을 클릭했을 때, 사용되는 어셈블리 코드를 찾아야 합니다.
어셈블리 코드는 치트엔진의 메모리 뷰(Memory view)에서 찾아볼 수 있는데,
메모리 뷰에서 찾기엔 매우 많은 어셈블리 코드들이 있다는 것을 알 수 있습니다 ㅠㅠ....
다행히도, 치트엔진에서는 특정 메모리 주소에 어떤 어셈블리 코드가 쓰기(Write) 되는지 볼 수 있는 기능이 존재합니다!!
메모리주소 우클릭 -> Find out what writes to this address 버튼 클릭
영어를 직역해서 말 그대로 이 메모리 주소에 어떤 쓰기(Write)가 있는지 알아내는겁니다.
버튼을 클릭하면 아래와 같은 사진의 창이 하나 뜰겁니다
여기서 튜토리얼의 <Change value> 버튼을 클릭해줍니다.
버튼을 클릭하면 위와같이 어떤 어셈블리 코드가 이 메모리 주소에 쓰기 된건지 볼 수 있습니다.
이 메모리를 클릭하고 <Show disassembler> 버튼을 클릭합니다
그럼 아래와같이 메모리 뷰어가 켜지고 해당 어셈블리 코드의 위치(주소)로 이동하게 됩니다.
위에서 볼 수 있듯이 mov [rax], edx 라는 어셈블리 코드가 사용되었습니다.
정확하게 이게 뭔진 몰라도 우리는 Change value를 눌러서 저 어셈블리 코드가 실행된것이기 때문에
[rax]는 value의 값의 주소를 나타내고, edx는 [rax]에 집어넣을 랜덤한 값을 표시한다는것을 알 수 있습니다!
자세하게 다시 설명하면, [rax]는 주소를 나타내고 그 주소에 edx라는 값을 집어넣는 행위가 되겠고,
이 행위는 우리가 change value를 눌렀을때 나타난 어셈블리 코드이기 때문에
바로 위에서 말했듯이, [rax]는 value의 값의 주소를 나타내고, edx는 [rax]에 집어넣을 랜덤한 값을 표시를 합니다.
우리는 이 주소를 nop이라는 명령어로 바꿔줄겁니다.
nop은 아무 코드가 없다는 뜻입니다. 특별한 의미가 아니라 아무 명령도 수행하지 않겠다는 명령어입니다.
위와같이 우클릭 -> Assemble를 클릭합니다.
값을 nop로 바꾸어주고 OK를 클릭합니다.
이상한 경고문이 표시되는데 YES를 클릭합니다.
이후 튜토리얼의 Change value 버튼을 눌러주면 값은 안 바뀌게 되므로 NEXT버튼이 활성화됩니다!!
'리버스 엔지니어링 > 치트엔진 튜토리얼' 카테고리의 다른 글
[7편] 치트엔진 튜토리얼 - Step 7 (Code Injection) (2) | 2023.01.01 |
---|---|
[6편] 치트엔진 튜토리얼 - Step 6 (포인터와 오프셋) (3) | 2022.12.06 |
[4편] 치트엔진 튜토리얼 - Step 4 (4) | 2022.12.05 |
[3편] 치트엔진 튜토리얼 - Step 3 (0) | 2022.12.04 |
[2편] 치트엔진 튜토리얼 - Step2 (0) | 2022.12.03 |
[1편] 치트엔진 설명 & 다운로드 (0) | 2022.12.03 |
댓글