[ 리버싱 / 프로그래밍 / 음악 / 게임 / 그 외... ]



목요일, 8월 10, 2017



업무 특성상(?) Hex 값을 다루는 경우가 많은데...

이번에 파이썬용 Hex Dump 함수를 간단하게 만들어 봤습니다.

앞으로 파이썬으로 작업하다가 Hex 값이 필요할 땐 이 함수를 우려먹는 걸로... :)


def print_hex_dump(buffer, start_offset=0):
    print('-' * 79)

    offset = 0
    while offset < len(buffer):
        # Offset
        print(' %08X : ' % (offset + start_offset), end='')

        if ((len(buffer) - offset) < 0x10) is True:
            data = buffer[offset:]
        else:
            data = buffer[offset:offset + 0x10]

        # Hex Dump
        for hex_dump in data:
            print("%02X" % hex_dump, end=' ')

        if ((len(buffer) - offset) < 0x10) is True:
            print(' ' * (3 * (0x10 - len(data))), end='')

        print('  ', end='')

        # Ascii
        for ascii_dump in data:
            if ((ascii_dump >= 0x20) is True) and ((ascii_dump <= 0x7E) is True):
                print(chr(ascii_dump), end='')
            else:
                print('.', end='')

        offset = offset + len(data)
        print('')

    print('-' * 79)


사용법은 간단합니다~ :)

print_hex_dump(mft_buf, mft_offset)


요런 식으로 내용을 보고 싶은 버퍼와 시작 오프셋 값을 지정해주면~



요렇게 딱~~

시작 오프셋을 지정하지 않으면 기본적으로 '0' 으로 됩니다.

별거아닌데 쓸데없이 만족스럽네요.. :)




목요일, 7월 27, 2017



얼마 전 종영된 '프로듀스 101 시즌2' 에 멤버 4명이 나와서 화제가 된 그룹 ~

'뉴이스트' 의 '여보세요' 를 살포시 포스팅해봅니다.

프로듀스 101 방송이 끝난 후 뉴이스트 노래들이 역주행을 했는데

그 중 가장 순위가 높은 곡(멜론 기준)이기도 하고...

개인적으로 뉴이스트 노래 중 가장 좋아하는 곡이기도 하구요 ~ :)


   


