반응형

‘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

반응형
반응형

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출력 활성화

 

반응형
반응형
반응형
반응형

ASM Code


* 디버깅할때 자주 보게되는 한눈에 들어오지 않는 asm 코드들을 정리한다.
 

DisAsm

xor eax, eax

  • xor( Exclusive OR) - 두 오퍼랜드의 비트들에 대해 논리 XOR를 수행하여 그 결과를 목적지 오퍼랜드에 저장한다.
  • XOR 연산은 두 값 중 한 값만 참인 경우 참으로 간주하므로 eax값을 0으로 만드는 코드이다.
  • 같은 값을 xor하면 모든 비트가 같으므로 1이 나올수 없다.
  • 결국 mov eax, 0 과 같은 결과가 나온다는 얘기인데, 위와 같은 코드를 사용하는 이유는 xor연산이 cost & opcode size가 작기 때문인듯 하다.
    0041CD4E B8 00 00 00 00   mov         eax,0
    0041CD53 33 C0              xor         eax,eax

mov edi, edi

  • 2byte NOP코드와 같다.
  • XP-SP2이후부터, 함수 prolog의 첫번째 명령으로 추가되었다.
  • 이는 마이크로소프트가 재부팅 없이 패치를 수행(hot-fix)하기 위해 추가한 것으로
    XP-SP2
    이전에는 prolog 2byte(why2?)+이어지는 명령의 2byte를 교체해야 했으나,
    XP-SP2
    이후에는 위의 두바이트 명령이 추가됨으로써 함수의 prolog가 정확히 5바이트로 변경되었으며, 이로 인해 인라인 후킹이 더 쉬워졌다.(다른 코드로의 점프에 필요한 바이트수가 5byte)

jmp WHook!ILT+360(?MyMessageBoxWYGHPAUHWND__PB_W1IZ) (00b3716d)

  • ILT( Incremental Link Table )
    /INCREMENTAL
    옵션을 주어 링크 했을때, 링커는 함수 주소들의 배열(ILT)을 생성한다. 그리고 함수를 호출하기 위해 해당 슬롯을 통해 함수를 직접 호출한다.
    ILT+360은 해당배열의 360번째 슬롯의 주소를 의미한다.

add byte ptr [eax],al

  • 이 명령의 기계어 코드를 보면 0000이다. 이 명령이 반복적으로 계속되는 경우, 유효한 기계어 코드라기 보다는 0으로 채워진 메모리를 디스어셈블러가 이 코드로 번역했다고 보는 게 맞을 거 같다.

pushad

  • 모든 레지스터를 저장

popad

  • 모든 레지스터를 복구

 

Asm 코드 작성

_emit [BYTE]

  • 인자로 넘겨진 바이트들을 직접 기계어 코드로서 삽입

 

 

 

반응형

+ Recent posts