지난번에 올린 Pin 을 이용한 메모리 조작 분석에 이어서 ~
이번에도 '게임 해킹툴 분석' 측면으로 접근해보려 합니다 :)
물론 응용하기에 따라 다른 쪽으로 이용도 가능하겠지만요.. ^^;;;
Pin 을 이용한 비정상 함수 호출 분석
게임 내부의 함수들은 게임이 진행되는 중에 게임에서 호출하는 것이 일반적입니다.
FPS 게임에서 캐릭터가 죽는 경우를 예를 들어봅시다.
게임 내부적으로 무기 데미지 / 캐릭터 체력 / 착탄 부위 등 이것저것 계산을 해서
조건을 만족하는 경우에 게임이 Kill 함수를 호출하는 것이 정상적인 흐름입니다.
만약 이 Kill 함수가 게임이 아닌 다른 곳에서 호출되면 어떻게 될까요...? @_@
게임 진행과 상관없이 캐릭터가 죽겠죠... -_-;;;
이런 식으로 게임 해킹툴이 게임 내부 함수를 호출하는 것을 '비정상 함수 호출' 이라고 합니다.
Pin 을 이용해서 인젝션 된 DLL 이 대상 프로세스의 함수를 호출하는 것을 분석해봅시다.
테스트 샘플 구성은 '메모리 조작 분석' 과 동일합니다.
[ Sample.zip 다운로드 ]
- Sample.exe : 게임 프로세스
- SampleDll.dll : 게임 프로세스에 인젝션되는 게임 해킹툴
Sample.exe 가 실행될 때 SampleDll.dll 을 로드하고
DLL 이 로드된 후, 'F2' 키를 누르면~ SampleDll.dll 이 Sample.exe 의 함수를 호출합니다.
Sample.exe 실행 |
'F2' 키를 눌렀을 때... 실행되는 SampleDll.dll 의 코드는 아래와 같습니다.
SampleDll.dll 의 비정상 함수 호출 코드 (소스코드) |
이 코드를 디버거로 보면 아래와 같은 디스어셈블 코드가 나옵니다.
SampleDll.dll 의 비정상 함수 호출 코드 (디스어셈블 코드) |
핵심 API 는 "INS_IsCall" 입니다.
CALL 명령이 나오면 이 API 의 리턴값이 TRUE 가 됩니다.
아래는 Pin tool 예제 코드입니다.
// CallTrace.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_Call(string &CallFunc, ADDRINT target) { if ((target >= SampleBaseAddr) && (target < (SampleBaseAddr + SampleMappedSize))) { TraceLog << CallFunc + " [ Target : " + hexstr(target) + " ]" << endl; } } VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { INS tail = BBL_InsTail(bbl); ADDRINT Address = INS_Address(tail); if ((Address >= DllBaseAddr) && (Address <= (DllBaseAddr + DllMappedSize))) { if (INS_IsCall(tail)) { string CallFunc = "- eip: " + hexstr(Address) + " [CallFunc] " + INS_Disassemble(tail); INS_InsertPredicatedCall(tail, IPOINT_BEFORE, AFUNPTR(Log_Call), IARG_PTR, new string(CallFunc), IARG_BRANCH_TARGET_ADDR, IARG_END); } } } } //------------------------------------------------------------------- int main(int argc, char *argv[]) { PIN_InitSymbols(); if (PIN_Init(argc, argv)) return Usage(); TraceLog.open("CallTrace_Log.txt", ofstream::out); TraceLog << "### Call Trace Log ###" << endl << endl; IMG_AddInstrumentFunction(ImageLoad, NULL); TRACE_AddInstrumentFunction(Trace, NULL); PIN_AddFiniFunction(Fini, NULL); PIN_StartProgram(); return 0; }
빌드해서 생성된 CallTrace.dll 을 이용해보면~
Sample.exe 실행 (with Pin - CallTrace.dll) |
CallTrace.dll 에서 남긴 로그 |
이번에도 역시 SampleDll.dll 에서 비정상 함수 호출을 하는 코드가 로그 파일에 제대로 기록되었네요~ :)
마치며
Pin 을 이용해서 '메모리 조작 분석' 과 '비정상 함수 호출 분석' 을 분석하는 방법을 살펴봤는데요.기능별로 설명(?)하기 위해 MemTrace / CallTrace 로 나눴지만...
잘 조립하면 하나의 DLL 로 합칠 수도 있습니다 :)
실제 게임에 적용하기 위해서는 이것저것 고려해야 될 사항들과 장벽들이 많지만... @_@;;
Pin 을 공부하시는 분들께 조금이나마 도움이 되었으면 좋겠네요~~ :)
안녕하세요=) 잘보고 예제하면서 pin어떤식으로 쓰면 될지 감잡을 수 있었네요. 저도 프로젝트 속성 설정하는데 잘안되서,(윈프 경험이 없어서 그런지..뭐가 문제인지도 모르겠고) 고민즘 하다가 %PIN_ROOT%\source\tools\Mypintool 에 있는 프로젝트를 불러와서 그곳에서 작업하니까 문제 없지 빌드 잘되네요 ㅎㅎ 후에 보시고 댓글 읽는 분에게 도움되면 좋을거 같습니다. =)
답글삭제앗.. ㅋㅋ
삭제http://www.xeronichs.com/2017/02/vs2015-with-intel-pin-32.html
여기다가 기록한다는걸..ㅎㅎ 여기까지 오시는 분은 보고 도움 되시길!
흠.. Mypintool 그 쪽에 있는 프로젝트 속성을 참고해서...
삭제하나하나 그대로 설정하는 방법으로 정리를 해둔건데 안된다는 분들이 꽤 계시더라구요;;
제가 정리한 내용 중에 뭔가가 누락되었거나...
그걸 따라하는 과정에서 뭔가를 빠뜨린게 아닌가 싶네요;; ^^;;
어쨌든 감사합니다~ (_ _)