뉴이스트(NU'EST) - 여보세요

여보세요
밥은 먹었니
어디서 뭐 하는지
걱정되니까
Tell me baby where you at
여보세요
Call me baby I be there
Wherever you are I be there
여보세요
Pick up the phone girl
Cuz I gotta be there

차가 막히는지 늦을 건가 봐 (급한 맘에)
배터리는 또 깜빡 하셨나 봐 (나는 또)
왠지 비가 올 것 같애 고민을 하다가 (너를 좀 더)
빨리 보고 싶은 맘에 일찍 데릴러 나가

깜짝 놀라겠지 날 보면 (좋아하겠지)
길이 엇갈리지 않게 더 (달려야겠지)
저 멀리 니 모습 보이는데 왜 난
전활 걸어 한다는 말이 결국엔

여보세요 밥은 먹었니
어디서 뭘 하는지 걱정되니까
여보세요 왜 아무 말 못하니
여보세요 여보세요

널 데릴러 왔어 비가 올까 봐
혼자 쓸쓸히 빗속을 걸을까 봐
집 앞이야 니가 보여 누구랑 있나 봐
솔직히 말 못했어 그럼 널 잃을까 봐

나도 알아 내 행동 비겁해
비겁하다 놀려도 난 절대 못 가 더는
이런 내 맘 알까 너는
네게 가는 길이 내게 왜 지옥행
같이 느껴져야 되는건지
이건 말이 안돼
니 외로움 달래 준건 난데
어서 말해 제발 아무 사이 아니라고
왜 난 안돼 한 번 해봐 아무 말이라도

지금 너 거기서 뭐하니
지금 널 멀리서 멍하니
바라보는 내가 느껴지지 않니
하고픈 말은 다 내일 해
미안하단 말도 내일 해
자꾸 어딜 봐 바로 여기가 니가 있어야 할 자린데

여보세요 밥은 먹었니
어디서 뭘 하는지 걱정되니까
여보세요 왜 아무 말 못하니
여보세요 여보세요

널 보고 싶었어 비가 오니까 (비가 내리니까)
너와 걷던 거리를 걷다 보니까 (죽겠으니까)
집 앞이야 보고 싶어 너는 아닌가 봐 (보고싶어)
솔직히 미치겠어 너 아님 안되나 봐

Baby I can’t let you go (밥은 먹었니)
I only think about you girl
What would I be without you girl (어디서 뭐 하는지)
Don’t tell me lies, Don’t say goodbye
I just wanna let you know (왜 아무말 못하니)
I only think about you girl
What would I be without you girl
What would I be without you girl

여보세요




일요일, 5월 28, 2017



최근에 우연히 듣게된 노래인데 2014년에 발매된 곡이네요...

이런 노래를 지금껏 몰랐다니... @_@

제대로 취향저격 당해서 무한재생 중입니다...







마크툽(MAKTUB), 구윤회 - Marry Me

비내리는 날엔
우산이 되주고
어둠이 오면 빛이 되줄게

추운 겨울이면
난로가 되주고
더운 날엔 바람이 될게

잠이 들 때까지 머릴 만져줄게
니가 두려울 때마다 꼭 옆에 있어줄게

갑작스런 맘에 문득 떠나고 싶으면
내일 무슨 일이 있어도 함께 떠나줄게

Marry Me
내 손 잡아줄래요
Marry Me
나와 평생 함께 할래요
남은 나의 모든 삶.
오직 그대 남자로 살고 싶어요
Marry Me darling
나와 결혼해줄래요

순간뿐이 아냐 많이 생각했어
헌데 내 사랑을 줄 수 있는 여잔 너밖에 없어

차갑고 어두운 험하고 쓸쓸한 세상 속
평생의 동반자로 함께 걸어가고 싶어

Marry Me
내 손 잡아줄래요
Merry Me
나와 평생 함께 할래요
남은 나의 모든 삶.
오직 그대 남자로 살고 싶어요
Marry Me darling
나와 결혼해줄래요

내 안에 숨쉬는 아름 다운 그대
영원히 같은 꿈을 꾼다면 얼마나 좋을까
믿어요 Marry Me
그대와 함께 하는 매일이
내겐 천국이죠
나와 결혼해줄래요

비내리는 날엔
우산이 되주고
어둠이 오면 빛이 되줄게





일요일, 5월 14, 2017



전 세계적으로 "Wanna Cryptor" 랜섬웨어가 유행입니다 ;;;

이 랜섬웨어에 대한 정보는 안랩 ASEC 블로그의 내용을 참고하면 되겠습니다.

ASEC BLOG - SMB 취약점으로 전파되는 워너크립터(WannaCryptor) 랜섬웨어


KISA 에서도 랜섬웨어 예방 요령 공지를 하고 있습니다.

KISA보호나라 & KrCERT - SMB 취약점을 악용한 랜섬웨어 방지 대국민 행동 요령


KISA 에서 안내하는 내용은 다음과 같습니다.

------------------------------------------------------------------------
1. PC 를 켜기전 네트워크 단절
  - 랜선 뽑기, 와이파이 끄기

2. 감염 경로 차단
 1) 제어판 -> ( '시스템 및 보안' ) -> Windows 방화벽
 2) 고급 설정 -> 인바운드 규칙 -> 새 규칙
 3) 포트 -> 'TCP' 선택, '특정 로컬 포트' : 139, 445 -> '연결 차단' 선택
 4) '도메인', '개인', '공용' 체크
 5) 이름 "SMB 차단" 으로 일단 설정

3. 인터넷 재연결후 보안 업데이트
  - 윈도우 보안 패치
  - 백신 프로그램 업데이트
------------------------------------------------------------------------

PC 를 잘 다루는 분이 아니라면 ~

2번 항목은 꽤나 번거롭고 어렵게 느껴질 수 있겠다 싶더군요...;;;

그래서 뚝딱뚝딱~ 툴을 만들어 봤습니다.


[ 윈도우 방화벽 SMB 차단 룰 등록 & 삭제 도구 다운로드 ]

"SMB_Block_Rule.zip" 파일을 받아서 압축을 풀면 2개의 실행파일이 있습니다.

- Insert_SMB_Block_Rule.exe : 윈도우 방화벽에 SMB 관련 포트 차단 룰을 등록
- Delete_SMB_Block_Rule.exe : Insert 툴로 등록한 룰 삭제


사용법은 간단합니다.

네트워크 단절 상태를 만든 다음~

"Insert_SMB_Block_Rule.exe" 파일을 "관리자 권한"으로 실행합니다.

윈도우 방화벽을 사용중이라면 아래 화면처럼 "SMB 차단" 룰을 등록해 줍니다.

SMB 관련 포트 차단

이 상태에서 다시 인터넷 연결해서 윈도우 보안 업데이트 및 백신 업데이트를 진행하시면 됩니다 ~ :)

어렵지 않죠~? :)


나중에 다시 원상태로 돌리고 싶을 땐~

"Delete_SMB_Block_Rule.exe" 를 "관리자 권한"으로 실행하면~

