파이썬 2.7 에서 디스어셈블러 모듈을 써보고 싶어서~ 

파이썬 전반적인 활용능력도 익힐겸(?) "libdasm" [ libdasm 사이트 ] 라이브러리 가져와

직접 "PyDasm" 모듈을 빌드하기로 결정했습니다.


그런데 이게 왠걸...? "vcvarsall.bat" 파일을 찾을 수 없다는 에러를 뱉으며 빌드가 되지 않더군요;;;


처음 시도시 PyDasm 빌드 실패



구글링을 하며 이런저런 정보를 뒤지다 보니~ 

Python 2.7 버전대는 Visual Studio 2008 을 기준으로 되어있다는 그런 글들이 많이 보이더군요..;;

제 PC 에는 Visual Studio 2010, Visual Studio 2013 Express ... 이렇게 설치가 되어있는데 말이죠;;;


근데 아무리 생각해도 저 에러는 "vcvarsall.bat" 파일만 제대로 찾으면 왠지 될거 같다는 생각에~

파이썬의 "Disutils" 라이브러리에서 "vcvarsall.bat" 를 찾는 부분을 뒤져봤습니다.

이것저것 뒤지다보니 MS Visual C++ 컴파일러 계열에 대해서 처리하는 방식이 눈에 들어오더군요.. @_@;;



C 컴파일러에 대한 기본 설정



"msvc" 의 경우는 "msvccompiler" 모듈의 "MSVCCompiler" 클래스를 사용하더군요~ :)


msvccompiler 모듈을 열어봤더니... 맨 마지막에 아래와 같은 내용이 있더군요.. @_@ ;;;


msvccompiler.py



get_build_version() 을 해서 8.0 이상이면 "msvc9compiler" 모듈의 "MSVCCompiler" 을 IMPORT~!!


get_build_version() 은 뭘까요..?? @_@ ;;


get_build_version()



코드 자체는 어려운 코드가 아닙니다.


저 코드 결과가 어떻게 되는지 파이썬 콘솔로 테스트 해볼까요..? :)


파이썬 콘솔 테스트


간단히 설명하면 sys.version 내에서 "MSC v." 문자열을 기준으로 그 뒤의 문자열을 찾아서~

majorVersion, minorVersion 을 계산하는 코드입니다.

( 특이한 점은 majorVersion 을 구할 때 15 에 6 을 빼서~ 9 를 구하는 점이랄까요..; )


다시 돌아가서 어쨌든 결과는 9.0 으로 8.0 보다 크기때문에~

"msvc9compiler" 모듈의 "MSVCCompiler" 클래스를 사용합니다.

"msvc9compiler" 모듈엔 대략 다음과 같은 코드들이 있습니다.


참조할 레지스트리 정보


vcvarsall.bat 경로 설정



드디어 "vcvarsall.bat" 파일 경로를 설정하는 부분을 찾았습니다.

Visual Studio 설치시 생성되는 레지스트리 정보를 읽어와서 경로를 지정하는군요~



[ 키포인트 ]


코드를 보면 아시겠지만 "version" 값에 따라 레지스트리 접근 경로가 달라지는데요...

"version" 값은 앞서 언급한 get_build_version() 으로 리턴되는 값을 말합니다.

"msvc9compiler" 모듈에도 get_build_version() 이 있는데~

여기서 majorVersion 연산하는 부분을 살짝 고쳐서 10.0 이 리턴되도록 하면~

Visual Studio 2010 의 레지스트리를 정상적으로 참고하면서 모듈 빌드도 정상적으로 됩니다~ :)


msvc9compiler.py 의 get_build_version()


Visual Studio 2012 나 2013 의 경우도 동일한 방식으로 majorVersion 부분을 고쳐서~

11.0, 12.0 이 리턴되도록 하면 해당 버전에 맞게 잘 된답니다... ^^;;;



마무리는 일단 기분좋게 빌드는 완료된 화면으로~ :))


majorVersion 수정 후 빌드 성공한 화면



ps... 환경변수만 살짝 건드려서 더 간단히 해결할수 있을지도 모른다는건 함정... =_=;;;;




YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon 진모씨 2014.01.23 03:24 신고  댓글주소  수정/삭제  댓글쓰기

    허걱.. 저는 그냥 VS100COMNTOOLS 환경변수를 VC90COMNTOOLS 환경변수로 지정해줬더니 되서..
    이런 방법도 있었군요, 감사합니다.

    • BlogIcon XeroNic(HS) 2014.01.23 12:11 신고  댓글주소  수정/삭제

      저는 개인적인 호기심 차원에서~
      파이썬에서 어떻게 C/C++ 컴파일러를 호출하는지 보다보니...
      이런 식의 흐름이 파악이 되더라구요~ :)

      외부에 영향을 미칠 수 있는 환경변수를 건드리지 않고~
      파이썬 내부에서 해결하는게 더 깔끔할것 같아서~ :)
      요런 것도 포스팅을 하게 되었네요~ㅎㅎ

  2. Lsick 2015.12.11 11:12  댓글주소  수정/삭제  댓글쓰기

    사용하시는 소스분석 툴 이름이 뭔가요 ?




