꽃미남 프로그래머 김포프가 창립한 탑 프로그래머 양성 교육 기관 POCU 아카데미 오픈!
절찬리에 수강생 모집 중!
프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by 알 수 없는 사용자
제가 오늘 포스팅할 내용은 '해킹' 입니다!
옛날엔 해킹이 굉장히 먼나라 이야기처럼 들렸지만 요즘은 정말 해킹이 난무하는 시대가 온 것 같습니다.


게임도 역시 이 해킹의 대상에서 벗어날 수 없습니다.
특히나 P2P를 이용한 온라인 게임들은 해킹에 취약하며, 해킹에 의한 피해가 다른 게임에 비해 굉장히 큽니다. 저도 역시 몇년전 P2P를 이용한 게임의 유지보수를 하면서 해킹에 굉장히 많이 시달린 경험이 있습니다. 게임프로그래머가 게임만 만들면 되지 해킹에 대해서 알 필요가 있냐?! 라고 물으실 분들이 계실수도 있습니다. 하지만 저는 게임을 만들고 게임을 서비스하는 모든것들이 게임개발자로서 신경써야 하는 부분들이라고 생각합니다. 게임 해킹은 게임 서비스를 괴롭히는 요소중 하나이기 때문에 게임프로그래머도 기본적인것은 알아야 하지 않나 생각됩니다.

사설이 조금 길었는데요.. 
아무튼 오늘 설명할 내용은 '울트라에디트'와 '기본적인 센스'만으로 해킹이 가능한 게임에 대해서 입니다.

이게 무슨 김밥천국에서 아메리카노 파는 소리처럼 들릴지도 모르겠습니다만..
해킹 보안에 대해 아무런 신경을 쓰지 않고 만든 게임은 해커도 아닌 그냥 일반 사용자가 
울트라에디트만으로 해킹이 가능한 게임을 만들어버릴지도 모릅니다.

일단 무작정 울트라에디트로 해킹을 한번 해봅시다!


위 샘플을 받으면 실행파일이 하나 있을 것입니다.
이것을 실행시키면 F1을 누르면 "TestFucntion1" F2를 누르면 "TestFunction2" 메시지가 나오는 아주 간단한 프로그램입니다. 발로 만든 샘플이죠..



이 프로그램을 울트라에디트에서 열어봅시다.
저는 울트라에디트가 없어서 무료 헥사 에디터를 하나 받았습니다..



실행파일의 구조에 대해 공부하신적이 없다면 조금 머리가 아플 것입니다. 일단 눈앞에 보이는건 무시하고 Ctrl+F를 눌러서 검색을 해봅시다. TestFunction으로 검색을 해보도록 합시다.



이렇게 검색을 하면 아마 다음과 같은 코드가 검색이 될 것입니다.


TestFunction1@TestClass@@어쩌고 저쩌고 하는게 있고 그 아래에 TestFunction2@TestClass@@블라블라..
여기서 TestFunction1을 TestFunction2로 수정을 해보도록 하겠습니다.



그리고 저장을 한 후에 실행파일을 다시 실행시키고 F1을 누르면..
이번엔 TestFunction1이 아닌 TestFunction2 라는 메시지가 나올 것입니다.



정말 울트라에디트 하나만으로 정말 간단하게 프로그램 수정이 되버린것입니다.

전문적인 지식이 없어도 이렇게 헥사에디터로 프로그램파일을 열어서 "HP" 또는 "MP" 같은 키워드를 검색하여 간단하게 수정을 시도하는 유저들이 존재하며, 그렇게 수정을 해서 실제로 비정상적인 동작을 하는 게임도 존재합니다.

그렇다면 방금 헥사에디터를 이용해서 수정한 것은 어떤것이 어떻게 수정된 것일까요?

보통 저렇게 문자열을 검색 해서 나오는것은 코드내에서 문자열을 사용했기 때문이라고 생각할 수 있습니다. 하지만 방금 수정된 부분은 코드 내에서 직접적으로 문자열을 사용한 부분이 아닙니다.

