Excuse the ads! We need some help to keep our site up.

List

Game Security Guide - Memory cheat

  • 많은 게임 개발 업체들은 게임에서 발생하는 부정 행위로 인한 피해를 최소화하기 보안 제품들을 많이 적용하고 있습니다.
    • 일부 사람들은 보안 제품을 적용하면 모든 부정 행위를 차단해 줄 것이라고 생각합니다.
    • 하지만 보안 제품들 대부분은 부정 행위를 완벽하게 차단하는 것이 아니라 부정행위를 어렵게 만드는 것 입니다.
    • 이러한 보안 제품들은 게임 코드에 보안 코딩이 잘 되어 있어야 더 큰 효과를 볼 수 있습니다.
  • 해당 페이지에서는 Memory Cheat tool에 의해 발생하는 게임 부정 행위를 방지하지 위한 가이드입니다.
  • 아래 가이드 방안을 적용하여도 부정 행위는 발생 할 수 있습니다.

Anti debugging

ptrace()

  • 다음과 같은 코드를 이용해 다른 프로세스(디버거,Memory Cheat tool)가 해당 프로세스틑 연결하는 것은 확인 할 수 있습니다.

    • 해당 코드는 아주 기본적이고 일반적인 Anti debugging 코드 입니다.

    • 해당 프로세스가 디버깅 되고 있지 않다면 ptrace()는 0을 반환 하며, 디버깅 되고 있을 경우 0이 아닌 다른 값이 반환됩니다..

    • 즉, 아래 코드를 사용해 디버거 또는 메모리 치트 툴이 게임 프로세스에 연결되어 있는지 확인 할 수 있습니다.

ptrace(PTRACE_TRACEME,0,0,0)
int result = ptrace(PTRACE_TRACEME,0,0,0);

if(result != 0){
  exit(0);
}

Memory Cheat tool

  • 보안 코드를 설명하기 전에 Memory Cheat tool의 동작 방식에 대한 이해가 필요합니다.
  • Memory Cheat tool은 다음과 같은 방식으로 원하는 값을 찾습니다.
    • 첫번째 검색 - Memory Cheat tool은 Game Memory에서 값을 검색 합니다.
      • 검색 값과 같은 값이 저장되어 있는 영역의 주소들은 Memory Cheat tool에서 보관(New list)합니다.
    • 두번째 검색 - Memory Cheat tool은 Game Memory에서 값을 검색 하지 않습니다.
      • Memory Cheat tool은 앞에서 보관한 주소 목록만을 이용하여 해당 영역에 저장된(갱신된) 값이 검색 값과 같은지 확인합니다.
      • 검색 값과 같은 값이 있다면 해당 영역의 주소 값을 보관합니다.
      • 다음 검색에서도 이러한 과정이 진행됩니다.
    • 세번째 검색 - 여러번의 검색을 통해 원하는 값이 저장된 영역을 확인 할 수 있습니다.
Memory Cheat tool

Game Code

  • 다음은 게임에서 사용되는 값을 메모리 치팅으로 부터 보호 할 수 있는 코딩을 설명하겠습니다.

Division

  • 다음과 같이 값을 분할하여 값을 보호 할 수 있습니다.
    • 게임에서는 화면에 출력되는 값은 메모리에 분할되어 저장되기 때문에 치트 툴에 값이 검색 되지 않습니다.
    • Ex)
      • 화면에 출력되는 값 : 100(value1 + value2)
      • 메모리에 저장된 값 : value1(32), value2(68)
DivisionValue
static int value1= 0,value2 = 0, value3 = 0,total = 0;

int Util::DivisionValue(int value){
    value3 = value1;
    value1 = getRandomNumber(0 ,value1 + value2 + value);
 
    value2 = value3 + value2 + value - value1; 
    return value1 + value2;
}

int Util::getRandomNumber(int from, int to){
    return (int)from + arc4random() % (to-from+1);
}
  • 아래와 같이 메모리에 Score 값이 분할되어 저장됩니다.
Example

XOR

  • 다음과 같이 값을 XOR 연산을 하여 값을 보호 할 수 있습니다.
    • 게임에서는 화면에 출력되는 값은 XOR 연산되어 메모리에 저장되기 때문에 치트 툴에 값이 검색 되지 않습니다.
    • Ex)
      • 화면에 출력되는 값 : 100(value1 + value2)
      • 메모리에 저장된 값 : value1(32), value2(68)
XOREncrypt
int Util::XOREncrypt(int value){
    srand((unsigned int)time(NULL));
    salt = rand()%10;
    encode = value^salt;

    return encode;
}
int Util::XORDecrypt(int encode){
    return encode^salt;
}
  • 아래와 같이 메모리에 Score 값이 XOR 연산되어 저장됩니다.

Example

Memory realloc Sample

  • 다음과 같이 값을 매번 새로운 영역에 값을 저장해 값을 보호 할 수 있습니다.
    • 게임에서는 화면에 출력되는 값이 갱신될 때 마다 새로운 메모리 영역에 저장되기 때문에 치트 툴에 값이 검색 되지 않습니다.
    • Ex)
      • 첫번째 값 : 100, 0x601000
      • 두번째 값 : 200, 0x601480
      • 세번째 값 : 300, 0x601780
      • ...
Memory realloc Sample
Int *score = new int;
...
Delete score;
  • 아래와 같이 메모리에 Score 값이 저장될 때 마다 새로운 메모리 영역에 저장됩니다.
Example

Related site

  • N/a