# python 2.7.8 기준

 

1. 파이썬 설치 이후 Paimei 설치 (Paimei가 뭔지 잘모르나 일단 설치)

 

PaiMei-1.1.win32.exe

 

2. 아래 pydasm.pyd를 다운로드 후에 "C:\Python27\Lib\site-packages\pydbg\" 에 복사 후 덮어 씌움

 

pydasm.pyd

 

3. 아래 __init__.py 파일을 다운로두 후에 "C:\Python27\Lib\ctypes\"에 복사 후 덮어 씌움

 

__init__.py

 

4. python 에서 import pydbg 하여 에러 메시지 없으면 정상 설치

http://cdpython.tistory.com/35

 

http://ha.ckwith.me/entry/열혈강의-파이썬-간단한-명령어-해석기-설계

메시지 구동 구조


윈도우 운영체제에서 실행되는 대부분의 응용프로그램은 메시지 구동 구조 (Message - Driven Architecture)로 동작한다. 여기서 메시지는 운영체제가 프로그램의 외부 또는 내부에 변화가 발생했음을 해당 프로그램에 알리기 위한 개념이다.


일반적으로 도스용 프로그램이나 윈도우의 콘솔 응용 프로그램은 프로그래머가 정한 순서대로 실행된다. 따라서 순차적인 방식에 의존해야 하므로 알고리즘과 논리의 흐름에 중점을 두고 프로그래밍 한다.


하지만 대부분의 윈도우 응용 프로그램은 순차적으로 실행되지 않고 어떤 메시지를 받는가에 따라 코드의 실행 순서가 달라진다.



출처 : 한빛출판사 윈도우 프로그래밍 기초

           [출처 : 한빛출판사 윈도우 프로그래밍 기초 sample.pdf]


외부에서 메시지를 발생시키는 이벤트(Event)가 발생하면 운영체제가 관리하는 시스템 메시지 큐 (Message Queue)에 정보가 저장된다. 각각의 응용프로그램은 운영체제로부터 독립적인 메시지 큐를 할당받으며 운영체제는 시스템 메시지 큐에 저장된 메시지를 적절한 응용프로그램 메시지 큐에 보낸다. 응용프로그램은 자신의 메시지 큐를 감시하다가 메시지가 발생해서 큐에 들어오면 하나씩 꺼내서 처리하고 메시지가 없을 때는 대기한다.



메시지 핸들러 집합


윈도우 운영체제의 특징에서 살펴본 것처럼 윈도우 응용프로그램은 메시지 구동 구조로 동작한다. 메시지 구동 구조에서는 받는 메시지에 따라 실행 순서가 달라지며 해당 메시지에 어떻게 반응하는가에 따라 동작이 달라진다. 메시지를 받았을 때 동작을 결정하는 코드를 편의상 메시지 핸들러 (Message Handler)라 부르자. 프로그래머는 키보드 메시지 핸들러, 마우스 메시지 핸들러, 메뉴 메시지 핸들러 같은 다양한 메시지 핸들러를 작성하게 된다.


메시지 핸들러의 집합을 윈도우 프로시저(Window Procedure)라 부른다. 윈도우 운영체제는 프로그램이 처리하지 않은 메시지를 자동으로 처리할 수 있도록 운영체제 차원의 메시지 핸들러를 제공한다.



참고 URL : http://maxtrain.egloos.com/2775961




아래 내용 출처는 http://adolys.tistory.com/entry/PeekMessage-GetMessage-TranslateMessage-DispatchMessage 입니다.


윈도우즈 프로그램에서 메시지 (Message) 를 처리하는 부분을 메시지 루프라고 하며

메시지 루프 (Message Loop) 에서 하는 일은 메시지를 꺼내고 필요한 경우 약간 형태를 바꾼 후

응용프로그램으로 전달하는 것 뿐이다. 이 과정은 WM_QUIT 메시지가 전달될 때까지, 

즉 프로그램이 종료될 때까지 반복된다. 


결국 메시지 루프 (Message Loop) 가 하는 일이란 메시지 큐에서 메시지를 꺼내

메시지 처리 함수로 보내주는 것 뿐이다.


BOOL GetMessage




이 함수는 시스템이 유지하는 메시지 큐에서 메시지를 읽어들인다. 읽어들인 메시지는 첫번째 인수가 지정하는 MSG 구조체에 저장된다. 이 함수는 읽어들인 메시지가 프로그램을 종료하라는 WM_QUIT일 경우 False를 리턴하며 그 외의 메시지이면 True를 리턴한다.


따라서 WM_QUIT 메시지가 읽혀질 때까지 즉, 프로그램이 종료될 때까지 전제 while 루프가 계속 실행된다. 나머지 세 개의 인수는 읽어들일 메시지의 범위를 지정하는데 잘 사용되지 않으므로 일단 무시하기로 한다.




BOOL TranslateMessage



TranslateMessage는 키보드 입력 메시지를 가공하여 프로그램에서 쉽게 쓸 수 있도록 해준다고 한다. Windows는 키보드의 어떤 키가 눌러졌다거나 떨어졌을 때 키보드 메시지를 발생시키는데 이 함수는 키보드의 눌림 (WM_KEYDOWN) 과 떨어짐 (WM_KEYUP) 이 연속적으로 발생할 때 문자가 입력되었다는 메시지 (WM_CHAR) 를 만드는 역할을 한다. 예를 들어 A키를 누른 후 다시 A키를 떼면 A문자가 입력되었다는 메시지를 만들어낸다.



LONG DispatchMessage



시스템 메시지 큐에서 꺼낸 메시지를 프로그램의 메시지 처리 함수로 전달

이 함수에 의해 메시지가 프로그램으로 전달되며 프로그램에서는 전달된 메시지를 점검하여 다음 동작을 결정



BOOL PeekMessage



GetMessage함수와 마찬가지로 메시지 큐에서 메시지를 읽는다. 메시지의 범위를 줄 수 있는 기능도 GetMessage와 동일하다. 그러나 이 함수는 GetMessage와는 달리 읽은 메시지를 무조건 제거하지 않으며 큐가 비어있을 경우 대기하지 않고 곧바로 리턴한다는 점이 다르다. 따라서 이 함수는 메시지를 읽지 않고 단순히 메시지가 있는지 확인만 할 수 있으며 이런 특성은 백그라운드 작업에 적절하다.


GetMessage 함수는 메시지 큐가 비어 있을 경우 무한 대기를 하기 때문에 백그라운드 작업을 할 수 없지만

PeekMessage 함수를 사용하면 즉시 리턴하며 리턴 값으로 메시지의 유무를 알려주므로 0을 리턴할 때 백그라운드 작업을 수행할 수 있다. 


- hWnd : 메시지를 받을 윈도우이며 이 윈도우로 보내지는 메시지를 조사한다. 이 윈도우는 반드시 같은 스레드에 소속된 윈도우여야 하며 다른 스레드로 보내지는 메시지는 메시지는 조사할 수 없다. 이 인수가 NULL이며 이 함수를 호출한 스레드로 전달된 모든 메시지를 조사한다.


- wMsgFilterMin : 조사할 메시지의 최소 값

- wMsgFilterMax : 조사할 메시지의 최대 값


- 위 wMsgFilterMin과 wMsgFilterMax 두 인수를 사용하면 일정한 범위에 속한 메시지만 조사할 수 있는데 이를 메시지 필터링이라고 한다. 예를 들어, 키보드 관련 메시지만 조사하고 싶으면 WM_KEYFIRST, WM_KEYLAST로 범위를 지정할 수 있다. 이 두 인수가 모두 0이면 메시지 필터링을 하지 않으며 모든 메시지를 조사한다.


- wRemoveMsg : 조사한 메시지를 처리할 방법을 지정하는 플래그의 조합