이 실행파일의 코드를 잠시 살펴보면 Sample.exe가 있고 SampleDll.dll이 있습니다.
Sample.exe가 SampleDll.dll을 사용하고 있고, SampleDll에 TestClass와 TestFunction1,2가 들어있습니다.


 


이렇게 암시적로딩으로 dll을 사용하는 경우 '__declspec(dllexport)'와 '__declspec(dllimport)'같은 키워드를 사용하게 됩니다. export를 한 함수는 dll의 .edata 영역에 정보가 저장이 되고, import를 한 함수는 사용하는 exe또는 dll의 .idata 영역에 정보가 저장이 됩니다.


 
 그 중에서 위에서 수정한 부분은 Sample.exe의 .idata 영역에 있는 INT(Import Name Table)라는 녀석입니다. 정확하게는 INT의 요소가 가리키고 있는 IMAGE_IMPORT_BY_NAME 구조체의 내용을 수정한 것입니다.

그렇다면 도대체 INT라는 녀석이 뭐길래 이런 정보를 저장하고 있는걸까요?
암시적 로딩을 이용한 dll 로딩을 할 때의 과정을 보면 INT가 하는 역활을 알 수 있습니다.
자세하게 설명하기엔 너무 복잡하고 머리 아프니까 간략하게 설명하도록 하겠습니다.

로딩할 DLL의 이름 가져오기 -> DLL 로딩 -> 임포트 섹션에서 임포트할 함수들의 정보 가져오기 -> 익스포트 섹션에서 함수들의 주소 가져오기 -> 임포트 섹션의 IAT(Import Address Table)에 함수들의 주소 저장하기

이 과정이 끝나게 되면 DLL에 있는 함수는 IAT를 통해 호출할 수 있습니다. 
따라서 울트라에디트같은 헥사에디터를 통해 INT를 수정하고 프로그램을 실행시키게 되면, 
DLL이 로딩될 때 원래 호출해야 할 함수가 아닌 다른 함수의 주소를 가져와서 IAT에 저장하기 때문에 다른 함수가 호출되는 것입니다.

IMAGE_IMPORT_BY_NAME 구조체의 내용을 수정하는 것은 일반적으로 코드에 "" 키워드를 이용해 입력된 문자열 데이터보다 수정될 수 있다는것을 인식하기 어렵기 때문에 훨씬 위험합니다. 게다가 함수의 이름과 클래스의 이름이 노출되기 때문에 해커들에게 정보를 주는 역활을 하기도 합니다.

그런데 보통 게임을 만들때에는 역활별로 프로젝트 단위로 나눠서 작업을 많이 하게 됩니다.

그리고 이 모든 프로젝트들이 항상 정적라이브러리로만 쓰는건 아닐것입니다. 저희팀 같은 경우에는 상황에 따라서 정적라이브러리를 쓰기도 하고 동적라이브러리를 쓰기도 합니다.

아무튼 제가 말씀드리고자 하는것은 어쨌든 동적라이브러리로 만들고 익스포트된 내용들은 위에처럼 수정이 가능하거나 또는 정보를 제공하게 되므로 게임과 직접적인 연관이 있는 시스템, 컨텐츠 관련 내용들의 경우에는 정적라이브러리로 만드는것이 좋다는 것입니다.

그리고 어쩔 수 없이 동적라이브러리로 만들고 게임과 직접적인 연관이 있는 함수들을 노출해야 한다면, 실행파일의 변조체크 정도는 해주고 서비스를 해야 할 것입니다.

실행파일의 변조체크를 하는 가장 간단한 방법은 MD5같은 체크섬 알고리즘을 이용하여 실행파일과 dll의 내용로부터 체크섬값을 미리 얻어와서 서버에 저장해두고, 로그인시에 클라이언트가 실시간으로 체크섬값을 실행된 실행파일과 dll로부터 얻어온 후 서버로 보내고 서버에서 체크하는 방법입니다.

물론 해킹의 방법은 굉장히 다양하고 보안을 위해 이런저런 코드를 넣은것도 우회하는 방법이 굉장히 많습니다만.. 기본적인것들은 알아두자 하는 생각에 포스팅을 해 보았습니다.
반응형
,