위에서 등록했던 "SMB 차단" 룰을 삭제해줍니다.


일단 제가 사용중인 Windows 7 환경에서는 실행이 잘되어서 공유하는데...

다른 윈도우는 모르겠네요;;; 혹시라도 문제가 있으면 댓글 남겨주세요.




수요일, 4월 19, 2017



스타크래프트 클래식 1.18

"스타크래프트" 를 열렬히 좋아하는건 아니지만~

중학생 시절 PC방 가서 밤샘도 해보고, 모뎀으로 친구와 멀티플레이를 해본...

나름의 소소한 기억들이 있어서 그런지 "스타크래프트 리마스터" 의 소식이 반가웠습니다.


덕분에 클래식 버전은 1.18 로 업데이트 되면서 무료 배포로 딱~!!!

[ 스타크래프트 클래식 설치파일 다운로드 ]


추억의 화면

오랜만에 에피소드 진행하면서~ 스토리 다시 한 번 되새겨 봐야겠어요~ :)

리마스터가 나오면 이 모든걸 "한글"로 즐길 수가 있겠죠...? @_@

얼른 나오길....





화요일, 4월 11, 2017



지난번에 올린 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 의 비정상 함수 호출 코드 (소스코드)
참고로 lpFunc 는 프로세스 베이스 주소 + 0x1000 의 값으로 고정해두었습니다.

이 코드를 디버거로 보면 아래와 같은 디스어셈블 코드가 나옵니다.

SampleDll.dll 의 비정상 함수 호출 코드 (디스어셈블 코드)
노란 박스 안의 저 "CALL" 명령으로 시작되는 코드를 Pin 으로 잡아내면 되겠죠~? :)


핵심 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 을 공부하시는 분들께 조금이나마 도움이 되었으면 좋겠네요~~ :)





목요일, 3월 30, 2017



믿고 듣는 아이유~ :D

이번 노래도 제대로 취향저격이네요~ (*-_-*)

음원차트를 휩쓸고 있는 중... ㅋ








아이유(IU) - 밤편지

이 밤 그날의 반딧불을
당신의 창 가까이 보낼게요
음 사랑한다는 말이에요

나 우리의 첫 입맞춤을 떠올려
그럼 언제든 눈을 감고
음 가장 먼 곳으로 가요

난 파도가 머물던
모래 위에 적힌 글씨처럼
그대가 멀리
사라져 버릴 것 같아
늘 그리워 그리워

여기 내 마음속에
모든 말을
다 꺼내어 줄 순 없지만
사랑한다는 말이에요

어떻게 나에게
그대란 행운이 온 걸까
지금 우리 함께 있다면
아 얼마나 좋을까요

난 파도가 머물던
모래 위에 적힌 글씨처럼
그대가 멀리
사라져 버릴 것 같아
또 그리워 더 그리워

나의 일기장 안에
모든 말을
다 꺼내어 줄 순 없지만
사랑한다는 말

이 밤 그날의 반딧불을
당신의
창 가까이 띄울게요
음 좋은 꿈 이길 바라요



일요일, 3월 26, 2017



일전에 Visual Studio 에서 Intel Pin 프로젝트를 설정하는 방법을 올린 적이 있습니다.

이번에는 응용차원에서 Pin 을 활용하는 방법을 올려봅니다. @_@

주 업무분야가 '게임보안' 인만큼 '게임 해킹툴 분석' 측면으로 접근해봤습니다... ^^;;

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 예제 코드입니다


// 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 에서 메모리 조작을 하는 코드가 깔끔하게(?) 로그 파일에 기록되었습니다~ :)


마치며

일반적으로 Pin 으로 프로그램을 실행시키면 그냥 실행시키는 것보다 속도가 느립니다.

게다가 Instrumentation 하는 범위가 넓을 수록... 로깅 위치가 많을 수록...

엄~~~청나게 느려집니다. -_-;;;;;;

Instrumentation 범위 조절과 로깅 위치 조절만 하더라도 실행 속도를 올릴 수 있으니...

적절하게 필터링을 해서 쓰는 걸로~ :)


5년 전에 회사에서 이것저것 시도하다 한계에 부딪혔던걸...

지금 올리네요... -_-;;;;;




수요일, 2월 15, 2017



Pin 3.2 버전이 올라왔군요... @_@ !!!

[ Pin - A Binary Instrumentation Tool 다운로드 페이지 ]


Pin 2.14 버전은 VS2015 를 지원하지 않고~

Pin 3.0 은 작년에 올라왔다가 어느 순간 윈도우 버전 다운로드 링크가 사라져서 난감했는데...