예전에~ 게임 프로세스 메모리 스캔 엔진을 조금 바꿔볼까 싶어서...


이것저것 정보를 모으던 중 알게된 녀석입니다.


그 당시 룰을 직접 만들면서 "오호... 요놈봐라..!?" 하면서 감탄했던 녀석인데.. 


얼마 전(2013년 12월 26일)에 2.0 이 나왔네요.. @_@ ;;;


매칭 알고리즘이 더 빨라졌다고 하는데... 살포시 소스 한번 봐줘야겠네요..ㅎㅎ



[ YARA 사이트 ]http://plusvic.github.io/yara/




'Etc...' 카테고리의 다른 글

KT, 1200만 고객정보 유출  (0) 2014.03.06
YARA 2.0 이 나왔었군요.  (0) 2014.01.16
[Review] 리소스 에디터 - ResEdit  (0) 2012.03.28
[Review] 윈도우즈용 grep - BareGrep  (4) 2012.02.17
[Review] FireFox 9.0.1 Release~~  (0) 2011.12.23
[Review] Firefox 6.0 Release~  (0) 2011.08.17
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



예~~~전에 지극히 개인적인 편의를 위해 만든 인젝터가 하나 있습니다. ㅎㅎㅎ


이름도 거창한(?) "건담 인젝터" ;;;


2011/07/31 - [My Portfolio] - [APP] GInjector (Gundam Injector)


이 당시 가장 신경을 썼던 기능이 "Drag & Drop" 인데요~~


( 기존의 다른 인젝터들을 쓸 때 매번 버튼을 눌러서 인젝션 할 대상파일을 지정하는게 귀찮아져서~

Drag & Drop 을 지원하는 걸 그냥 만들자~~ 해서 뚝딱뚝딱 만든거랄까요.. ^^;;;; )



이때만해도 주로 인젝션 작업을 한 OS 가 XP 였기에~ 별다른 불편함없이 잘 썼습니다.


그러다가 이런저런 이유로 몇 달 전부터 주 작업 OS 를 Win7 으로 바꿨는데~


인젝터를 '관리자 권한으로 실행' 만 하면~~ 탐색기(낮은 권한 상태)로부터 Drag & Drop 이 안먹히더군요;;;


Drag & Drop 때문에 만든 인젝터인데 그게 안먹힐 때의 그... 허탈함이란..;;;


'수정해야지... 수정해야지...' 생각만 해오다가 불과 2 ~ 3일 전에서야 수정을 했습니다.



키포인트는 비스타부터 지원되는 "ChangeWindowMessageFilter" API 인데요~~

( MSDN - http://msdn.microsoft.com/en-us/library/windows/desktop/ms632675(v=vs.85).aspx )


일반적으로는 권한이 낮은 프로세스에서 권한이 높은 프로세스로 메시지 전달이 안되는데


메시지를 받는 프로세스쪽(저의 경우는 인젝터가 되겠죠~)에서


위의 API 를 이용해서 메시지 필터 설정을 해주면 메시지 전달이 가능하더군요~ :)


Drag & Drop 과 관련된 메시지를 허용하도록 설정하는 코드는 다음과 같습니다.


//
// 컴파일러 버전에 따라 "ChangeWindowMessageFilter" 를 바로 쓸 수 없는 경우도 있어서
// 동적으로 구해오는 방식으로 했습니다.
//
#ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049

#ifndef MSGFLT_ADD
#define MSGFLT_ADD 1

typedef BOOL (WINAPI *pfnChangeWindowMessageFilter)(UINT, DWORD);

.
.
.

HMODULE hUser32Mod = LoadLibrary("USER32.DLL");
if (hUser32Mod != NULL) {
    pfnChangeWindowMessageFilter pChangeWindowMessageFilter =
        (pfnChangeWindowMessageFilter)GetProcAddress(hUser32Mod, "ChangeWindowMessageFilter");

    // XP 이하의 OS 는 해당 API 가 없음. API 가 있는 경우만 실행될 수 있도록 함...
    if (pChangeWindowMessageFilter != NULL) {
        pChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
        pChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
        pChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ADD);
    }
}
// 이후 필요없는 경우 USER32.DLL 은 언로드~
// if (hUser32Mod) FreeLibrary(hUser32Mod);

덕분에 지금은 Win7 에서 인젝터를 "관리자 권한으로 실행" 해도 Drag & Drop 이 잘 동작해서~


인젝터가 존재의 이유를 다시 찾았습니다... =_=v...



YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST