반응형

‘Low’ Integrity level 프로세스 디버깅

 

Vista이후의 OS에는 “Integrity level”(이하 IL)이라는 것을 두어, 같은 사용자 권한으로 동작하는 프로세스라도 IL에 따라 자원 혹은 다른 프로세스에 대한 접근권한을 제어한다.

프로세스의 IL[System, High, Medium, Low] 네 가지 중 하나의 값을 가질 수 있는데, 특히 Low-IL의 경우, 로컬 리소스나 (Medium이상의 IL로 실행된) 다른 프로세스 대한 접근에 상당한 제한이 있다.

 

이 포스트에서는 Low-IL로 실행된 어플리케이션에서 출력하는 OutputDebugString DbgView.exe를 통해 확인 하는 내용에 대해 다룬다.

 

실제 이러한 디버깅 케이스는 흔히 발생하는 케이스는 아니나, Low level로 실행되는 어플리케션을 개발한 경우 이를 디버깅하거나, 기 작성된 Low level로 실행되는 어플리케이션에 injection되어 동작하는 모듈을 디버깅하는 경우 유용할 수 있다.

Low level로 실행되는 어플리케이션의 예를 들자면,

n  IE 8(보호모드)

n  Adobe Reader X

n  MS Office 2010(제한된 보기)

등을 들 수 있다.

 

Windows7에서 IE8을 실행 해 보면 아래와 같이, Medium-IL프로세스가 생성되고 그 프로세스의 자식으로 Low-IL프로세스가 생성된다.

 

 

IE를 통한 악성코드로부터 로컬 시스템을 보호화기 위한 조치로 생각되며(그래서 보호모드 라고 이름을 붙인듯), 자식으로 생성된 Low-IL프로세스는 대부분의 로컬 파일/폴더로의 접근이 제한된다. Low-IL로 실행된 경우에는 보는 것 처럼 Temp폴더 조차도 별도의 폴더로 설정되어 있음을 알수 있다.
[ Medium-IL]

[ Low-IL ]

  

BHO를 이용한 모듈이나 다른 방식으로 IE 8에 인젝션되어 동작하는 모듈을 개발했다고 생각해 보자.

이런한 경우, 일반적인 방법으로는 해당 모듈에서 호출한 OutputDebugString의 출력을 DbgView를 통해 볼수 없다. 여기서 일반적이라 함은 DbgView.exe를 그냥 실행시킨( Medium-IL) 경우를 의미한다.

그냥 파일 로그를 남기면 되지 않겠냐고? 그것 역시도 불가능 하다. Low-IL에서는 위에서 설명한 대로 대부분의 경로에 파일을 생성 할 수 없다. (위에서 살펴본 Temp폴더라면 파일 생성/쓰기가 가능하긴 하지만)

  
언젠가 웹서치를 하다가 DbgView가 공유메모리와 이벤트를 통해 OutputDebugString 출력을 디스플에이 한다고 본 기억이 있는데.....

DbgView Open하고 있는 객체들을 Process Exporer로 확인해 보면

DBWIN_BUFFER_READY, DBWIN_DATA_READY 등의 이벤트를 생성하고 있는 것을 볼 수 있다.

이를 통해 DbgViewOutputDebugString()의 출력을 공유 메모리등에 Write한 후, 상기 이벤트를 설정해 DbgView창에 출력한다고 유추해 볼수 있겠다. 


“Low-IL로 실행된 프로세스(IE8보호모드)가 Medium-IL로 실행된 DbgView의 이벤트 및 리소스에 접근 할수 없어 출력되지 않음정도로 이해하면 될 것 같다.

 

그러면 어떻게 하면 Low-IL로 실행된 프로세스가 출력하는 디버깅 메시지를 확인 할 수 있을까?

위의 내용을 정확히 이해 했다면 방법은 간단하다.

DbgView Low-IL로 실행시키면 된다는 거다. 물론 DbgView Low-IL로 정상적으로 실행되어 준다면

 