Pin 3.2 버전으로 다시 올라왔네요~ :)


Pin 3.x 로 넘어오면서 프로젝트 생성 시 손봐줘야 될 것들이 많아졌는데~

기록보관 차원에서 포스팅해봅니다.


시작하기 전에


준비물 : Visual Studio 2015 Community, Pin 3.2 (윈도우용)

Pin 3.2 는 다운로드 페이지에서 받은 후, 원하는 곳에 압축을 풀어두면 됩니다.


프로젝트 생성 및 Pin 설정


Win32 응용 프로그램 - DLL - 빈 프로젝트

PinTool 은 DLL 형태이기 때문에~ DLL 을 선택한 후 "빈 프로젝트" 로 프로젝트를 생성합니다.

프로젝트에 파일이 하나도 없으면 '프로젝트 속성' 페이지에 'C/C++' 항목이 안보이니...

편의상 비어있는 cpp 파일이라도 하나 만들어서 프로젝트에 추가해줍니다.


이제 '프로젝트 속성' 페이지를 열어서~ 하나하나 만져주면 됩니다.

구성속성 - 일반
'구성속성' - '일반' 페이지에서 '문자 집합'"멀티바이트 문자 집합 사용" 지정해줍니다.


다음은 'C/C++' - '일반' 페이지의 '추가 포함 디렉터리' 에 Pin 관련 Include 폴더들을 추가해줍니다.

C/C++ - 일반 - 추가 포함 디렉터리
PinTool 프로젝트 생성시 제일 귀찮은 부분이 아닐까~ 싶네요.

이번 버전에 비해 포함시켜줘야 되는 폴더들이 많아졌습니다. oTL;;;;

압축을 풀어둔 폴더가 PIN_ROOT 라는 가정하에 아래의 폴더들을 추가하면 됩니다.
( 제 PC 의 경우 PIN_ROOT=E:\Work\Source\pin-3.2-81205-msvc-windows 가 되겠죠~ )

------------------------------------------------------------------------------------------------
%PIN_ROOT%\source\include\pin
%PIN_ROOT%\source\include\pin\gen
%PIN_ROOT%\extras
%PIN_ROOT%\extras\components\include
%PIN_ROOT%\extras\crt
%PIN_ROOT%\extras\crt\include
%PIN_ROOT%\extras\crt\include\arch-x86 (64비트용은 arch-x86_64)
%PIN_ROOT%\extras\crt\include\kernel\uapi
%PIN_ROOT%\extras\crt\include\kernel\uapi\asm-x86
%PIN_ROOT%\extras\libstdc++\include
%PIN_ROOT%\extras\stlport\include
%PIN_ROOT%\extras\xed-ia32\include\xed
( 64비트용은 %PIN_ROOT%\extras\xed-intel64\include\xed )
------------------------------------------------------------------------------------------------

일단 이 정도는 최소한으로 포함이 되어야 되는 걸로 보입니다.

없어도 되겠지 싶어서 폴더를 없애보면 컴파일 에러가... -_-;;;;;


C/C++ - 전처리기
'C/C++' - '전처리기' 페이지에서 아래 값들을 추가해줍니다.

------------------------------------------------------------------------------------------------
TARGET_IA32
(64비트용은 TARGET_IA32E)
HOST_IA32
(64비트용은 HOST_IA32E)
TARGET_WINDOWS
__PIN__=1
PIN_CRT=1
__i386__
(64비트용은 __LP64__ )
------------------------------------------------------------------------------------------------


다음은 'C/C++' - '코드 생성' 페이지~

C/C++ - 코드 생성
'C++ 예외 처리 가능' 항목을 "아니요" 로~

'런타임 라이브러리' 항목을 "다중 스레드(/MT)" 로~

'보안 검사' 항목을 "보안 검사 사용 안 함(/GS-)" 으로 지정해줍니다.


C/C++ - 언어
'C/C++' - '언어' 페이지에선 '런타임 형식 정보 사용' 항목을 "아니요(/GR-)" 로 지정합니다.


그리고 'C/C++' - '명령줄' 페이지의 '추가 옵션' 부분에~

"/FIinclude/msvc_compat.h" 를 입력해줍니다.

C/C++ - 명령줄



다음은 '링커' 항목입니다.

'링커' - '일반' 페이지의 '추가 라이브러리 디렉터리' 에 Pin 관련 라이브러리 폴더를 추가해줍니다.

링커 - 일반 - 추가 라이브러리 디렉터리
PIN_ROOT 를 기준으로 아래의 폴더들을 추가해줍니다.

------------------------------------------------------------------------------------------------
[ 32비트 ]

