기본 콘텐츠로 건너뛰기

메모리 조작 해킹

Pin 을 이용한 메모리 조작 분석


캐릭터의 공격력을 높이기 위해 '공격 데미지 값' 이라는 데이터를 조작하거나... 

캐릭터가 받는 데미지를 없애기 위해 '데미지 처리 로직' 이라는 코드를 조작하거나... 

게임 해킹툴이 게임 치팅을 위해 가장 많이 사용하는 방식 중 하나가 '메모리 조작' 입니다. 


'메모리 조작' 은 조작하는 방식에 따라 아래와 같이 크게 두 종류로 나눌 수 있습니다. 

- 게임 프로세스 외부의 다른 프로세스에서 WriteProcessMemory 로 조작. 

- 게임 프로세스 내부에 DLL 을 인젝션 시켜서 직접 값을 조작. 


여기서는 DLL 을 인젝션 시켜서 직접 값을 조작하는 방식을 대상으로 

Pin 을 활용해보도록 하겠습니다. 

테스트 편의를 위해 Sample.exe 와 SampleDll.dll 을 간단하게 구현했습니다. 

[ Sample.zip 다운로드 ] 


- Sample.exe : 게임 프로세스

- SampleDll.dll : 게임 프로세스에 인젝션되는 게임 해킹툴  

Sample.exe 가 실행될 때 SampleDll.dll 을 로드하고... 

DLL 이 로드된 후, 'F1' 키를 누르면~ SampleDll.dll 이 Sample.exe 의 메모리를 조작합니다.
  

Sample.exe 실행

'F1' 키를 눌렀을 때... 실행되는 SampleDll.dll 의 코드는 아래와 같습니다. 

게임 해킹툴이 메모리 조작 시 자주 사용하는 형태입니다. 

SampleDll.dll 의 메모리 조작 코드 (소스코드)
 참고로 hModule 은 Sample.exe 프로세스의 베이스 주소입니다.
  

SampleDll.dll 의 메모리 조작 코드 (디스어셈블 코드)
우리의 목표는 SampleDll.dll 에서 Sample.exe 의 메모리를 0x90 으로 조작하는 노란 박스의 코드를...

Pin 을 이용해서 찾아내는 겁니다. :)

핵심 API 는 "INS_MemoryOperandIsWritten" 입니다.

메모리 쓰기가 발생하는 경우 이 함수의 리턴값이 TRUE 가 됩니다.

"MOV", "AND", "SUB" 등의 명령으로 메모리 주소에 값이 써지는 경우는 물론...

"PUSH", "CALL" 등의 명령으로 스택 메모리에 값이 써지는 경우도 포함됩니다. @_@;;;

이 함수를 잘 이용하면 DLL 에서 게임 프로세스의 메모리를 조작하는 코드를 찾을 수 있습니다.

아래는 Pin Tool 예제 코드입니다


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// MemTrace.cpp
 
#include "pin.H"
 
#include <iostream>
#include <fstream>
#include <string>
 
using namespace std;
 
ofstream TraceLog;
 
UINT32 SampleBaseAddr = 0;
UINT32 SampleMappedSize = 0;
UINT32 DllBaseAddr = 0;
UINT32 DllMappedSize = 0;
 
//-------------------------------------------------------------------
INT32 Usage()
{
 
    return -1;
}
 
VOID Fini(INT32 code, VOID *v)
{
    TraceLog << endl << "#eof..." << endl;
 
    if (TraceLog.is_open()) TraceLog.close();
}
 
VOID ImageLoad(IMG img, VOID *v)
{
    // 메인 프로세스 : Sample.exe
    if (IMG_IsMainExecutable(img) == TRUE) {
        SampleBaseAddr = IMG_StartAddress(img);
        SampleMappedSize = IMG_SizeMapped(img);
        TraceLog << "* Process Name : " << IMG_Name(img) << endl;
        TraceLog << "  StartAddress : " << hexstr(SampleBaseAddr)
            << ", MappedSize : " << hexstr(SampleMappedSize) << endl;
    }
 
    // SampleDll.dll
    if (IMG_Name(img).find("SampleDll.dll") != string::npos) {
        DllBaseAddr = IMG_StartAddress(img);
        DllMappedSize = IMG_SizeMapped(img);
        TraceLog << "* Sample Dll : " << IMG_Name(img) << endl;
        TraceLog << "  StartAddress : " << hexstr(DllBaseAddr)
            << ", MappedSize : " << hexstr(DllMappedSize) << endl;
    }
}
 
VOID Log_MemWrite(VOID *ip, string &MemWrite, VOID *addr)
{
    UINT32 target = UINT32(addr);
 
    if ((target >= SampleBaseAddr) &&
        (target < (SampleBaseAddr + SampleMappedSize))) {
        TraceLog << MemWrite << endl;
    }
}
 
VOID Instruction(INS ins, VOID *v)
{
    ADDRINT Address = INS_Address(ins);
 
    if ((Address >= DllBaseAddr) &&
        (Address <= (DllBaseAddr + DllMappedSize))) {
 
        UINT32 memOperands = INS_MemoryOperandCount(ins);
 
        for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
            if (INS_MemoryOperandIsWritten(ins, memOp)) {
                string MemWrite = "- eip: " + hexstr(Address) +
                    "   [WriteMem]  " + INS_Disassemble(ins);
 
                INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)Log_MemWrite,
                    IARG_INST_PTR,
                    IARG_PTR, new string(MemWrite),
                    IARG_MEMORYOP_EA, memOp,
                    IARG_END);
            }
        }
    }
}
 
//-------------------------------------------------------------------
int main(int argc, char *argv[])
{
    PIN_InitSymbols();
 
    if (PIN_Init(argc, argv)) return Usage();
 
    TraceLog.open("MemTrace_Log.txt", ofstream::out);
    TraceLog << "### Memory Trace Log ###" << endl << endl;
 
    IMG_AddInstrumentFunction(ImageLoad, NULL);
    INS_AddInstrumentFunction(Instruction, NULL);
 
    PIN_AddFiniFunction(Fini, NULL);
 
    PIN_StartProgram();
 
    return 0;
}

빌드해서 생성된 MemTrace.dll 을 이용해보면~~

Sample.exe 실행 (with Pin - MemTrace.dll)

MemTrace.dll 에서 남긴 로그

SampleDll.dll 에서 메모리 조작을 하는 코드가 깔끔하게(?) 로그 파일에 기록되었습니다~ :)

댓글

이 블로그의 인기 게시물

dns2proxy 해킹툴

dns2proxy Offensive DNS server This tools offer a different features for post-explotation once you change the DNS server to a Victim. <Referer to help (-h) to new params options> Feature 1 Traditional DNS Spoof adding to the response the original IP address. Using spoof.cfg file: hostname ip.ip.ip.ip root@kali:~/dns2proxy# echo " www.s21sec.com  1.1.1.1" > spoof.cfg // launch in another terminal dns2proxy.py root@kali:~/dns2proxy# nslookup  www.s21sec.com  127.0.0.1 Server: 127.0.0.1 Address: 127.0.0.1#53 Name:  www.s21sec.com Address: 1.1.1.1 Name:  www.s21sec.com Address: 88.84.64.30 or you can use domains.cfg file to spoof all host of a same domain: root@kali:~/demoBH/dns2proxy# cat dominios.cfg .domain.com 192.168.1.1 root@kali:~/demoBH/dns2proxy# nslookup aaaa.domain.com 127.0.0.1 Server: 127.0.0.1 Address: 127.0.0.1#53 Name: aaaa.domain.com Address: 192.168.1.1 Hostnames at nospoof.cfg will no be spoofed. Featu...

인터넷 웹페이지 디버깅 피들러(fiddler) 사용법

인터넷 디벌깅 툴 피들러 입니다. 개발자들은 인터넷 디버깅 툴을 많이 사용하고 있는데요 인터넷 익스플러워 , 사파리 구글크롬등 디버깅 툴은 내장되어 있습니다.  하지만 원하는 값을 얻기 어렵거나 사용하기 어려운 점도 있습니다. 그래서 사용하기도 간편하고 필요한 기능도 많도 원하는 값을 쉽게 확인 할수 있는 디버깅 툴을 소개 해드리려 합니다. 알고 계시는 분도 많겠지만 피들러 (fiddler) 라는 툴입니다.  피들러에 대하 알아보도록 하겠습니다.  피들러(Fiddler) 설치 피들러 설치를 하기 위해 아래 사이트에 접속합니다.   http://www.telerik.com/fiddler 사이트에 접속하시면 FreeDownload 버튼이 보입니다. 클릭을 해서 피들러 설치를 진행합니다. ▶ 피들러는 닷넷 프레임워크를 사용하는데요 window 7 이상 제품군이시면  Fiddler for NET4을 선택하시고 미만이면 .net2를 선택 하세요  이제 Download Fiddler를 선택합니다.  ▶ 피들러 설치 진행화면이 나옵니다. I Agree를 클릭합니다.    ▶ 설치할 폴더를 선택 후 Install을 클릭합니다.    ▶ 설치가 완료되면 Close 를 클릭합니다.    ▶ 설치가 완료되면 브라우저를 새로 실행 하시고 도구> Fiddler를 선택합니다. 도구메뉴가 안보이시면 Alt를 누르시면 보입니다.    ▶ 우측에도 피들러 메뉴가 있습니다.  도구를 클릭 후 피들러를 클릭합니다.   ▶ 실행이 되면 아래와 같은 화면이 나오는데요...

보안 공부 링크

SSLsplit - SSL/TLS기반의 네트워크 포렌식 및 침투테스트(중간자공격) 도구 http://www.roe.ch/SSLsplit 가상화 서버운영 및 구축을 위한 Xenserver가 오픈소스로 공개 http://www.xenserver.org/ Python과 Fabric를 사용한 SSH 봇넷 C&C 구축 예제 http://raidersec.blogspot.kr/2013/07/building-ssh-botnet-c-using-python-and.html 파워쉘을 이용한 비밀번호 정보 획득 http://www.obscuresecurity.blogspot.kr/2013/07/get-gpppassword.html niktoHelper - Nmap의 Grepable형식을 Nikito와 연동하기 위한 파이썬 스크립트 http://milo2012.wordpress.com/2013/07/07/niktohelper-bridge-between-nmap-grepable-output-and-nikto/ 루비를 통한 심도있는 XSS 방어 방법 http://homakov.blogspot.com.es/2013/07/xss-defense-in-depth-with-rackrails-demo.html IT관련 E-Book 모음 http://www.cyberhades.com/2013/07/04/unos-libritos-tecnicos-para-el-veranito JJEncode 스크립트 분석 http://www.kahusecurity.com/2013/jjencode-script-leads-to-drive-by/ 웹브라우저 호환성 검증 및 분석결과 제공 http://www.modern.ie/ko-kr/ http://browsershots.org/ html 색상 선택 도구 https://kuler.adobe.com/create/color-wheel/ Windows 메모리 보호 메커니즘 http://resources.infosecinstitute.com/window...