프로세스를 Low-IL로 실행시키는 것은 ProcessExplore를 이용하면 이 역시 어렵지 않다.


그리고 다행히도 DbgView.exe는 Low-IL에서도 잘 구동된다. 

(.. ProcessExplore가 없었다면, 어떻게 분석하고 디버깅 했으려나?)


자 이제 모든 준비는 끝났다.디버깅 하면 된다.

아주 간단한 결론이지만, 이방법을 찾지 못해 디버깅한다고 별 삽질을 다했으니 포스팅할 만한 가치는 있지않나? 싶다.

 

 

 

 

 

 

반응형

'Windows Programming > 디버깅' 카테고리의 다른 글

Windbg case by case  (0) 2011.07.08
[WinDbg] 조건부 브레이크 포인트  (1) 2011.07.08
[WinDbg] Kernel 모드에서 특정 프로세스 디버깅하기  (0) 2011.07.05
WOW64 디버깅  (0) 2011.06.27
WinDbg 명령어 정리  (0) 2011.06.21
반응형

 

Kernel 모드에서 특정 프로세스 디버깅하기

 

이번 포스트에서는 WinDbg Debugee OS에 연결 한 후(Kernel-Mode), TestApp.exe프로세스를 디버깅하는 절차에 대해 설명합니다.

 

n  디버깅 하려는 TestApp.exe EPROCESS 주소를 확인하기 !process 0 0 TestApp.exe명령을 입력합니다.


n  .process /i EPROCESS주소를 입력하여 해당 프로세스 컨텍스트로 이동합니다.
Context switching
을 위해 ‘g’를 입력하라고 하는군요. ‘g’를 입력해서 진행시키면 context가 변경된 후, 다시 break가 걸립니다.

 

n  TestApp.exe의 심볼을 로드하기 위해 .reload /user 명령을 입력합니다.

 

n  이제 디버깅 하려는 프로세스의 컨텍스트로 이동되었고 심볼도 로드되었으므로, 디버깅하려는 함수에 breakpoint를 설정합니다.

 

n  보시는 것처럼 TestApp OK버튼을 누르면, DoSomething에서 breakpoint가 걸리는 것을 확인 할 수 있습니다.

 

n  로드된 프로세스의 심볼을 언로드 하려면 .reload /u /user명령을 입력하시면 됩니다.

 

이후의 디버깅은 알아서~ 하시면 됩니다.



n  kernel-mode 디버깅 환경에서 특정 프로세스의 user function에 breakpoint 설정하는 방법

> bp /p @$proc KERNEL32!CreateThreadStub


n  user module list

> lmu

반응형
반응형

svchost.exe

 

 

작업관리자를 보면 svchost.exe프로세스가 다수 실행되어 있는 것을 볼 수 있습니다.

네이버나 기타 검색사이트에서 검색해보면

"svchost.exe가 여러개 떠 있다."
"svchost.exe가 cpu를 100% 잡아 먹는다"
라는 질문들을 많이 볼수 있습니다.

그럼 svchost.exe는 악성코드나 바이러스 같은 것일까요?
아닙니다. svchost.exe는 MS Windows의 시스템 프로세스중의 하나입니다.


전문적인 지식은 없지만, 위에 언급한 svchost.exe관련 문제는 svchost.exe자체의 문제라기 보다는 svchost.exe 이용(악용)한 바이이러스나 악성코드 때문이라고 볼 수 있을것 같습니다.


이 그럼 프로세스는 무슨 역할을 하는 것일까요?

svchost.exe의 속성을 한번 살펴보겠습니다.

 

"Host Process for Windows Services"라고 되어 있네요.

말그대로 Dll로 구현된 윈도우즈 서비스를 호스팅 하는 시스템 프로세스입니다.

프로그래밍 관점에서 보자면 svchost.exe "인자로 전달된 서비스에 대해, 관련 서비스가 구현된 Dll을 로드하여 해당 모듈의 ServiceMain()을 호출 해 준다"라고 생각하면 이해가 편할 듯 합니다.

 

그럼 실제로 어떤 식으로 구동되어 있는지 확인해 보겠습니다.

n  Process Explore를 이용해 svchost.exe가 호스팅 하고 있는 서비스들을 손쉽게 확인해 볼 수 있습니다.
아래의 이미지처럼 말이죠.
C:\Windows\system32\svchost.exe -k RPCSS

 

n  Services 탭에서 좀더 자세한 정보도 볼수 있습니다.(실제 서비스가 구현된 Dll정보도 볼수 있군요)
그리고 보시는 것처럼 한 개의 scvhost.exe에서 한 개 이상의 서비스를 호스팅 하고 있는 경우도 있습니다.
 


아래의 링크에 추가적인 정보가 있으니 참고하시기 바랍니다.


-------------------------------------------------------------------------------------------------------------------------------
 

http://support.microsoft.com/kb/314056


Svchost.exe 파일은 %SystemRoot%\System32 폴더에 있습니다. Svchost.exe는 시작할 때 레지스트리의 서비스 부분을 확인하여 로드해야 하는 서비스 목록을 구성합니다. 여러 개의 Svchost.exe 인스턴스가 동시에 실행될 수 있습니다. 각 Svchost.exe 세션마다 서비스 그룹을 포함할 수 있으므로 Svchost.exe가 시작되는 방법과 위치에 따라 각각 다른 서비스가 실행될 수 있습니다. 이러한 서비스 그룹을 통해 더 효과적으로 제어하고 더 쉽게 디버깅할 수 있습니다.

Svchost.exe 그룹은 다음 레지스트리 키에서 식별됩니다.
HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Svchost
이 키의 각 값은 별도의 Svchost 그룹을 나타내며 활성 프로세스를 볼 때 별도의 인스턴스로 표시됩니다. 각 값은 REG_MULTI_SZ 값에 해당하며 해당 Svchost 그룹 하에서 실행되는 서비스를 포함하고 있습니다. 각 Svchost 그룹은 Parameters 키에 ServiceDLL 값이 들어 있는 다음 레지스트리 키에서 추출되는 서비스 이름을 하나 이상 포함할 수 있습니다.
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Service
Svchost에서 실행 중인 서비스의 목록을 보려면 다음과 같이 하십시오.
  1. Windows 작업 표시줄의 시작을 누른 다음 실행을 누릅니다.
  2. 열기 상자에 CMD를 입력한 다음 Enter 키를 누릅니다.
  3. Tasklist /SVC를 입력한 다음 Enter 키를 누릅니다.
Tasklist는 활성 프로세스의 목록을 표시합니다. /SVC 스위치는 각 프로세스의 활성 서비스 목록을 표시합니다. 프로세스에 대한 자세한 내용을 보려면 다음 명령을 입력한 후 Enter 키를 누릅니다.
Tasklist /FI "PID eq processID"(따옴표 포함)
다음 Tasklist 예제 출력은 실행 중인 Svchost.exe의 두 인스턴스를 보여 줍니다.
   Image Name         PID      Services
   ======================================================================== 
   System Process        0     N/A
   System                8     N/A    
   Smss.exe            132     N/A
   Csrss.exe           160     N/A
   Winlogon.exe        180     N/A
   Services.exe        208     AppMgmt,Browser,Dhcp,Dmserver,Dnscache,
                               Eventlog,LanmanServer,LanmanWorkstation,
                               LmHosts,Messenger,PlugPlay,ProtectedStorage,
                               Seclogon,TrkWks,W32Time,Wmi
   Lsass.exe            220    Netlogon,PolicyAgent,SamSs 
   Svchost.exe          404    RpcSs 
   Spoolsv.exe          452    Spooler 
   Cisvc.exe            544    Cisvc 
   Svchost.exe          556    EventSystem,Netman,NtmsSvc,RasMan,
                               SENS,TapiSrv 
   Regsvc.exe           580    RemoteRegistry 
   Mstask.exe           596    Schedule 
   Snmp.exe             660    SNMP 
   Winmgmt.exe          728    WinMgmt 
   Explorer.exe         812    N/A
   Cmd.exe             1300    N/A
   Tasklist.exe        1144    N/A
				
이 예제의 두 그룹에 대한 레지스트리 설정은 다음과 같습니다.
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Svchost:
Netsvcs: Reg_Multi_SZ: EventSystem Ias Iprip Irmon Netman Nwsapagent Rasauto Rasman Remoteaccess SENS Sharedaccess Tapisrv Ntmssvc
RApcss :Reg_Multi_SZ: RpcSs





반응형
반응형

Open/Save 파일폴더 경로얻기

 

 

폴더 경로 얻기

int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /*lParam*/, LPARAM lpData);

 

BOOL BrowseForFolder( WCHAR *pwFolderPath, WCHAR *pwInitialFolder )

{

             LPMALLOC pMalloc = NULL;

             WCHAR wszDisplayName [MAX_PATH];

             BROWSEINFO bi;

             BOOL bRet = FALSE;

 

             ZeroMemory(&bi, sizeof(bi));

 

             if ( SUCCEEDED(::SHGetMalloc(&pMalloc)) )

             {           

                          bi.lpszTitle =_T("Title Text");    

                          // 선택된아이템을리턴받을버퍼(폴더명만)

                           bi.pszDisplayName = wszDisplayName; 

                           // Parent Window Handle;

                          bi.hwndOwner = NULL;                  

                           // Callback Function 주소

                          bi.lpfn = BrowseCallbackProc;                                      

                           // Callback Function으로전달한parameter

                          bi.lParam = (LPARAM)pwInitialFolder; 

                           bi.pidlRoot = NULL;

                          // BIF_USENEWUI - 새폴더생성+EditBox

                          // BIF_DONTGOBELOWDOMAIN - nework표시안함

                           bi.ulFlags = BIF_RETURNONLYFSDIRS;

                           bi.iImage = -1;

 

                           LPITEMIDLIST pidl = ::SHBrowseForFolder(&bi);

                           if (pidl != NULL)

                           {

                                        if ( ::SHGetPathFromIDList(pidl, pwFolderPath) ) // Get Item FullPath

                                        {

                                                     bRet = TRUE;

                                        }

 

                                        pMalloc->Free(pidl);

                           }

 

                           pMalloc->Release();

                           pMalloc = NULL;

             }

 

             return bRet;

}

 

int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /*lParam*/, LPARAM lpData)

{

             if (uMsg == BFFM_INITIALIZED)

             {

                           //BROWSEINFO.lParam에서 설정 해준 값이 lpData로넘어온다.

                           // LPARAM으로 path를 넘겨주려면 WParamTRUE,

                           // PIDL을 넘겨주려면 FALSE로 넘겨준다.

                          if ( lpData )
                            
SendMessage
(hwnd, BFFM_SETSELECTION, (WPARAM)TRUE, (LPARAM)lpData);

             }

 

             return 0;

}

n  폴더선택창이 팝업될 때 기본 선택 경로를 설정하려면 BROWSEINFO.lpfn를 등록한 후, 위 예제의 BrowseCallbackProc 와 같이 처리하면 된다.

 

파일 경로 얻기

#include <commdlg.h>
BOOL
GetOpenFilePath( WCHAR *pwFilePath, WCHAR *pwInitialFolder )

{

             OPENFILENAME ofn;

 

             ZeroMemory(&ofn, sizeof(OPENFILENAME));

 

             ofn.lStructSize = sizeof(OPENFILENAME);

             ofn.hwndOwner = NULL;

             // File Filter

             ofn.lpstrFilter = L"Exe Files (*.exe)\0*.exe\0Dll Files (*.dll)\0*.dll\0\0";                     

             ofn.lpstrInitialDir = pwInitialFolder;      // InitialFolder

             ofn.lpstrFile = pwFilePath;     // Default FileName / Output FilePath

             ofn.nMaxFile = MAX_PATH; // The size, in characters, of the buffer pointed to by lpstrFile

             ofn.lpstrDefExt = NULL;           // The default extension

             ofn.lpstrTitle = L"파일을선택하세요"; // Title

             ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_OVERWRITEPROMPT;

 

             //if ( ::GetSaveFileName(&ofn) == FALSE ) Save 파일이름 얻기

             if ( ::GetOpenFileName(&ofn) == FALSE ) // - Open 파일이름 얻기

             {

                           DWORD dw = CommDlgExtendedError();

                  return FALSE;

             }

 

             return TRUE;

}

n  GetSaveFileName()/GetOpenFileName()함수의 상세 에러코드는 GetLastError()가 아닌 CommDlgExtendedError() API를 이용해 확인 해야 한다.

n  여기서 주의해야 할점은 OPENFILENAME.lpstrFile 필드는 디폴트 파일명을 셋팅하는데도 사용되며, 디폴트 파일명을 사용하지 않더라도 버퍼의 첫번째 문자는 널 문자로 설정되어야 한다.
그렇지 않을 경우, FNERR_INVALIDFILENAME(0x00003002)가 발생하여 다이얼로그 생성에 실패한다.(즉 해당 버퍼는 반드시 초기화 되어야 한다.)

 

 

 

Windows Vista 이후의 OS에서는 IFileDialog 인터페이스를 통해, 파일/폴더 이름 얻기가 가능하다.

MSDN에서 [Cmmon Item Dialog]을 키워드로 검색하거나 아래 링크를 확인해 보면 자세한 정보가 기술되어 있다.

n  http://msdn.microsoft.com/en-us/library/bb776913(v=VS.85).aspx

관련 샘플은 아래의 경로에서도 확인 가능하다.

n  C:\Program Files (x86)\Microsoft Visual Studio X.0\VC\atlmfc\src\mfc\dlgfile.cpp

 

반응형
반응형

64bit OS에서 32bit Application 디버깅

 

windbg(x64)로 WOW64환경에서 돌아가는 win32 App를 디버깅하려 하면, 아래와 같은 아주 요상한 콜스택을 보게 된다.

 

이런 경우에는 wow64exts.dll 익스텐션을 이용해서 디버깅 해야하며,

!wow64exts.sw 라고 입력하면 x86 디버깅 모드로 변환되어 콜스택이 정상적으로 표시된다.




물론 windbg(x86)버전으로 디버깅해도 문제 없이 디버깅 가능하다.

 

 

반응형
반응형

WinDbg 명령어정리

Command

option

Desc

종료

q

디버깅 종료

qd

디버깅 종료;연결해제

User-mode : Target Application은 종료되지 않는다.

Kernel-mode : Debugee OS Pending되지 않고 계속해서 동작한다.

디버깅 환경정보

vertarget

타겟 컴퓨터 정보 표시

version

디버그 환경 정보 표시

.lastevent

마지막 디버그 이벤트 정보 표시

||

디버깅 세션 정보 표시

symble & sorurce

.symfix

MS 심볼경로 설정

.sympath

심볼경로 확인/설정

!sym noisy

심볼파일 검색 과정을 출력

!sym quiet

심볼파일 검색 과정을 출력하지 않음

.srcpath

.srcpath+ d:\project

소스경로 설정

.srcnoisy

.srcnoisy 1

소스경로 검색 과정을 출력

모듈

lm

로드된 모듈 표시

lm m nt*

패턴과 일치되는 모듈 표시

v

모듈 상세정보 표시

!lmi

!lmi ntdll.dll

모듈 상세정보 표시

.reload

/f test.sys

심볼을 즉시 로드

/i test.sys

TimeStamp가 맞지 않아도 강제로 심볼 로드

/user

[kd] User symbol load

x

x nt!*

x *!*abc*

x /v nt!NtCreateFile