%PIN_ROOT%\ia32\lib
%PIN_ROOT%\ia32\lib-ext
%PIN_ROOT%\ia32\runtime\pincrt
%PIN_ROOT%\extras\xed-ia32\lib


[ 64비트 ]

%PIN_ROOT%\intel64\lib
%PIN_ROOT%\intel64\lib-ext
%PIN_ROOT%\intel64\runtime\pincrt
%PIN_ROOT%\extras\xed-intel64\lib
------------------------------------------------------------------------------------------------

라이브러리 폴더를 추가한 다음~ 실제 사용할 라이브러리를 지정해야되는데요...

링커 - 입력 - 추가 종속성

'링커' - '입력' 페이지의 '추가 종속성' 항목에 아래의 라이브러리들을 추가해줍니다.

------------------------------------------------------------------------------------------------
pin.lib
pinvm.lib
xed.lib
kernel32.lib
ntdll-32.lib (64비트는 ntdll-64.lib)
c-static.lib
m-static.lib
os-apis.lib
stlport-static.lib
crtbeginS.obj
------------------------------------------------------------------------------------------------

라이브러리 추가 후엔 '모든 기본 라이브러리 무시' 항목을 "예(/NODEFAULTLIB)" 로 지정합니다.

링커 - 입력


'링커' - '고급' 페이지에도 만져줘야 될 항목들이 있습니다.

링커 - 고급

'진입점' 항목에 "Ptrace_DllMainCRTStartup%4012" 를~ (64비트는 "Ptrace_DllMainCRTStartup" 만)

'기준 주소' 항목에 "0x55000000" 을~ (64비트는 "0xC5000000") 입력하고

'이미지에 안전한 예외 처리기 포함' 항목을 "아니요(/SAFESEH:NO)" 로 지정합니다.


마지막으로 '링커' - '명령줄' 페이지의 '추가 옵션'"/export:main" 을 입력~!!

링커 - 명령줄



꽤 번거롭긴(?) 하지만  일단 여기까지하면~

Pin 코드를 작성해서 테스트 해볼 수가 있습니다. @_@

빌드 성공


다음엔 게임 해킹툴 분석 시 도움이 될만한 PinTool 을 만들어보는 걸로~~ ㅋ :)








화요일, 2월 14, 2017



안드로이드쪽 공부하면서 바이너리 분석도 같이 보고 있는데...

ELF 포맷에 ARM 타입의 바이너리가 많더군요.. @_@;;;

IDA Pro 를 장만할(?) 여력은 안되고... -_-;;;

이것저것 뒤져보다 ARM 지원하는 디스어셈블 엔진(Capstone Engine)이 있길래...

요걸로 간단한 디스어셈블러 만들어보자~~ 는 생각으로 작업을 했습니다.


디스어셈블 엔진을 사용하려는데 파일의 어느 부분이 코드영역인지 몰라서... -_-;;;;;

또 ELF 포맷 문서를 한참 들여다봤네요...

공부한 내용을 바탕으로 C++ Builder 로 뚝딱뚝딱~~ (이라 쓰고 삽질이라고 읽...;;; )


ELF 포맷 - Info View

Hex View

Disasm View


디스어셈블은 섹션 중 Execute 플래그가 있는 부분만 하도록 했는데...

ELF 포맷에 대한 이해도가 부족하다보니 요렇게 하는게 맞는건지 모르겠네요...ㅋ ^^;;;

좀 더 공부를 해야겠어요... @_@;;...



[ Simple ELF View 다운로드 ]






일요일, 2월 05, 2017



안드로이드 앱을 만들어 보고 싶어서 '안드로이드 스튜디오 (2.2.3)'를 설치하고~

버벅대며 이것저것 만져봤습니다.


버튼 위젯을 하나 올려놓고 테스트를 하던 중...

버튼 텍스트를 영어로 할 땐 문제가 없는데, 한글로 할 떄 글자가 깨지는 현상이 발생하더군요.. @_@;

한글이 안보인다.. oTL


구글을 통해 찾아보니 기본 한글 폰트 설정이 잘못되어 있어서 폰트를 읽어오지 못하기 때문에...

글자가 깨진다고 하더군요.


안드로이드 스튜디오 레이아웃 폰트 관련 폴더

fonts.xml 파일의 내용


안드로이드 스튜디오가 설치된 폴더의 "plugins\android\lib\layoutlib\data\fonts" 폴더의

fonts.xml 에 레이아웃 디자인 시 사용되는 폰트들이 설정되어 있는데...

한글인 경우 "NotoSansCJK-Regular.ttc" 폰트로 되어 있습니다.

그런데 이 폴더에는 "NotoSansCJK-Regular.ttc" 폰트가 없더군요... =_=;;;; ??

