본문 바로가기

Tool

메모리 패치(Memory Patch)

메모리 패치(Memory Patch) : 윈도우 운영체제가 사용중인 메모리 값들을 검색해서 원하는 값으로 변경을 하는 것

유명한 툴로는 티서치(Tsearch)와 치트엔진(Cheat Engine)이 있다.


티서치(Tsearch) :

1. 메모리 값 수정
2. 어셈코드를 추가해 넣는 코드인젝트(Code Inject)
3. 바이너리 수정(Hexedit)
4. 동적 메모리 할당(DMA) 방식의 메모리 값 수정

티서치를 이용하여 간단한 메모리 값 수정을 해보겠다.

그 외의 기능은 Help메뉴를 실행하면 제작자가 메뉴얼을 스샷과 예제 파일까지 포함시켜 쉽게 익힐 수 있다.



1. Open Process
2. 메모리의 특정 값 검색
3. 메모리 주소를 검색한 결과창
4. 메모리 주소의 값을 수정하는 곳

원하는 메모리 값으로 변경하는 방법은 OpenProcess(1)로 현재 실행되어 있는 프로그램을 선택하고, 돋보기(2)를 눌러서 메모리상의 특정 값을 검색하고, 메모리 주소 검색 결과 창에서 실제 메모리 주소를 선택하고, 해당 메모리 주소지의 Value를 변경한다.

예제로 윈도우 기본 프로그램인 카드놀이의 점수를 수정해 보겠다.

 

현재 점수는 45점이다. Tsearch를 실행하고 Open Process로 카드게임 프로세스인 Sol.exe를 선택한다.

돋보기 모양의 Init New Search를 클릭하면



검색 옵션은 Tpye에 1, 2, 4, 8, float, double이 있다.
1 byte : 255/2byte : 65535/4byte : 4294967295

Search에 Exact Value(정확한 값), Range(범위 값), Unknown Value(무조건 생성되는 값) 세가지이다.

45로 검색하면


10개의 메모리 주소가 검색이 되었다. 이 중에 어떤 것인지 찾기 위해 검색 내 검색을 해준다.

돋보기 ..(Next Search)을 선택하고, 카드 게임의 점수를 변경하고 그 값을 검색한다.

재검색창은 일반검색과 옵션이 다르다.

Exact Value : 정확한 값을 알고 있을 때 사용

Has Changed : Search된 value 중에 값이 변경된 것들만 재검색

Has not Changed : Search된 value 중에 값이 변경되지 않은 것들만 재검색

Has Increased : Search된 value 중에 값이 증가된 것들만 재검색

Has Decreased : Search된 value 중에 값이 감소된 것들만 재검색

Range : Search된 value의 범위를 지정하여, 지정된 value를 추출한다.

Increased by : Search된 value 중에서 특정 value 만큼 증가된 value를 찾아준다.

Decreased by : Search된 value 중에서 특정 value 만큼 감소된 value를 찾아준다.

Increased by more than% : Search된 value 중에서 %보다 많이 증가한 value를 찾아준다.

Decreased by more than% : Search된 value 중에서 %보다 많이 감소한 value를 찾아준다.

Increased by less than% : Search된 value중에서 %보다 적게 증가한 value를 찾아준다.

Decreased by less than% : Search된 value중에서 %보다 적게 감소한 value를 찾아준다.


점수가 32일 때 재검색하니 검색 결과가 하나가 되었고, 게임점수가 변함에 따라 refresh되면서 값도 자동으로 게임 점수와 같아진다.


더블클릭하면 우측에 목록이 뜨는데 value를 수정할 수 있다. 체크박스를 체크하면 설정한 값으로 해당 주소의 값을 고정시키는 기능을 한다.
(참고 : value에 -1을 입력하면 각 byte마다 가지는 최대값이다) 

우측창에 메모리 주소를 목록으로 만들어서 저장해놓고, 불러와서 사용할 수도 있다.

value를 천만으로 수정하고 확인해보면


점수가 천만 점이 된것을 볼수 있다.



치트엔진(Cheat Engine) :

델파이로 제작된 툴로써 줄여서 CE라고 부른다.


컴퓨터 모양의 아이콘을 클릭하면 Process List가 나타나고


프로세스를 숨겨놓은 경우에는 Windows List를 선택하여 윈도우 창을 기준으로 확인할 수 있다.
프로세스를 선택하면 해당 프로세스의 메모리들을 검색하여 원하는 값을 수정할 수 있다.


예제로 윈도우 기본 프로그램인 핀볼의 점수를 수정해 보겠다.
게임실행 후 Process List에서 PINBALL.exe를선택한다.

점수를 치트 엔진의 Value에 입력하고 New Scan을 클릭한다.


2개의 메모리 주소가 검색되었다.
티서치와는 다르게 재검색 옵션에 Same as First Scan 옵션이 있어서 처음 값과 비슷한 값을
검색해준다.


주소값을 더블클릭하면 하단의 리스트 창에 추가되며, 주소지 설명과 Value값 수정을 할 수 있다. 두 값의 Value를 바꿔가며 실험해보니 007F4872가 핀볼점수 값이다.

Frozen(고정 값)이 있는데 체크를 해주면 해당 값으로 고정된다.
Value에 1억점을 입력해보니까 1억점으로 점수가 변경되었다.


이제 어떤 부분이 점수를 더하는 부분인지를 찾아서 흐름을 직접 수정하겠다.

하단의 Value 목록 창의 우클릭 메뉴에서 Find out What writes to this address 를 선택한다.
(참고 : Find out What accresses this address를 선택하면 해당 주소지에 접근하는 좀 더 포괄적인 범위를 탐지한다)

그러면 점수가 변화되는 시점에서 어느 부분이 변경되는지 주소를 찾아준다.
비어있는 상태로 목록이 뜨고 점수에 변화를 주게 되면 다음과 같이 주소가 잡힌다.


점수가 변경되는 시점에서 add 명령이 있었으므로 점수를 더해가는 것임을 알 수 있다.
주소를 선택하고 Show disassembler 버튼을 눌러 분석하겠다.


치트엔진이 메모리 값의 변화를 감지해서 해당 주소지 부분부터 디버깅 할 수 있도록 준 것이다. 우측에 레지스터 값들을 확인할 수 있고, 상단 메뉴의 디버깅 메뉴를 이용해서 Breakpoint를 걸어서 단계별로 값들을 확인할 수 있다.

단축키는 올리디버거와 비슷하게 설정되어 있다.

이제 코드를 수정해서 점수를 고쳐보겠다. 수정할 주소를 선택하고 Tools->Assemble 선택한다.


Auto assemble 창에서 Template->Code Injection을 선택하면 선택했던 주소지를 기준으로 해서 코드를 생성해주고, 원하는 어셈코드를 넣을 수 있는 부분을 표시해준다.
코드를 주입할 주소를 적는 부분은 선택했던 주소지가 자동으로 들어가 있다. OK를 누르면 코드가 생성된다.

alloc(newmem,2048) //2kb should be enough    // 2kb만큼 코드를 삽입할 공간 확보
label(returnhere)
label(originalcode)
label(exit)

0101757C:         // 코드를 변경할 위치
jmp newmem   // newmem 레이블로 점프 5바이트
nop
nop
nop
nop
nop                 // originalcode와 사이즈를 맞추기 위해서 nop 5개, 5바이트로 한다.
returnhere:           그러면 원래 점수를 추가하는 주소에서는 newmem으로 점프를 해서
                          입력한 어셈코드가 실행된다.

newmem: //this is allocated memory, you have read,write,execute access             
//place your code here
코드 입력할 부분

originalcode:
add [eax],esi                     // eax의 값에 esi를 더한다.
mov edx,[eax]                   // edx에 eax의 값을 넣는다.
cmp edx,3b9aca00              // edx와 3b9aca00 비교

exit:
jmp returnhere

점수를 추가로 더하는 코드를 작성하겠다.

newmem :
add [eax], esi                  // eax의 값에 esi를 더한다. 
add [eax], 100000             // eax의 값에 100000을 더한다. 
mov edx, [eax]                // edx에 eax의 값을 넣는다.
cpm edx, 3b9aca00           // edx와 3b9aca00 비교

오리지널 코드의 순서를 그대로 유지한 채 add [eax], 100000 한 줄만 추가됐다.
Execute 버튼을 누르면 어느 메모리 영역에 자신이 Code injection 한 것이 들어가게 되는지 알려준다.

00A20000, 이 부분에 newmem에 추가한 코드들이 추가되어서 핀볼 점수가 추가되는 부분에서 입력한 코드들이 실행된다.
메모리 뷰어를 보면 기존 코드들이 다음과 같이 변경된 것을 볼 수 있다.


01017593 주소지로 가보면(Ctrl+G) 추가했던 코드들을 볼 수 있다.


입력했던 값들이 00A20000부터 정의가 되어있고, 00A20010부터는 원본 코드가 있다.
가장 중요한 부분은 jmp 01017586인데 처음에 점수가 추가되는 부분의 위치가 0101757C였고, 10바이트 다음인 01017586으로 다 시 되돌리는 것이다.

입력한 코드가 실행되고, 그 후에 원본 코드가 실행되고, 원래 있었던 위치로 다시 jmp하는 순서다.



이외에도 치트엔진에는 메모리치트, 디버거, DLL 인젝션, 코드인젝션 등이 있다.
또 치트엔진은 오픈 소스 이기 때문에 변형된 버전이 많이 존재한다.

'Tool' 카테고리의 다른 글

네트워크 모니터링 툴(Network-Monitoring Tool)  (2) 2009.11.26
바이너리 분석  (1) 2009.11.07
디컴파일러(Decompliers)  (0) 2009.11.07
아이다(IDA)에 MS 심볼 서버 연동하기  (9) 2009.11.06
아이다(IDA)에 Hex-Ray 연동  (9) 2009.11.06