x /t nt!NtCreateFile

x /n nt!ntCreate*

심볼 타입을 표시.

데이터 타입을 표시

이름순으로 정렬

ln

ln [address]

해당 주소에 근접한 심볼의 정보 표시

!dh

!dh [Option] Address

-f  Display file headers

-s  Display Section Headers

-a  Display all header nformation

displays the headers for the specified image

레지스터

r

레지스터 정보 표시

r $proc

현재 프로세스의 PEB주소( user-mode)

현재 프로세스의 EPROCESS주소( kernel-mode)

r $thread

현재 스레드의 TEB주소( user-mode)

현재 스레드의 ETHREAD주소( kernel-mode)

r $tpid

현재 프로세스 ID(PID)

r $tid

현재 스레드 ID(TID)

언어셈블

u


f

b

언어셈블

언어셈블(함수전체)

언어셈블(ip이전의 8개 명령어)

콜스택

k

[n]

p

b

n

v

f

콜스택 정보표시

함수정보 출력

인자표시

프레임번호

FPO정보 표시

스택 사용량 표시

break point

bp

bp 0x123456

bp 설정

bl

bp 리스트 출력

bc

bc * | [frame_no]

bp 삭제

bd,be

bd * | [frame_no]

bp disable/enable

bm

bm notepad!*Win*

패턴과 일치하는 모든심볼에 bp설정

bu

bu aaa!bbb

로드되지 않은 심볼에 대한 bp설정

ba

특정 주소에 access bp

지역변수

dv

dv modulr!test*

/i

/V

심볼유형과 인자유형 표시

변수저장 위치 표시( register or address )

데이터유형

dt

df _EPROCESS 0xaddr

dt _PEB @$peb

주소를 특정 데이터 형으로 변환해서 표시

Current Process PEB정보 디스플레이

du

dpu



Unicode string 표시

da

dpa

Ansi string 표시

dc

db

dy

!address

!address

!address [address]

dds

dds [Options] [Range]


dds esp esp+100

Display Words and Symbols

esp 부터 esp+100까지의 값을 출력

- callstack이 깨진경우, stack확인의 용도로 사용할 수 있다

프로세스 & 스레드 정보

!peb

PEB(Process Environment Block)표시

!teb

TEB(Thread Environment Block) 표시

~*kb

모든 thread의 콜스택 표시

!gle

API의 마지막 에러코드 표시

실행 제어

t

Trace

~.t

다른 스레드를 중지시킨 상태에서 하나의 statementt 실행

g

p

Step Over

gu

gu


~0 gu

현재함수가 복귀할 때 까지 실행

스레드 0을 제외한 모든 스레드를 freeze

wt

-oR

내부에서 호출된 함수와 함수호출 횟수등의 정보 표시

(특정 API 내부에서 호출되는 함수와 결과를 한눈에 확인 할 수 있다.)

.cxr

컨텍스트 변경

!ready

.thread

!thread

.trap

.process

!process

ed

eb

eb .-6 90 90 90 90 90 90

6byteNOP(0x90)으로 변경

!error

!error [error code]

에러코드 정보표시

 

 

 

 

 

 

Set Exceptions

sxe

 

sxe av(0xc0000005)


sxe ld:[moduleName]


sxe ud:[moduleName]

Set Exceptions

Break when access violation

Break when [module] load

Break when [module] unlod

sxd

sxd av

Disable Break when av(first chance)

Create Dump

.dump

/f  full user-mode dump

/m  minidump

/u  Append date,time,PID

Create Dump File

.writemem

.writemem FileName Range

 

: Range – BaseAddr L”DumpSize”

 

.writemem c:\a.dll 0x00030000 L28000

writes a section of memory to a file

WinDBG 설정

.lines -e

라인정보 표시

.enable_unicode 1

Watch, local변수 창에 유니코드 표시

ed Kd_DEFAULT_MASK 8

Vista이상: DbgPrint출력 활성화

 

반응형

+ Recent posts