한글을 처리할 수 있는 폰트가 없어서 글자가 깨지는거죠... oTL;;

그럼 한글을 처리할 수 있는 폰트를 지정해주면 문제가 해결이 되겠죠~? :)



가장 간단한(?) 방법은 기본 지정된 폰트를 다른 걸로 바꿔주는 겁니다.

"나눔고딕" 폰트를 사용하기


다행히도 레이아웃 폰트 관련 폴더에 "나눔고딕(NanumGothic.ttf)" 폰트가 이미 포함되어 있습니다.

fonts.xml 파일에서

<family lang="ko">
    <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
</family>
이렇게 되어있는 부분을

<family lang="ko">
    <font weight="400" style="normal">NanumGothic.ttf</font>
</family>
이렇게 바꿔주면 되는거죠~ :)

일단 요렇게만 해도 레이아웃 화면에서 한글은 잘 나오더군요...



다른 방법으로는 "NotoSansCJK-Regular.ttc" 폰트를 추가해주는 방법이 있습니다.

"NotoSansCJK-Regular.ttc" 폰트를 추가하기


"NotoSansCJK" 폰트는 구글의 NotoSansCJK 페이지 에서 구할 수 있습니다.

[ NotoSansCJK-Regular 폰트 다운로드 ]


ZIP 파일 압축을 풀고 "NotoSansCJK-Regular.ttc" 파일을 레이아웃 폰트 폴더에 복사를 한 다음..

레이아웃 폰트 폴더의 "fontsInSdk.txt" 파일을 열어서 내용을 추가해줍니다.

fontsInSdk.txt 파일에 "NotoSansCJK-Regular.ttc" 추가

폰트만 복사하고 "fontsInSdk.txt" 파일에 내용 추가를 하지 않으면 인식이 되지 않으니...

꼭~ 추가해 주셔야 됩니다 @_@;;


두 방법 중 입맛에 맞는 방법으로 해결을 하시면 되겠습니다. ^^:;;

한글이 잘보인다.. @_@





월요일, 1월 30, 2017



리버싱을 하다보면 필요에 따라 자신만의 툴을 만드는 경우가 종종 있습니다.

툴을 만들다보면 윈도우 API 를 사용해야 할 때가 있는데...

파이썬에서 ctypes 로 윈도우 API 를 사용하는 방법을 정리해봤습니다.


우선은 ctypes 와 ctypes.wintypes(자료형 모음) 를 임포트 해줍니다.

from ctypes import *
from ctypes.wintypes import *


윈도우 API  는 대체로 windll 을 이용하면 되는데요~

아래처럼 모듈 이름과 함수 이름을 적어주면 됩니다.

# Type 1
GetModuleFileName = windll.kernel32.GetModuleFileNameW
GetModuleHandle = windll.kernel32.GetModuleHandleW

# Type 2
Kernel32 = windll.kernel32

GetModuleFileName = Kernel32.GetModuleFileNameW
GetModuleHandle = Kernel32.GetModuleHandleW


입력하기 쉽게 "GetModuleFileName", "GetModuleHandle" 로 했을 뿐...

windll.kernel32.GetModuleFileNameW / Kernel32.GetModuleFileNameW 이나

windll.kernel32.GetModuleHandleW / Kernel32.GetModuleHandleW 를 그대로 사용해도 됩니다.

사용하려는 API 가 많을 경우 Type 2 처럼 사용하는게 더 편하지 않을까 생각되네요 ^^;;;


API 사용 예 #1 - GetModuleHandleW

from ctypes import *
from ctypes.wintypes import *

Kernel32 = windll.kernel32

print("[*] GetModuleHandleW [*]")
Kernel32_BaseAddr = Kernel32.GetModuleHandleW("KERNEL32.DLL")
print("    - KERNEL32.DLL = 0x%X" % Kernel32_BaseAddr)

GetModuleHandleW 호출 결과

가장 단순한 형태의 사용 예입니다. 그냥 인자를 넣어주기만 하면 되는거죠~ :)

참고로 64비트 파이썬에서는 GetModuleHandleW 를 호출하기 전에...

restype 을 직접 지정해줘야 주소값을 제대로 가져옵니다.

Kernel32.GetModuleHandleW.restype = c_void_p
Kernel32_BaseAddr = Kernel32.GetModuleHandleW("KERNEL32.DLL")


API 사용 예 #2 - GetModuleFileNameW

from ctypes import *
from ctypes.wintypes import *

Kernel32 = windll.kernel32

path = create_unicode_buffer(MAX_PATH)