- Flag 설명

  1) PM_NOREMOVE - 메시지를 읽은 후 큐에서 메시지를 제거하지 않는다.

  2) PM_REMOVE - 메시지를 읽은 후 큐에서 메시지를 제거한다.

  3) PM_NOYIELD - 다른 스레드로 제어를 양보하지 않는다.

  4) PM_QS_INPUT - 디폴트로 이 함수는 모든 메시지를 다 처리하는데 이하의 플래그들을 지정하면 

                              특정 메시지들만 처리하도록 할 수 있다. 이 플래그들은 98 이상, 2000이상에서 적용된다.

                              마우스나 키보드 등의 입력 메시지만 처리한다.

  5) PM_SQ_PAINT - 그리기 메시지만 처리

  6) PM_QS_POSTMESSAGE - 타이머나 핫키 메시지를 포함하여 붙여지는 메시지만 처리

  7) PM_SQ_SENDMESSAGE - 보내지는 메시지만 처리


실제 메시지 처리는 별도의 메시지 처리 함수 (WndProc) 에서 수행한다. 

메시지는 시스템의 변화에 대한 정보이며 MSG라는 구조체에 보관된다. 


MSG 구조체는 다음과 같이 정의되어 있다.


typedef struct tagMSG{

HWND         hwnd;

UNIT           message;

WPARAM    wParam;

LPARAM     lParam;

DWORD       time;

POINT         pt;

} MSG;


- hwnd : 메시지를 받을 윈도우 핸들

- message : 어떤 종류의 메시지인가를 나타내며, 중요하게 봐야할 목록

- wParam : 전달된 메시지에 대한 부가적인 정보를 가진다. 어떤 의미를 가지는가는 메시지 별로 다르다.

- lParam : 전달된 메시지에 대한 부가적인 정보를 가진다. 어떤 의미를 가지는가는 메시지 별로 다르다.

- time : 메시지가 발생한 시간

- pt : 메시지가 발생했을 때의 마우스 위치


message 멤버를 읽음으로써 메시지의 종류를 파악하며 message 값에 따라 프로그램의 반응이 달라진다.

GetMessage 함수는 읽은 메시지를 MSG 형의 구조체에 대입해 주며 이 구조체는 DispatchMessage 함수에 의해 응용프로그램의 메시지 처리 함수 (WndProc) 로 전달된다. 


메시지는 실제로 하나의 정수 값으로 표현되는데

메시지의 종류가 많아 windows.h를 참고 하여 확인토록 한다. 

WM_ 접두어로 시작한다.


WM_QUIT : 프로그램 끝낼 때 발생 메시지

WM_LBUTTONDOWN : 마우스의 좌측 버튼을 누를 경우 발생

WM_CHAR : 키보드로부터 문자가 입력될 때 발생

WM_PAINT : 화면을 다시 그려야할 필요가 있을 때 발생

WM_DESTROY : 윈도우가 메모이에서 파괴될 때 발생

WM_CREATE : 윈도우가 처음 만들어질 때 발생





 














GetPrivateProfileStringA라는 함수가 악성 코드 분석 중 확인되어 찾아보았다.


1) 함수원형



2) GetPRivateProfileStringA는 아래의 그림과 같이 ini 구성 설정에 관련한 함수라고 한다.



3) 분석한 악성코드에서 아래와 같이 사용되게 되는데 version361.dat 파일에는 파일 버전에 대한 내용이 담겨져 있다.



- 이 의미는 Temp\version361.dat 파일에서 [data] 섹션의 versionname Key가 가진 값을 파싱해서 Return Buffer에 BufSize 만큼 넣으며 만약에 파싱이 되지 않을 경우 Return Buffer에 button02.jpg 라는 기본 문자열을 넣는다.


4) 아래는 테스트 코드 이다.



- 대상 test.ini 내용은 아래와 같다.



- 결과는 아래와 같이 babo라는 문자열을 data에 넣어서 출력한다.



5) 해당 API는 악성 코드가 자신의 버전 정보 혹은 기타 문자열을 특별히 파싱해서 사용될 때, 사용할 수 있는 API로 보인다.



6) 실제 exe 파일을 OllyDbg로 열어보면 아래와 같이 함수 원형대로 인자 값이 넘어가는 것을 확인할 수 있다.

    




+ Recent posts