print("[*] GetModuleFileNameW [*]")
Kernel32.GetModuleFileNameW(0, path, MAX_PATH)
print("    - Path = %s" % path.value)

GetModuleFileNameW 호출 결과

윈도우 API 중에는 GetModuleFileName 처럼 데이터를 담을 버퍼를 인자로 받아서

그 버퍼에 데이터를 넘겨주는 방식도 있습니다.


create_string_buffer, create_unicode_buffer 로 데이터를 담을 수 있는 객체를 만들 수 있는데요...

create_string_buffer 는 C 언어의 "char *", 파이썬의 "bytes" 와 대응되며,

create_unicode_buffer 는 C 언어의 "wchar *", 파이썬의 "str" 과 대응됩니다.

~A 계열 함수를 사용할 때는 create_string_buffer 를 사용하고,

~W 계열 함수를 사용할 때는 create_unicode_buffer 를 사용하면 됩니다.

객체에 담겨진 실제 데이터는 value 를 통해 얻을 수 있습니다.

create_string_buffer / create_unicode_buffer


API 사용 예 #3 - CreateProcessW

from ctypes import *
from ctypes.wintypes import *


class PROCESS_INFORMATION(Structure):
    _fields_ = [("hProcess", HANDLE),
                ("hThread", HANDLE),
                ("dwProcessId", DWORD),
                ("dwThreadId", DWORD)]


class STARTUPINFO(Structure):
    _fields_ = [('cb', DWORD),
                ('lpReserved', LPWSTR),
                ('lpDesktop', LPWSTR),
                ('lpTitle', LPWSTR),
                ('dwX', DWORD),
                ('dwY', DWORD),
                ('dwXSize', DWORD),
                ('dwYSize', DWORD),
                ('dwXCountChars', DWORD),
                ('dwYCountChars', DWORD),
                ('dwFillAttribute', DWORD),
                ('dwFlags', DWORD),
                ('wShowWindow', WORD),
                ('cbReserved2', WORD),
                ('lpReserved2', LPBYTE),
                ('hStdInput', HANDLE),
                ('hStdOutput', HANDLE),
                ('hStdError', HANDLE)]


Kernel32 = windll.kernel32

startupinfo = STARTUPINFO()
processinfo = PROCESS_INFORMATION()

print("[*] CreateProcessW [*]")
Kernel32.CreateProcessW("C:\\Windows\\NOTEPAD.exe", None, None, None, 0, 0,
                        None, None, byref(startupinfo), byref(processinfo))
print("    - hProcess = %X" % processinfo.hProcess)
print("    - dwProcessId = %d (%X)" % (processinfo.dwProcessId, processinfo.dwProcessId))

CreateProcessW 호출 결과

앞의 두 예제와 비교하면 코드의 양이 꽤 깁니다...;;; ( 이게 다 구조체 때문임.. =_=;;;; )


파이썬은 C 언어의 '구조체' 를 그대로 사용할 수 없기 때문에...

'구조체' 를 인자로 받는 API 를 사용하기 위해서는 추가 작업이 필요합니다.

ctypes 의 "Structure" 클래스를 상속받아서 임의의 클래스를 만든 다음...

"_fields_" 에 구조체 멤버들을 추가해주면 됩니다.

함수 인자에 참조 연산자('&')를 사용하는 경우가 있는데 파이썬은 "byref" 를 이용하면 됩니다.



이상의 세가지 형태의 API 사용 방법을 숙지하고 있으면...

대부분의 윈도우 API 는 문제없이 사용할 수 있을거라 생각합니다. @_@;;;





화요일, 1월 24, 2017



프로그래밍 전문잡지 "마이크로소프트웨어" 가 다시 돌아왔습니다 :)

예전처럼 월간지 형식은 아니지만 그래도 종이로 인쇄된 책을 넘겨볼 수 있다는 건 정말 반갑네요 ^^


2017년 vol.387


1997년...

같이 놀던 친구의 영향으로 프로그래밍에 관심을 갖기 시작하면서~

프로그래밍 관련 책들을 보기 시작했는데 "마이크로소프트웨어" 도 그 중 하나였습니다.

그 당시는 책 내용을 거의 이해못했던 기억이 나네요... ^^;;;

C 언어 공부를 막 시작했고 printf() 로 문자열 출력하는 것만으로 신세계를 경험했던 수준에서는

너무 어려웠달까요...;;;

1년 정도 지난 후, 기반 지식이 조금 쌓인 후에야 처음에 봤던 내용들이 이해가 가더군요 @_@;;

그 후로는 지금 당장은 어려워도 나중엔 도움이 되겠지 생각하고 정기구독을 하기도 했습니다.
( 실제로 시간이 조금 지난 후에 그 내용들이 도움이 되었다는게... )


2000년 조금 지난 시점에는 "웹" 이 유행하기 시작하면서...

마소의 내용도 웹프로그래밍, DB 등 분야가 다양해지더군요.

책 한 권에 담을 수 있는 내용의 양은 정해져 있는데, 다루는 분야가 넓어진 만큼...

원하는 내용이 많이 줄어드는 걸 느꼈습니다.

책 한 권 안에 볼 내용이 하나도 없는 경우도 있더군요...;;;


그 후로 회사 생활을 시작하면서 회사에서 정기구독을 하면 회사에서 보고~

업무 분야(보안, 리버싱 등...)의 내용이 담기거나 지인이 기고를 하면 한번씩 구매를 했네요..;;

어쨌든 필요한 정보도 얻고 나름 도움도 받았던 잡지가 2015년 12월을 마지막으로 휴간되더군요.
( '휴간'이라 쓰고 '폐간' 이라 읽... )


2015년 마소들


휴간 결정이 난 후로 많은 분들이 아쉬워했고 다시 살리려는 움직임도 많았던 걸로 알고 있는데...

그 결실이 이렇게 맺어진 게 아닌가 싶네요... :)


프로그래밍 전문잡지의 명맥이 계속 유지될 수 있길...





금요일, 1월 20, 2017



대세 드라마 "도깨비" 의 OST 입니다.

멜로디 라인이 제대로 취향저격을...ㅜㅜ...

얼마간 무한반복 할 듯 싶네요.






에일리 - 첫눈처럼 너에게 가겠다

널 품기 전 알지 못했다
내 머문 세상 이토록
찬란한 것을

작은 숨결로 닿은 사람
겁 없이 나를 불러준 사랑

몹시도 좋았다
너를 지켜보고 설레고
우습게 질투도 했던
평범한 모든 순간들이

캄캄한 영원
그 오랜 기다림 속으로
햇살처럼 니가 내렸다

널 놓기 전 알지 못했다
내 머문 세상 이토록
쓸쓸한 것을

고운 꽃이 피고 진 이 곳
다시는 없을 너라는 계절

욕심이 생겼다
너와 함께 살고 늙어가
주름진 손을 맞잡고
내 삶은 따뜻했었다고

단 한번 축복
그 짧은 마주침이 지나
빗물처럼 너는 울었다

한번쯤은 행복하고
싶었던 바람
너까지 울게 만들었을까

모두, 잊고 살아가라
내가 널, 찾을 테니
니 숨결, 다시
나를 부를 때

잊지 않겠다
너를 지켜보고 설레고
우습게 질투도 했던
니가 준 모든 순간들을

언젠가 만날
우리 가장 행복할 그날
첫눈처럼 내가 가겠다

너에게 내가 가겠다



수요일, 1월 11, 2017



일전에 '스카이림 스페셜 에디션' 관련된 내용을 올린 적이 있습니다.

http://www.xeronichs.com/2016/11/SkyrimSE-Achievements-with-MOD.html ]


모드 적용 시 업적 달성 가능하도록 해주는 툴을 만들어야지... 만들어야지... 하다가

요 며칠간 뚝딱뚝딱 만들어봤습니다.


UI 작업할 땐 개인적으로 C++ Builder 를 더 좋아하는데~

스카이림 스페셜 에디션이 64비트 클라이언트라서 어쩔 수 없이 Visual Studio 로..;;;;

( 현재 보유 중인 C++ Builder 스타터 에디션은 64비트를 지원하지 않다보니.. oTL;;; )

예전에는 MFC 도 그럭저럭 썼던거 같은데... 오랜만에 만져보니 뭔가 번거롭더군요..

특히 컨트롤 크기나 배치 등 설정을 세밀하게 하는게 C++ Builder 에 비해서 귀찮습니다;;;




스카이림 실행 파일("SkyrimSE.exe") 파일의 경로를 지정해주고~

"Patch (with Run)" 버튼을 누르면 게임 실행과 동시에 패치를 해줍니다.


참고로 실행 파일을 직접 패치하는 게 아니라 실행된 프로세스의 메모리 코드를 패치하는거라서...

매번 -_-;;; 실행을 해줘야 합니다...

일단 제가 원하는 선에서는 잘 동작하는 관계로 기능 추가가 있을지는 모르겠네요..ㅋㅋ ^^;;;


[ SkyrimSE_AE_Patch 다운로드 ]

[ Visual Studio 2015 재배포 패키지 ]




카테고리

가장 많이 본 글

통계

Copyright © XeroNic(HS) BLOG | Powered by Blogger
Design by WP Lift | Blogger Template by NewBloggerThemes.com