오늘 간만에 드라이버 코드를 좀 만졌습니다. 예전에 만들어 놓은 동적 로딩 가능한 드라이버를 테스트할 일이 생겼거든요. ㅎㅎ 반응 속도가 굉장히 빨라야 한다고 해서 허접한 드라이버에 큐도 집어넣고, 나름 동기화도 처리하려고 뮤텍스를 사용했습니다.

그러다 보니 어느새 드라이버가 재부팅 되기 시작했습니다. 한참을 디버깅한 후에 알아내긴 했는데, 내가 이러고도 멀티코어 OS를 만든다고 할 수 있나 하는 생각이 들더군요. 코어 2개가 동작하니 싱글코어 일때 보다 더 Lock/Unlock 범위를 신경썼어야 하는데… ㅠㅠ 크윽... 역시 아직 멀었나 봅니다. 아주 기본적인 것 조차 헷갈리고 있으니... 이거 원 ㅎㅎ

덕분에 오늘 반성의 시간을 좀 가졌네요. 에혀... 역시 아직 멀었습니다. ㅠㅠ

밤이 늦었으니 오늘은 이만… ㅎㅎ 다들 좋은 밤 되세요 ㅠㅠ)-b

 오늘 RSS를 돌다가 Orange.net(http://0range.net/entry/%EC%88%A8%EC%96%B4%EC%9E%88%EB%8A%94-%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84-%EC%B0%BE%EB%8A%94-%EB%B0%A9%EB%B2%95)에서 재미있는 글을 발견해서 스크랩해놓습니다.

 드라이버 링크(PsLoadedModuleList)에서 자신을 끊어내버리고 숨어있는 드라이버를 찾아내는 방법에 대한 내용인데요, 드라이버가 존재하는 디렉토리(\\Driver)를 검색해서 찾아내는 방법입니다.



  평소에 드라이버를 숨길 일도, 찾아낼 일도 없어서 잘 모르고 있었는데, 꽤나 기발한 것 같군요. 하지만 ZwQueryDirectoryObject 함수를 후킹하면 좀 효용이 떨어지겠군요. ^^;;;;

 자세한 내용은 http://blog.csdn.net/DryFisHH/archive/2008/02/16/2098545.aspx 에서 보실 수 있습니다. ㅎㅎ
 그럼 좋은 주말 보내세요 ;)

 
 오래 간만에 필터 드라이버를 사용할 일이 생겼습니다. 구석에 짱박힌 소스를 꺼내서 설치한 후 테스트해보니... 얼래... 또 키보드 마우스에 아무런 반응이 없습니다. 이런 경우 눈 앞이 캄캄해지고 정신적으로 공허해져서 믿고 싶지 않은 상태가 되는데... 그래도 오늘은 비교적 일찍 정신이 들더군요.

 사실 어제부터 분석하기 시작했지만... ㅡ_ㅡa... 답이 쉽게 안나왔습니다. 그래서 다시 처음부터 하나하나 드라이버 상태를 관찰해가면서 진행한 결과... 빙고~!!!! 다시 잘 동작하는 키보드 마우스 필터 드라이버를 완성했습니다. >ㅁ<)-b 이거 쓸일은 별로 없는데... 괜시리 시간만 투자하는게 아닌가 싶기도 하군요. ^^;;;;

 필터 드라이버 수정하기가 점점 더 힘들어지는 것 같습니다. 그래도 이렇게 나마 감을 잃지 않고 있으니 다행이네요. ㅎㅎ 요즘은 64bit OS의 늪에 빠져서 헤어나오지 못하는지라 ㅎㅎ

 아웅~ 오늘은 이만자고, 내일은 64Bit OS에 어플리케이션을 올리는 방법에 대해 생각해봐야겠습니다. 사실 이 정도만 하면 거의 끝난거나 마찬가니지... 언능하고 끝내야겠습니다. ;)

 그럼 이만~!!! 다들 좋은 밤 되세요 ;)

 Immunity Debugger를 만드는 Immunity 사에서 Kernel Exploit 관련 자료들을 공유하고 있습니다. ^^)/~ 원문은 http://immunityinc.com/resources-papers.shtml 에서 보실 수 있습니다.

 아직 보지 않아서 무슨 자료인지는 정확히 알 수 없지만, 제목만 훓어봐도 꽤 괜찮겠다 싶은 내용이 있더군요. 아래는 위 사이트에서 소개한 목차와 내용입니다.
June 11, 2008: Exploiting Kernel Pool Overflows (Kostya Kortchinsky)
ODP

June 11, 2008: The I2OMGMT Driver Impersonation Attack (Justin Seitz)
PDF
ODT

March 28, 2008: The Hacker Strategy (updated for Harvard ABCD meeting)
PDF

February 29, 2008: IO Immunity Style (Sinan Eren)
PDF

January 26, 2008: The Hacker Strategy (S4 SCADA conference keynote)
PDF

January 22, 2008: Going Against The Gradient
PDF
OpenOffice

December 14, 2007: Beyond Fast Flux
OpenOffice (presentation)
PDF

November 23, 2007: Exploit Development with Immunity Debugger
OpenOffice (presentation)

August 10, 2007: Damian Gomez - Intelligent Debugging
PDF (presentation)
Openoffice (presentation)

July 6, 2007: Nicolas Waisman - Understanding and Bypassing Windows Heap Protection
PDF (presentation)
Openoffice (presentation)

July 6, 2007: Justine Aitel - The IPO of 0days
PDF (presentation)
Openoffice (presentation)

April 8, 2007: Dave Aitel - CANVAS Command Line Executer
Openoffice (paper)

April 8, 2007: Kostya Kortchinsky - Macro-Reliability in Win32 Exploits
Openoffice (presentation)

December 6, 2006: Dave Aitel - Remote Language Detection
Openoffice (paper)

August 30, 2006: Dave Aitel - MSRPC Fuzzing
OpenOffice (paper)
OpenOffice (presentation)

February 13, 2006: Dave Aitel - Resilience
PDF
OpenDocument
TGZ source

January 26, 2006: Dave Aitel - Nematodes (updated)
PDF
OpenDocument
VisualSploit Preliminary Flash Demo

September 29, 2005 Dave Aitel - Nematodes
OpenOffice PDF

May 9th, 2005 Dave Aitel - Practical IDS Evasion
OpenOffice

Feb, 28th, 2005 Bas Alberts - Exploiting the PHP_Limit bug
PDF

Jan 29, 2005 Dave Aitel - 0days: How hacking really works
Open Office PDF HTML

Oct 12, 2004 Dave Aitel - The CANVAS Reference Implementation
Open Office

Oct 12, 2004 Dave Aitel - Advanced Ordnance 2
Open Office PDF

August 12, 2004 Dave Aitel - Microsoft Windows, a lower Total Cost of Ownership
Open Office    |   PDF

June 21, 2004 Dave Aitel - Beyond Best Practices (Given at OWASP AppSec 2004)
Open Office

May 19, 2004 Dave Aitel - Rapid Application Development in Linux using pyGTK
Open Office

March 1, 2004 Dave Aitel - Enterprise Secific Software Security Issues:
Open Office

Feb 4, 2003 The Advantages of Block-Based Protocol Analysis for Security Testing:
Open Office   |    HTML   |    Text   |    Post Script   |    PDF

July 29, 2002 Using SPIKE 101
Power Point   |    Real Media

Feb 24, 2003 - Vivisection of an Exploit Development Process
Power Point   |    Real Media

May 1, 2003 - Windows Exploitation for Unix Hackers
Power Point

Sep 29, 2003 - MOSDEF
Power Point

Jan 27, 2004 - Advanced MOSDEF
Open Office

March 1, 2003 Nicolas Waisman - Linux Heap Overflow Techniques
Power Point

Sep 12, 2003 Microsoft Heap Overflows I/II
PDF    |   Open Office

Sep 12, 2003 Microsoft Heap Overflows II/II
PDF    |   Open Office

 완전 득템이군요. ^^;;; 그럼 즐거운 주말 보내시길~ ;)


 흑흑... 이게 얼마만인지 모르겠습니다. ㅜ_ㅜ)-b 쌩판 모르는 상태로 HID 드라이버를 손보기 시작해서 키보드와 마우스를 생성하기까지 한참 걸렸고, 보안 프로그램에 걸려서 이걸 피해 가는데 또 한참 걸렸네요.

 ㅜ_ㅜ 아아~ 진짜 ㅡ_ㅡa... 간단히 쓸 수 있는 API를 막아놔서 다른 방법을 찾는다고 고생했습니다.  ㅜ_ㅜ 제가 아는 범위에서 테스트 안해본 케이스가 거의 없을 정도로 오만가지를 다 썼는데... 결국 간단한 아이디어로 해결... ^^;;; 그것도 놀다가 깜짝 떠올라서... ㅎㅎㅎ(역시 인생은 타이밍~!!!). 아이디어는 어쩔 수 없이 비공개... 왠지 하면 큰일날듯해서 ^^;;;;;

 가상 HID 드라이버가 HID miniport 드라이버이다 보니 이것저것 제약사항이 많더군요. 뭐 하나 제대로 할 수 있는 것도 없고... 툭하면 재부팅되기 일수이고... 평일 저녁시간과 주말 일부를 올인해서 겨우 해결했습니다. 방금 테스트했는데 큰 문제가 없는 것 같네요. ^^)/~~~

 이제 더러워진 드라이버 코드를 좀 정리하고, 약간 테스트만 더하면 끝날 것 같습니다. 어휴~ 이번 주는 따로 스케줄이 있어서 내일 말고는 시간이 없을 듯한데, 내일 저녁에 완전히 끝내 놓야겠군요. ^^;;;; 어휴... 죽는 줄 알았습니다. 어휴~ 진짜... @0@)/~!!!

 덕분에 HID에 대해서 공부 한번 제대로 했습니다(정말? ㅡ_ㅡa..). 역시 DDK만한게 없군요. 최고입니다. ㅎㅎ DDK 만세~~
 그럼 다들 좋은 밤 되세요 ;)

ps) 이런... ㅡ_ㅡa... 한쪽은 또 다른 수를 써놓았군요. ㅡ_ㅡ;;; 좀 더 파봐야 할 것 같습니다. ㅜ_ㅜ 아우~ 진짜... ㅜ_ㅜ)/~

 아아~ 역시 이거 USB가 만만치 않군요. ㅜ_ㅜ... 잘 모르는 상태에서 시작했던 USB 개발이라... 막히니 해결하는데 시간이 많이 걸리네요. ㅜ_ㅜ...

 가상 USB의 특성상(Bus 드라이버 같은거다보니... ^^;;;) USB API로 드라이버를 찾게되면 맨 상단에 위치한 드라이버가 나오게 되는데... 이걸 직접 찾아서 Open 하려니 드라이버가 또 필요할 것 같고...

 지금 고민에 빠져있는 상태입니다. 일단 간단히 메시지를 보낼 방법을 찾았지만 생각보다 문제가 많더군요. ㅡ_ㅡa... 그래서 결국 다른 방법을 찾아야겠는데... 아아... 이거 원... ^^;;; 결국 드라이버를 하나 더 써야할지...
 
 어찌하면 좋을까요? ㅜ_ㅜ
 좋은 생각 있으신 분 계시나요?


 과로로 며칠 쉬다가 겨우 다시 작업 중입니다. 가상 HID(Virtual HID) 드라이버는 대충 완성됬는데... 글쎄 또 보안 프로그램이 문제군요. ㅡ_ㅡa... 이것 참.... 답답하네요. ㅎㅎ

 다시 오늘부터 열혈 디버깅 들어갑니다. 삽질하다보면 삽이 부러지던지 바닥을 뚫던지 결판이 나겠지요. ;) 아우~ 이거 신경질이 살살 납니다. 이래서야 원... 뭘 할수가 있어야.... 다 만들어 놓고도 써먹질 못하니... ^^;;;;

 이제 또 누가 이기나 해봐야겠군요. ㅎㅎ >ㅁ<)-b

 분석해서 나중에 또 올리겠습니다.

 그럼 다들 좋은 밤 되시길~ ;)


 아우~ 지난주와 이번주, 완전 피곤합니다. ㅜ_ㅜ 만들어 놓았던 필터 드라이버가 특정 상황에서 동작하지 않는 문제가 있어서 디버깅한다고 거의 날밤을 샜습니다. 거짓말 조금 보태서 설치하고 재부팅하고 하는 과정을 거의 200번 정도 한 것 같습니다. ㅜ_ㅜ

 증상 또한 다양했는데... 재부팅이 일어나질 않나, 갑자기 필터 드라이버가 사라지질 않나... 처음에는 프로그램을 잘 못 짠줄 알고 코드를 열심히 수정했습니다. 그런데 가만히 보니 코드의 문제가 아닌 것 같은 느낌이 들어서 다시 커널쪽으로 방향을 틀었습니다.

 역시나... 보안 프로그램이 필터 드라이버의 함수를 수정하거나,  필터 드라이버를 언로딩하고 다시 로딩하는 작업을 수행하더군요. ㅡ_ㅡ;;;; 필터 드라이버가 언로딩 되는 경우는 윈도우가 종료될 때라고 한정하고 있었기때문에 속수무책으로 당했습니다. ㅡ_ㅜ..

 그래서 부랴부랴 언로딩 루틴에 처리하는 부분을 보완하고, 수정된 필터 함수를 좀 손봤더니 잘 되는군요. 내가 쓰겠다는데 왜 내 드라이버를 손보는 것인지... 살짝 기분이 않좋습니다. ㅡ_ㅡa...

 그래도 해결했으니 기분은 좋네요. ^^)/~
 비록 하는 일은 이쪽과 거리가 있지만, 그래도 아직 죽지 않았습니다. @0@)/~!!!


 아흑... 요즘 뜨는 대세가 가상 HID(Virtual HID)라고 해서 잘 모르는 USB Spec을 뒤지면서 작업을 하고 있습니다. 어휴... 이것 참 진짜 어렵네요. ㅜ_ㅜ...

 그래도 어떻게 어떻게 진행해서 키보드와 마우스로 인식시킨 다음 마우스 데이터를 밀어넣는데 성공했습니다. >ㅁ<)/~ ㅎㅎ 신나는 군요. ;)

 HID Report 구조체를 보면서 발견한건데, Mouse의 좌표 값이 상대값이네요. 하긴... 절대값으로 들어올려면 마우스가 지금 어디에 있었고 얼마만큼 움직였는지 알아야하니까 당연히 상대값으로 가는게 맞겠지요. ^^;;;;

 아휴~ 머리를 썼더니 골치가 다 아픕니다. ^^;;; 이거 원... 취미생활은 하나도 못하고 계속 작업만 하고 있군요. ㅜ_ㅜ)/~ 빨리 마무리해야겠습니다.

 그럼 다들 좋은 밤 되시길~ ;)
 간단히 시작했던 작업이 어느새 필터 드라이버를 동적 로딩하는 단계까지 발전했습니다. ㅜ_ㅜ)/~ 이게 어찌된 영문인가 모르겠습니다. ^^;;;;

 기존의 드라이버가 DDK의 소스를 기반으로 만들어졌는데, 정적으로 로딩되서 실행되는 방식이었습니다. 그런데 갑자기 동적 로딩으로 할 수 있게 해달라는 요청이 있어서 소스를 손보기 시작했습니다. 참고로 동적 로딩과 정적 로딩은 아래와 같은 차이가 있습니다. ^^

  • 정적 로딩 : 윈도우 레지스트리에 등록하여 윈도우 시작 시에 자동으로 로드되는 방식
  • 동적 로딩 : 사용자가 요청하면 로딩하는 방식, 일반적으로 시스템 초기화가 완료된 이후에 로딩됨

 처음에는 간단히 동적 로드만 되면 되겠거니 생각했는데, 이게 일이 점점 많아지는 겁니다. ㅜ_ㅜ 키를 입력하게 하는 주요 루틴을 다른 쪽으로 옮겨야 하더군요. 이때부터 작업 로드가 심하게 걸리기 시작했습니다. 잠도 못자고 분석하고 테스트하고... 후덜덜덜...

 정적 로딩하는 버전은 PNP 메시지를 받아서 드라이버가 등록될 때 상위 Driver의 Callback 함수를 가지고 있다가 그걸 강제로 호출해서 값을 넣도록 하는 방식이었는데, 동적 로딩할 때는 PNP 메시지를 받지 못한 상태로 로딩되기 때문에 MJ_READ 에서 이를 처리하도록 해야했습니다. 삽질 끝에 알았습니다. 이런... ㅜ_ㅜ 더불어 IRP를 Cancel해야 다시 읽는 다는 것두요. ^^;;;

 노트북이 없었더라면 작업 시간이 두배 정도 더 걸릴뻔 했습니다. 어휴... 끔찍하네요. ^^;;;;
 방금 테스트를 해봤는데, 정상적으로 동작하는 것 같습니다.
 신나는 주말입니다. ^^)/~

 오늘 테스트하는데 스캔 코드(Scan Code)가 필요해서 찾다보니 아주 깔끔하게 정리된 내용을 발견했습니다. 원문은 http://blog.naver.com/jesuskth?Redirect=Log&logNo=20005262457에서 보실 수 있습니다.

Const SCANKEY_ESC = 1

Const SCANKEY_1 = 2             ' 1
Const SCANKEY_2 = 3             ' 2
Const SCANKEY_3 = 4             ' 3
Const SCANKEY_4 = 5             ' 4
Const SCANKEY_5 = 6             ' 5
Const SCANKEY_6 = 7             ' 6
Const SCANKEY_7 = 8             ' 7
Const SCANKEY_8 = 9             ' 8
Const SCANKEY_9 = 10            ' 9
Const SCANKEY_0 = 11            ' 0
Const SCANKEY_MINUS = 12        ' -
Const SCANKEY_EQUAL = 13        ' =
Const SCANKEY_BS = 14           ' ←

Const SCANKEY_TAB = 15          'TAB
Const SCANKEY_Q = 16            ' Q
Const SCANKEY_W = 17            ' W
Const SCANKEY_E = 18            ' E
Const SCANKEY_R = 19            ' R
Const SCANKEY_T = 20            ' T
Const SCANKEY_Y = 21            ' Y
Const SCANKEY_U = 22            ' U
Const SCANKEY_I = 23            ' I
Const SCANKEY_O = 24            ' O
Const SCANKEY_P = 25            ' P
Const SCANKEY_SQUARE_OPEN = 26  ' [
Const SCANKEY_SQUARE_CLOSE = 27 ' ]
Const SCANKEY_ENTER = 28        ' ENTER

Const SCANKEY_CTRL = 29         ' CTRL
Const SCANKEY_A = 30            ' A
Const SCANKEY_S = 31            ' S
Const SCANKEY_D = 32            ' D
Const SCANKEY_F = 33            ' F
Const SCANKEY_G = 34            ' G
Const SCANKEY_H = 35            ' H
Const SCANKEY_J = 36            ' J
Const SCANKEY_K = 37            ' K
Const SCANKEY_L = 38            ' L
Const SCANKEY_SEMICOLON = 39    ' ;
Const SCANKEY_QUOTATION = 40    ' '

Const SCANKEY_QUOTATION2 = 41   ' `
Const SCANKEY_LSHIFT = 42       ' LEFT SHIFT
Const SCANKEY_WON = 43          ' \

Const SCANKEY_Z = 44            ' Z
Const SCANKEY_X = 45            ' X
Const SCANKEY_C = 46            ' C
Const SCANKEY_V = 47            ' V
Const SCANKEY_B = 48            ' B
Const SCANKEY_N = 49            ' N
Const SCANKEY_M = 50            ' M
Const SCANKEY_COMMA = 51        ' ,
Const SCANKEY_PERIOD = 52       ' .
Const SCANKEY_SLASH = 53        ' /
Const SCANKEY_RSHIFT = 54       ' RIGHT SHIFT

Const SCANKEY_PRTSC = 55        ' PRINT SCREEN SYS RQ
Const SCANKEY_ALT = 56          ' ALT
Const SCANKEY_SPACE = 57        ' SPACE
Const SCANKEY_CAPS = 58         ' CAPS
Const SCANKEY_F1 = 59           ' F1
Const SCANKEY_F2 = 60           ' F2
Const SCANKEY_F3 = 61           ' F3
Const SCANKEY_F4 = 62           ' F4
Const SCANKEY_F5 = 63           ' F5
Const SCANKEY_F6 = 64           ' F6
Const SCANKEY_F7 = 65           ' F7
Const SCANKEY_F8 = 66           ' F8
Const SCANKEY_F9 = 67           ' F9
Const SCANKEY_F10 = 68          ' F10
Const SCANKEY_NUM = 69          ' NUM ROCK
Const SCANKEY_SCROLL = 70       ' SCROLL ROCK

Const SCANKEY_GRAY_HOME = 71    ' 키패드
Const SCANKEY_GRAY_UP = 72
Const SCANKEY_GRAY_PGUP = 73
Const SCANKEY_GRAY_MINUS = 74
Const SCANKEY_GRAY_LEFT = 75
Const SCANKEY_GRAY_CENTER = 76
Const SCANKEY_GRAY_RIGHT = 77
Const SCANKEY_GRAY_PLUS = 78
Const SCANKEY_GRAY_END = 79
Const SCANKEY_GRAY_DOWN = 80
Const SCANKEY_GRAY_PGDN = 81
Const SCANKEY_GRAY_INS = 82
Const SCANKEY_GRAY_DEL = 83

Const SCANKEY_F11 = 87          ' F11
Const SCANKEY_F12 = 88          ' F12


 와우~ 이번에 모 드라이버들이 업데이트가 좀 되서 애를 좀 먹었습니다. ^^;;; 리버싱을 해서 분석하는게 아니라 윈도우 커널이 어떻게 변경되는가를 보고 추측(?)해서 작업하기 때문에 테스트 케이스를 상당히 많이 만들어두는 편입니다.

 어떤 케이스가 무사히 통과할지는 모르는거니까, 상당한 노가다가 필요한 작업이지요. ㅜ_ㅜ)/~ 이거 테스트할려고 오늘 퇴근도 일찍했는데, 나름 보람있군요. ㅎㅎ 잘 돌아가는 걸 확인하고 나니 뿌듯합니다.

 이제 슬슬 정리하고 쉬어야겠습니다. 간만에 머리를 굴렸더니 다리(??)가 아프네요(저도 이유를 모르겠습니다. 이게 무슨... ㅡ_ㅡa...).

ps) 이럴줄 알았으면 툴을 좀 많이 만들어 두는 건데... 이번 주말에 신경 좀 써서 노가다를 피하는 방향으로 좀 가야겠군요. ;)
 분석할 드라이버가 생겨서 당분간 NDS or PSP 홈브루를 개발하기 힘들 것 같습니다. 일단 아웃풋이 나와야해서.. ^^;;;;

 뭐 그리 거창한 것은 아니고, 게임 보안에 관련된 드라이버인데... 원체 실력이 허접한지라 그냥 훓어보는 정도입니다. 예전에 많이 분석하고 배우고 그랬었는데... 그때와는 또 많이 달라졌네요. ㅎㅎ

 예전에 제가 분석할 때는 SDT쪽을 누가 티안나게 잘 훔치는가가 대세였는데... 지금은 한쪽은 SDT를 완전히 포기하고 ntoskrnl쪽을 패치하는 쪽으로 방향을 바꿨고, 다른 한쪽은 아직 SDT쪽에 손을 대고 있더군요. ㅎㅎ

 뭐 어떻게 하고 있는지를 알았으니 이제 파 보는 일만 남았습니다. ㅎㅎ 언능 완료하고 오겠습니다. ;)

 그럼 좋은 밤 되시길~ ^^)/~

ps) 그러고보니 이때까지 분석 드라이버 하나 안가지고 있었군요. 매번 템플릿에 손을 좀 대서 하다보니 귀찮아져서... 이 기회에 만들어둬야겠습니다. ;)


18 Path 관련 Shell API

 원문 :  http://kkamagui.springnote.com/pages/790020

 참고 : http://blog.naver.com/drvoss/20046975128

 

함 수 명

인  자

결  과

PathAddBackslash

c:\path1

c:\path1\

PathBuildRoot

0

A:\

PathCanonicalize

c:\path1\..\.\path1

c:\path1

PathCompactPath

c:\path1\path2\path3\file.txt

c:\path1\...\file.txt

PathFileExists

c:\path1\file.txt

파일의존재유무[T/F]

PathFindFileName

c:\path1\path2\file.txt

file.txt

PathIsDirectory

c:\path1\path2

디렉토리유무[T/F]

PathIsfileSpec

file.txt

순수파일이름인지[T/F]

PathMakePretty

C:\PATH1\FILE.TXT

C:\path1\file.txt

PathIsNetworkPath

\\YHKim\path1\file.txt

네트워크경로인지[T/F]

PathIsRoot

c:\

루트경로인지유무[T/F]

PathIsSystemFolder

c:\windows\System32

시스템폴더인지유무[T/F]

PathRemoveBackslash

c:\path1\path2\

c:\path1\path2

PathRemoveBlanks

“ c:\path1\path2 “

“c:\path1\path2”

PathRemoveExtension

c:\path1\path2\file.txt

c:\path1\path2\file

PathRemoveFileSpec

c:\path1\path2\file.txt

c:\path1\path2

PathRenameExtension

c:\path1\path2\file.txt

c:\path1\path2\file.changed

PathStripPath

c:\path1\path2\file.txt

file.txt

 

관련된 참고할 만한 MSDN Resource
Shell Function들 중 일부 함수들
http://msdn2.microsoft.com/en-us/library/bb776426(VS.85).aspx
Shell Lightweight Utility Functions중 Path와 관련된 함수들
http://msdn2.microsoft.com/en-us/library/bb773559(VS.85).aspx
User Profiles Function중 Path를 얻어 오는데 관련된 함수들
http://msdn2.microsoft.com/en-us/library/aa375109(VS.85).aspx

ps. Path가 등록이된 파일을 찾고 싶다면, SearchPath를 이용하면 FullPath가 넘어 온다.
Qus) 클라이언트 컴퓨터에 설치된 firefox의 경로를 찾고 싶은데 어떻게 하지? Firefox가 써 놓은 레지스터리값를 뒤져볼까? firefox의 기본 설치 경로에 exe 파일을 createfile해서 판단할까?
Ans) SearchPath를 이용하셔서 FullPath를 얻으시고, 얻은 FullPath를 PathFileExists로 검증하시면 됩니다.

이 글은 스프링노트에서 작성되었습니다.

17 User Mode Process Dumper

원문 : http://www.microsoft.com/Downloads/details.aspx?FamilyID=e089ca41-6a87-40c8-bf69-28ac08570b7e&displaylang=en

 

User Mode Process Dumper Version 8.1

Brief Description
Microsoft Support Professionals Toolkit for Windows
The User Mode Process Dumper (userdump) dumps any running Win32 processes memory image on the fly, without attaching a debugger, or terminating target processes.

On This Page

Quick Details
File Name: UserModeProcessDumper8_1_2929_5.exe
Version: 8.1.2929.5
Date Published: 4/4/2007
Language: English
Download Size: 3.5 MB
Estimated Download Time: Dial-up (56K)DSL/Cable (256K)DSL/Cable (768K)T1 (1.5M) 9 min 

Overview

The User Mode Process Dumper (userdump) dumps any running Win32 processes memory image (including system processes such as csrss.exe, winlogon.exe, services.exe, etc) on the fly, without attaching a debugger, or terminating target processes. Generated dump file can be analyzed or debugged by using the standard debugging tools.

The userdump generates dump file by several triggers;
  • Dump by specifying PID or process name from command line
  • Dump automatically when process being monitored caused exceptions
  • Dump automatically when process being monitored exited
  • Dump by pressing hot key sequence


Updates in April 4,2007 (Build 8.1.2929.5)
  • Userdum is now fully compatible with Windows Server 2003 SP2 and Windows XP x64 Edition SP2. Previously, Process Monitoring did not function on SP2 of these operating systems. The same problem also occurred if a hotfix for KB919341 or KB909613 was applied to SP1 of these operating systems. This problem has been fixed.
  • System crash problem on Windows 2000 SP4 has been fixed. Bugcheck 0x1E (BucketID = userdump!ExtractImageFileName+26) could happen when a process monitored by Exit Monitor went to zombie state (the process is not alive but still remains in the system process list) and another process attempted to terminate the process in zombie state. Exit Monitor no longer dumps processes in zombie state in this case as they don’t have any meaningful memory image.
Updates in August 7,2006 (Build 8.1.2929.4)
  • Thread time information is added to the dump file by default so that debugger extension !runaway works.
  • Added all other meaningful MiniDumpWriteDump() options available in dbghelp.dll V6.4.7.1
  • Comment stream is added to the dump file indicating that the dump file was generated by userdump.exe. Comment includes Computer Name and how userdump.exe was launched
  • New userdump.exe -W option is added to add Window handle information. udext.dll debugger extension DLL is provided to see this information by debugger to debug the dump file.
  • EXEs and DLLs are now installed to %windir%\system32\kktools\ folder and this location is added to system path.
  • Userdump.exe is linked with dbghelp.dll dynamically for x86, too. You now need userdump.exe and dbghelp.dll provided with userdump.exe even in command line mode. The same dbghelp.dll is also installed for full-featured mode.
  • Userdump.exe no longer uses system provided dbghelp.dll on x64 and IPF. Instead, dbghelp.dll provided with userdump is always used on all platforms – x86, x64, and IPF.
  • Process Monitoring and Hot Key snapshot support long process names up to 32 bytes.
  • Process Monitoring supports "Switch the dumper" option to specify an alternative dumper such as sqldumper.exe.
  • Process Exit Monitoring supports dumping both a process being killed and a process who called NtTerminateProcess() in the cross-process termination scenario.
  • Process Exit Monitoring allows to specify either Complete minidump, Small minidump, or No dump .
  • Process Exception Monitoring allows to specify Complete minidump or Small minidump.
  • Process Exception Monitoring can catch exceptions raised by calling RaiseException() in WOW64 processes.
  • Process Exception Monitoring always catches exceptions raised by RaiseException() regardless of "Ignore exceptions that occur inside Kernel32.dll" switch.
  • The control panel applet was refined for better GUI.
  • Non-privileged users can no longer launch the control panel applet.
  • Improved event logging to log at the beginning and the end of dumping and indicates process names/PIDs.

 Top of page

System Requirements

  • Supported Operating Systems: Windows 2000 Service Pack 3; Windows 2000 Service Pack 4; Windows Server 2003; Windows Server 2003 Service Pack 1; Windows Server 2003 Service Pack 2; Windows XP Embedded Service Pack 1; Windows XP Embedded Service Pack 2
You need a debugger tool which support dump file analysis like "Debugging Tools for Windows"

 Top of page

Instructions

  1. If the previous version of the User Mode Process Dumper is installed, you need to uninstall first.

  2. Click the Download button on this page to start the download. Do one of the following:

    1. To start the installation immediately, click Open or Run this program from its current location

    2. To copy the download to your computer for installation at a later time, click Save or Save this program to disk.

  3. To install the User Mode Process Dumper, run the UserModeProcessDumper8_1_2929_5.exe package. After you accept the Software License Terms, all necessary files are copied to the C:\kktools\userdump8.1 folder.

  4. Go to C:\kktools\userdump8.1\Architecture folder or the folder you specified in the previous step, and run setup.exe.

  5. Prior to starting and using the User Mode Process Dumper, please be sure to read the readme.htm file, which is located in the C:\kktools\userdump8.1 folder.

 Top of page

Additional Information

Microsoft and partners are jointly developing tools to improve Windows supportability. This joint-development project started from 1998 and has counted 8th phase already. At phase 8 project, the following partners are participating in the project.
  • Fujitsu Limited.
  • Hitachi, Ltd.
  • Nihon Unisys, Ltd.
  • NTT Data Corporation
  • Toshiba Corporation

Tools are owned and released by Microsoft Corporation under the name of "Microsoft Support Professionals Toolkit for Windows".

 Top of page

 Top of page

 Top of page

 Top of page

 

이 글은 스프링노트에서 작성되었습니다.

15 오디오 드라이버를 이용한 exploit 개발

 원문 : http://coderant.egloos.com/4069321

 

 오디오 드라이버의 취약점을 이용해서 exploit을 개발하는 내용이 담긴 자료이다. 굉장히 흥미로운 내용을 담고 있다.

 

 

이 글은 스프링노트에서 작성되었습니다.

13 안티 크래킹 관련 자료

원문 : http://naggingmachine.tistory.com/136

 

- http://www.woodmann.com/crackz/Miscpapers.htm
- Reverse Engineering Team: http://www.reteam.org/index.html
- rEVERSE: http://ampm.ddns.co.kr/~reverse/
- 여리의 작업실: http://www.zap.pe.kr/
- The Reverse Engineering Community: http://www.reverse-engineering.net/
- Programmers' Tools: tp://www.protools.cjb.net/
- Secure Software Engineering: http://www.secure-software-engineering.com/ (보안 관련 내용들을 온라인 잡지 형태로 배포하는 사이트, 최신의 기술들이 소개되어 있음)
- Security Labs: http://www.websense.com/securitylabs/blog/blog.php?BlogID=66
- OpenRCE Anti Reverse Engineering Techniques Database: http://www.openrce.org/reference_library/anti_reversing
(어셈블리 코드를 직접 예제로 보여주면서 설명해 주는 사이트, 실질적인 코드를 제공)
- Scan of the Month 33: Anti Reverse Engineering Uncovered: http://www.honeynet.org/scans/scan33/nico/index.html (Anti Reverse Engineering 기법을 한 페이지에 잘 정리하였음)
- A Survey of Reverse Engineering Tools: http://www.cs.drexel.edu/~spiros/teaching/CS675/asmrceFINAL.pdf
- The Law and Economics of Reverse Engineering: http://www.yalelawjournal.org/pdf/111-7/SamuelsonFINAL.pdf
- Honeynet Project: http://honeynet.org/alliance/index.html (간단한 프로젝트를 통해서 각종 기법들을 알 수 있도록 유도함)
- Process Stalker: http://www.openrce.org/articles/full_view/12 (프로세스의 실행 경로를 탐색하며 문제를 파악하는 방법)
- OllyDbg: http://ollydbg.de/download.htm

이 글은 스프링노트에서 작성되었습니다.

원문 : http://www.thefengs.com/wuchang/work/courses/cs592_spring2007/ 
 
 지인의 블로그에서 오래전에 Cheating in On-line Games에 대한 링크와 자료들을 봤었는데, 나름 바쁜 일이 있어서 그냥 지나쳤습니다. 오늘 문득 생각이나서 다시 들어가보니 내용이 괜찮다는 덧글이 많이 붙어있더군요. 그래서 한번 읽어볼 겸 올려봅니다.

 온라인 게임용 보안 프로그램(nProtect, XTrap, 헥쉴드, 가드캣 등등)에 관심이 많으신 분들은 읽어보시면 방어 프로그램의 원리를 알 수 있을 겁니다. 창과 방패와 같다는 느낌이 드는군요.
 우수한 방패의 약점을 분석해서 더 우수한 창을 만들고 반대로 우수한 창의 약점을 분석해서 더 우수한 방패를 만들 수 있는 것처럼 해킹과 보안 역시 비슷한 관계가 있는 것이 아닌가 생각해봅니다. ^^;;;

 아래는 원문 사이트의 내용입니다.

Instructor:  

Wu-chang Feng (wuchang at cs dot pdx dot edu)
Office hours: After class
Office location: Fourth Avenue Building Suite 120-17(map)
Web site: http://www.thefengs.com/wuchang/work/courses/cs592
Course e-mail list: http://groups.yahoo.com/group/pdx-cs592
Course e-mail: pdx-cs592 at yahoogroups dot com

Location and Time:
SAB 209, Tuesdays and Thursdays, 2:00pm-3:30pm

Course content:  

  • Lecture 1 (4/3): Introduction (ppt | pdf)
  • Lecture 2 (4/5): On-line PC games and their cheats (ppt | pdf)
  • Lecture 3 (4/10): Software architecture of cheats (slides available through group)
  • Lecture 4 (4/12): Intel's AMT platform (ppt | pdf)
  • Optional class (Gligor lecture at UO) (4/17)
  • Lecture 5 (4/19): Rootkits Chapters 1-3 (ppt | pdf)
  • Lecture 6 (4/24): Rootkits Chapters 4 (ppt | pdf)
  • Lecture 7 (5/1): Rootkits Chapters 5-6 (ppt | pdf)
  • Lecture 8 (5/3): Rootkits Chapters 7-8 (ppt | pdf)
  • Cheat surveys (5/8): RTS | FPS | MMORPG
  • No class (5/10)
  • Lecture 9 (5/15): Rootkits Chapters 9-10 (ppt | pdf)
  • Lecture 10 (5/17): Anti-Debuggers (ppt | pdf)
  • Lecture 11 (5/22): Example Rootkit Rustock.B (paper link | ppt | pdf)
  • Lecture 12 (5/24): Reversing #1 (ppt | pdf | references)
  • Lecture 13 (5/29): Reversing #2 (ppt | pdf | Excerpts from suggested books)
  • Lecture 14 (5/31): System Integrity Services and Obfuscators - Slides:(ppt | pdf) Paper:pdf
  • Final presentations
    • MMO cheats - MMO Glider (Alex Ten): pdf
    • MMO cheats - MMO Glider (Dan Lake): pdf
    • RTS cheats - Genesis/Zerocraft (Wen Sun, Yang Chen): ppt
    • FPS cheats - HL2Hook (Sam Moffatt): odp | pdf

Grading:

  • Phase 2: Survey (Due 5/8) = 40%
  • Phase 3: Cheat disassembly and AMT counter-measure description (Due 6/12) = 60%

'Windows System Application' 카테고리의 다른 글

15 오디오 드라이버를 이용한 exploit 개발  (0) 2008.01.14
13 안티 크래킹 관련 자료  (4) 2007.12.08
01 PE 파일 분석-헤더분석  (2) 2007.11.16
04 System Monitor  (0) 2007.11.15
03 Network Monitor  (2) 2007.11.15

01 PE 파일 분석-헤더분석

 

들어가기 전에...

  • 이 글은 kkamagui에 의해 작성된 글입니다.
  • 마음껏 인용하시거나 사용하셔도 됩니다. 단 출처(https://kkamagui.tistory.com)는 밝혀 주십시오.
  • OS 제작에 대한 상세한 내용은 제가 쓴 책 "64비트 멀티코어 OS 구조와 원리"를 참고하시기 바랍니다.

 

개요

 윈도우 시스템 프로그래밍한다는 사람치고 PE 파일에 대해서 모르는 사람은 아마 거의 없을 것이다. 윈도우 실행 파일 및 DLL, 그리고 드라이버 파일까지도 PE 파일 형태를 따르고 있으니 뭘 해도 따라다니는게 이 PE(Portable Executable) 파일 포맷이니까 말이다. PE 파일 포맷은 크게 헤더, 섹션, 데이터의 세부분으로 나뉘는데 기존 DOS 시절 사용하던 COFF(Common Object File Format)과 거의 비슷한 구조를 가지며 기본 뼈대에서 확장된 듯한 형태를 가진다.

 PE 실행파일이 가지고 있는 헤더를 분석함으로써 실제 데이터가 있는 위치를 파일에서 찾고 해당 영역을 분석할 수 있다.

 PE 파일 구조에 대해서 자세히 알아보기 전에 참고할 좋은 프로그램 몇가지를 소개한다.

  • PE Explorer :  유료다. ㅡ,.ㅡ;;; 공짜 버전도 있는데 30일 한정이라서... 그렇지만 강력하다 @0@)/~
  • PE Browser : 공짜다. 하지만 역시 뭔가 부족하다는 거... 그냥 쓰기에는 괜찮다.

 앞으로 Relative Virtual Address(RVA)라는 용어가 많이 나올텐데, 잠깐 알아보자.

 RVA는 실행파일이 메모리에 로드되었을 때, 그 시작 주소를 0으로 생각하고 계산하는 주소이다. 즉 RVA의 값이 0x40 이고 실행파일이 로드되었을 때, 그 시작위치가 0x1000 이라면 실제 그 영역이 메모리에 로드되었을 때 위치는 0x1040이 된다. 실행파일 시작 위치를 0으로 하는 상대적 주소라는 것만 알면 같단하다. 뒤에 설명하면서 계속 사용될 용어이므로 알아두자. 

RVA

 

PE 파일 포맷 전체 구조

 PE 파일 포맷은 크게 아래와 같이 구성된다.

PE 파일 포맷 구조

 위에서 보는 것과 같이 크게는 붉은 색 부분과  푸른색 부분으로 나눌 수 있다. 붉은 색 부분은 헤더나 데이터가 위치하는 영역의 속성과 크기 등등을 나타내는 정보이고, 푸른 색 부분은 실제 데이터들이 위치하는 영역을 나타낸다.

  • IMAGE_DOS_HEADER : PE 파일의 처음에 위치하며 뒷부분에 DOS에서 실행했을 때,  에러 메시지(This program cannot be run in DOS mode)를 표시하는 스텁(Stub) 코드를 포함하고 있음. MAGIC Number와 다음에 오는 IMAGE_NT_HEADER의 위치를 표시
  • IMAGE_NT_HEADER : PE 파일 포맷에 대한 정보를 포함. 아래의 두 부분으로 구성 
    • IMAGE_FILE_HEADER :  Section의 수 및 속성과 같은 정보 포함
    • IMAGE_OPTIONAL_HEADER : PE 파일에 대한 속성 또는 이미지 베이스와 같은 정보 포함
      • Data Directory : 어떤 영역의 Virtual Address와 Size 정보를 포함
  • IMAGE_SECTION_HEADER : 섹션에 대한 실질적인 정보를 포함
  • Section(섹션) : 실제 데이터가 위치하는 영역

 각 영역에 대해 세부적으로 알아보자.

IMAGE_DOS_HEADER

 IMAGE_DOS_HEADER는 PE 실행파일 첫부분에 위치하며 아래와 같이 WinNT.h에 정의되어 있다.

#define IMAGE_DOS_SIGNATURE                 0x4D5A      // MZ
#define IMAGE_OS2_SIGNATURE                 0x4E45      // NE
#define IMAGE_OS2_SIGNATURE_LE              0x4C45      // LE
#define IMAGE_NT_SIGNATURE                  0x50450000  // PE00

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number <MZ>
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

  크게 주의해서 볼 부분은 실행파일인지 판단하는데 사용되는 e_magic 부분과 다음에 오는 IMAGE_NT_HEADER의 위치를 표시해 주는 e_lfanew 부분이다. 다른 부분은 크게 중요한 정보를 가지고 있지 않으니 일단 패스~

IMAGE_NT_HEADER

 IMAGE_NT_HEADER는 실제 PE 파일 포맷에 대한 정보를 포함하는 헤더로써 IMAGE_FILE_HEADER와 IMAGE_OPTIONAL_HEADER로 구성된다.

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature; <PE00>
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

 IMAGE_NT_HEADER는 위와 같이 Signature와 File 헤더, 그리고 Optional Header로 구성되어있다. Signature는 IMAGE_NT_SIGNATURE 로 <PE00>의 값을 가진다. 그럼 첫번째에 해당하는 FileHeader를 알아보자.

 

IMAGE_FILE_HEADER

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

 IMAGE_FILE_HEADER는 위와 같이 구성된다. 각 항목에 대해서 알아보면 아래와 같다.

  • Machine : CPU ID를 나타내는데, 간단히 보면 Intel 인지, MIPS 인지 등등의 정보가 들어있음
  • NumberOfSections : PE 파일에 포함된 총 섹션의 수를 나타냄
  • TimeDateStamp : 컴파일러 또는 링커가 파일을 생성한 시간. 1970년 1월 1일 GMT 기준으로 지나온 초
  • PointerToSymbolTable :  COFF 파일의 심볼 테이블의 오프셋을 나타냄. 없는 경우가 대부분
  • NumberOfSymbols : 심볼의 개수를 나타냄
  • SizeOfOptionalHeader : 뒤에 이어서 나오는 Optional Header의 크기를 나타낸다. 32Bit/64Bit에 따라서 그 크기가 다름
  • Characteristics : 파일의 특성

 Machine에 대한 매크로는 WinNT.h에 정의되어있는데 아래와 같다. Intel32 or Intel64가 대부분일테니까 위의 파란색만 보면 될것 같다.

#define IMAGE_FILE_MACHINE_UNKNOWN           0
#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5
#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB             0x01c2
#define IMAGE_FILE_MACHINE_AM33              0x01d3
#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1
#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS
#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon
#define IMAGE_FILE_MACHINE_CEF               0x0CEF
#define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE               0xC0EE

 

 다음은 Characteristics에 대한 부분인데 WinNT.h에 아래와 같이 정의되어있다. 역시나 파란색 부분만 보면 될 것 같다.

#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Agressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM                    0x1000  // System File.
#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.

 

IMAGE_OPTIONAL_HEADER

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //
    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;
    //
    // NT additional fields.
    //
    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

 Optional Header는 꽤나 중요한 정보를 가지고 있다. 위에서 보면 알 수 있듯이 PE 파일의 전반적이 내용들에 대한 정보를 포함한다. 항목이 꽤나 많은데 중요한 정보만 추리면 아래와 같다.

  • Magic : Signature로 32Bit의 경우 0x10b를 가짐
  • SizeOfCode : 섹션 중에 IMAGE_SCN_CNT_CODE 속성을 가진 섹션들 전체의 합
  • SizeOfInitializedData : 섹션 중에 IMAGE_SCN_CNT_INITIALIZED_DATA 속성을 가진 섹션들 전체의 합
  • SizeOfUninitializedData : 섹션 중에 IMAGE_SCN_CNT_UNINITIALIZED_DATA 속성을 가진 섹션들 전체의 합
  • AddressOfEntryPoint : Entry Point의 주소. 실제 로더가 제일 먼저 실행할 코드의 시작점
  • BaseOfCode : 코드가 시작되는 상대 주소(RVA)
  • BaseOfData : 데이터가 시작되는 상대 주소(RVA)
  • ImageBase : 이미지가 로딩되는 메모리의 Base 주소. 일반적으로 실행파일의 경우 0x400000(4Mbyte) 위치에 로딩
  • SectionAlignment : 섹션이 정렬되는 크기. PE 파일 자체가 메모리 맵 파일이기 때문에 0x1000(4Kbyte) 보다 크거나 같아야 함
  • SizeOfImage : 모든 섹션들의 합. 이미지 실행을 위해 메모리를 할당해야 하는 총 크기
  • NumberOfRvaAndSizes : 뒤에 오는 DataDirectory의 개수. 무조건 16개
  • Data Directory : 총 16개가 있으며 각 항목은 특정 데이터에 대한 정보를 가지고 있음. 뒤에서 설명

 Magic은 아래와 같이 WinNT.h에 정의되어있다.

#define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC       0x107

 

IMAGE_DATA_DIRECTORY

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

 데이터 디렉토리는 위와 같은 구조로 이루어져있으며 IMAGE_OPTIONAL_HEADER에 총 16개가 있다. 각각에 Index에 대한 매크로는 WinNT.h에 아래와 같이 정의되어있다.

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor

 

 이미지 디렉토리 정보는 굉장히 중요하다. 경우에 따라서 섹션이 합쳐질 수 있기 때문에 통합된 섹션에서 원하는 정보를 찾는 방법은 이미지 디렉토리에 포함된 정보를 이용하는 방법 밖에는 없다. 여러모로 많이 쓰이는 인덱스는 아래와 같은 역할을 한다.

  • IMAGE_DIRECTORY_ENTRY_EXPORT : Export 함수들에 대한 Export Table의 시작 위치와 크기를 나타냄
  • IMAGE_DIRECTORY_ENTRY_IMPORT : Import 함수들에 대한 Import Table의 시작 위치와 크기를 나타냄
  • IMAGE_DIRECTORY_ENTRY_RESOURCE : IMAGE_RESOURCE_DIRECTORY 구조체의 시작 위치를 나타냄
  • IMAGE_DIRECTORY_ENTRY_TLS : Thread Local Storage에 대한 포인터
  • IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG : IMAGE_LOAD_CONFIG_DIRECTORY 구조체애 대한 포인터
  • IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT : IMAGE_BOUND_IMPORT_DESCRIPTOR 구조체의 배열을 가리키는 포인터
  • IMAGE_DIRECTORY_ENTRY_IAT : Import Address Table의 시작 위치를 나타냄

 실제 위의 값중에서 변경하면 OS의 로더에 의해 로딩이 되지 않는 부분이 있는데, 붉은 색으로 표시된 IMAGE_DIRECTORY_ENTRY_TLSIMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 부분이다. 이 부분은 미리 로더가 읽어서 초기 작업을 실행하는 부분이라 이부분이 포함된 영역을 이상하게 조작하게되면 로더가 로딩에 실패하게 된다(PE파일 암호화 과제를 하면서 온몸으로 느꼈다.. ㅡ_ㅡ;;;). 조작을 하려면 신중히 해야될 듯 싶다.

 여기까지 IMAGE_NT_HEADER에 대해서 알아보았다. 일단 지금은 특정영역의 크기와 위치를 표시한다는 정도만 알아놓고 다음으로 넘어가자.

 

IMAGE_SECTION_HEADER

 PE 헤더의 뒷부분에 연속해서 IMAGE_SECTION_HEADER가 위치하게 된다. 섹션은 뒤에 올 코드나 데이터가 위치하는 영역에 대한 구체적인 정보를 포함하고 있으므로 굉장히 중요하다. 섹션의 개수는 앞서 IMAGE_FILE_HEADER에 포함된 NumberOfSections에서 얻을 수 있으며 해당 개수만큼 얻어오면 된다. IMAGE_SECTION_HEADER는 WinNT.h에 아래와 같이 정의되어있다.

#define IMAGE_SIZEOF_SHORT_NAME              8
typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

 

  중요한 항목에 대한 의미는 아래와 같다.

  • VirtualSize : 실제 코드나 데이터 영역의 크기를 표시
  • VirtualAddress : 메모리에 로드되었을 때 RVA를 표시
  • SizeOfRawData : VirtualSize의 크기를 IMAGE_OPTIONAL_HEADER에 포함된 FileAlignment의 단위로 올림한 크기
  • PointerToRawData : 실제 섹션 데이터가 파일 내에 존재하는 오프셋. Virtual Address와 같을 수도 있고 다를 수도 있음
  • Characteristics : 섹션의 속성 표시. 자세한 것은 뒤를 참조

 위의 VirtualSize와 SizeOfRawData는 영역의 크기를 나타낸다는 공통점이 있으나 라운드 업된 크기와 실제 크기를 나타낸다는 차이가 있다. 만약 섹션의 크기를 조작했다면 위의 두부분 모두 손을 봐야 한다.

 Virtual Address와 Pointer To Raw Data의 값이 다를 수 있다고 했는데, 왜그럴까? 이것은 실행 파일의 크기를 줄이기 위해서이다. 만약 로드 되었을 때 크기가 0x2000 정도인 섹션이 있다고 하자. 그런데 이 섹션은 메모리의 값이 초기화 될 필요도 없고 값도 들어있지 않다면? 실행 시에 영역만 할당해주면 끝이라면? 이런 경우라면 굳이 이 섹션이 실행파일에서 영역을 가지고 있을 필요가 없다. 따라서 Virtual Address는 0이 아닌 값을 갖겠지만 파일 내에 위치를 의미하는 Pointer To Raw Data의 값은 0이 된다.

 즉 실제 파일 내에는 존재하지 않는 영역이 생김으로써 Virtual Address와 Pointer To Raw Data의 값이 달라질 수 있으며, 기타 다른 이유로도 충분히 다를 수 있다. 따라서 실행파일을 조작하기위해서는 Pointer To Raw Data의 값을 위주로 작업을 해야 한다.

 Characteristics는 해당 영역의 속성을 나타내는데, WinNT.h에 정의되어있고 아주 흥미로운 값을 가지고 있다.

//      IMAGE_SCN_TYPE_REG                   0x00000000  // Reserved.
//      IMAGE_SCN_TYPE_DSECT                 0x00000001  // Reserved.
//      IMAGE_SCN_TYPE_NOLOAD                0x00000002  // Reserved.
//      IMAGE_SCN_TYPE_GROUP                 0x00000004  // Reserved.
#define IMAGE_SCN_TYPE_NO_PAD                0x00000008  // Reserved.
//      IMAGE_SCN_TYPE_COPY                  0x00000010  // Reserved.
#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.
#define IMAGE_SCN_LNK_OTHER                  0x00000100  // Reserved.
#define IMAGE_SCN_LNK_INFO                   0x00000200  // Section contains comments or some other type of information.
//      IMAGE_SCN_TYPE_OVER                  0x00000400  // Reserved.
#define IMAGE_SCN_LNK_REMOVE                 0x00000800  // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT                 0x00001000  // Section contents comdat.
//                                           0x00002000  // Reserved.
//      IMAGE_SCN_MEM_PROTECTED - Obsolete   0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC          0x00004000  // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL                      0x00008000  // Section content can be accessed relative to GP
#define IMAGE_SCN_MEM_FARDATA                0x00008000
//      IMAGE_SCN_MEM_SYSHEAP  - Obsolete    0x00010000
#define IMAGE_SCN_MEM_PURGEABLE              0x00020000
#define IMAGE_SCN_MEM_16BIT                  0x00020000
#define IMAGE_SCN_MEM_LOCKED                 0x00040000
#define IMAGE_SCN_MEM_PRELOAD                0x00080000
#define IMAGE_SCN_ALIGN_1BYTES               0x00100000  //
#define IMAGE_SCN_ALIGN_2BYTES               0x00200000  //
#define IMAGE_SCN_ALIGN_4BYTES               0x00300000  //
#define IMAGE_SCN_ALIGN_8BYTES               0x00400000  //
#define IMAGE_SCN_ALIGN_16BYTES              0x00500000  // Default alignment if no others are specified.
#define IMAGE_SCN_ALIGN_32BYTES              0x00600000  //
#define IMAGE_SCN_ALIGN_64BYTES              0x00700000  //
#define IMAGE_SCN_ALIGN_128BYTES             0x00800000  //
#define IMAGE_SCN_ALIGN_256BYTES             0x00900000  //
#define IMAGE_SCN_ALIGN_512BYTES             0x00A00000  //
#define IMAGE_SCN_ALIGN_1024BYTES            0x00B00000  //
#define IMAGE_SCN_ALIGN_2048BYTES            0x00C00000  //
#define IMAGE_SCN_ALIGN_4096BYTES            0x00D00000  //
#define IMAGE_SCN_ALIGN_8192BYTES            0x00E00000  //
// Unused                                    0x00F00000
#define IMAGE_SCN_ALIGN_MASK                 0x00F00000
#define IMAGE_SCN_LNK_NRELOC_OVFL            0x01000000  // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE            0x02000000  // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED             0x04000000  // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED              0x08000000  // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED                 0x10000000  // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.

 

  중요한 플래그 별로 의미를 보면 아래와 같다.

  • IMAGE_SCN_CNT_CODE : 섹션에 코드가 포함되어있음. IMAGE_SCN_MEM_EXECUTE와 보통 같이 지정됨
  • IMAGE_SCN_CNT_INITIALIZED_DATA : 섹션이 초기화된 데이터를 포함하고 있음
  • IMAGE_SCN_CNT_UNINITIALIZED_DATA : 섹션이 초기화 되지 않은 데이터를 포함하고 있음
  • IMAGE_SCN_MEM_DISCARDABLE : 섹션이 버려질 수 있음. 한번 사용되고 필요없는 섹션들(relocation 데이터 같은 경우)이 이 속성을 가짐
  • IMAGE_SCN_MEM_SHARED : 섹션이 이 모듈을 사용하는 모든 프로세스에 의해서 공유될 수 있음을 의미
  • IMAGE_SCN_MEM_EXECUTE : 섹션이 실행 가능함
  • IMAGE_SCN_MEM_READ : 섹션이 읽기 가능함
  • IMAGE_SCN_MEM_WRITE : 섹션이 쓰기 가능함

 위의 값을 보면 섹션에 대한 속성이 미리 정의되어있다는 것을 알 수 있다. 즉 데이터 섹션 같은 경우 IMAGE_SCN_MEM_READ/WRITE 속성을 가지고 있으리라 유추할 수 있고, 코드가 포함된 섹션의 경우 IMAGE_SCN_MEM_EXECUTE 속성을 가지고 있다고 유추할 수 있다.

 섹션의 경우 섹션 이름을 가지고 있는데, VC로 실행파일을 만들면 .text, .data, .idata와 같은 이름의 섹션들이 생긴다. 이름 그대로 코드, 데이터와 같은 정보가 포함된 섹션이라는 것을 알 수 있는데, 여기서 속지 말아야 할 것은 섹션 이름은 권장값이므로 섹션 이름으로 섹션이 포함하는 내용을 판단하면 안된다는 것이다. 특히 파일의 크기를 줄이는 릴리즈 옵션 같은 경우는 섹션들이 합쳐져서 하나의 섹션으로 존재하는 경우도 있기 때문에 섹션 이름을 이용해서 찾아서는 안되며 IMAGE_NT_HEADER에 있는 Data Directory의 값을 참조해서 찾도록 해야 한다.

 

실제 구현

 설명이 굉장히 길었다. 이제 실제로 이 헤더 정보를 분석하는 간단한 코드를 작성해 보자. RVA와 PointerOfRawData의 관계를 생각하면 약간 복잡한데, 이것은 추후에 다시 보도록 하고 헤더 정보만 표시해 보자.

 분석하는 클래스를 작성하여 간단히 헤더 정보를 추출하고 이를 화면에 표시하는 테스트 프로그램을 작성하였다.

  • PEAnalyzer.h : PE 파일을 분석하는 클래스의 헤더 파일
  • PEAnalyzer.cpp : PE 파일을 분석하는 클래스의 소스 파일
  • main.cpp : 실제 사용하는 예제

 

 아래는 실행 결과이다.


IMAGE_DOS_HEADER의 값
IMAGE_SECTION_HEADER의 값

 

마치면서...

 지금까지 PE 파일의 헤더 정보에 대해서 알아보았다. 다음에는 실행에 필요한 함수들과 외부로 노출된 함수들을 찾는 것에 대해서 알아보자.

 

2007/10/09 01:00:16 추가 

 아래는 Win CE용 실행파일 헤더를 분석한 부분이다. IMAGE_FILE_HEADER의 Machine 필드 부분이 다른 것을 알 수 있다. 


 

첨부

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

13 안티 크래킹 관련 자료  (4) 2007.12.08
온라인 게임 해킹( Cheating in On-line Games )에 관한 내용 자료들  (0) 2007.11.16
04 System Monitor  (0) 2007.11.15
03 Network Monitor  (2) 2007.11.15
02 Key Launcher  (6) 2007.11.15

04 System Monitor

원문 : http://kkamagui.springnote.com/pages/569963

 

들어가기 전에...

 

 1년 전에 우리 애들과 함께 만든 시스템 감시 프로그램이다. SDT를 Hooking 하여 시스템 전체 프로세스 실행 및 종료를 감시하며 파일 및 폴더 접근을 감시한다. 또한 파일 및 폴더 자동 숨김 기능을 가지고 있어서 중요한 자료를 숨기는데도 그만이다. ^^;;;

 프로토타입으로 개발된 후, 여러 기능을 추가하여 다양한 버전으로 업그레이드 되었다.(System Monitor 만세!!, 우리 애들 만세!!!). System Monitor 프로토타입은 아래와 같은 기능을 가지고 있다.

  • 파일 및 폴더 숨김 기능
  • 파일 및 폴더 접근 제한 및 접근 알림 기능
  • 프로세스 실행 및 종료 모니터링 기능
  • 환경 설정기능

 

 파일_관리자.PNG

<파일 관리자 화면>

 

시스템_모니터링.PNG

<시스템 모니터링 화면>

 

환경설정.PNG

<환경설정 화면>

 

실행파일 : SystemMonitor.zip

주의!! : XP Service Pack 2 사용자가 아니면 재부팅이 될 수 있음!!!. 또한 XP Service Pack 2 사용자일지라도 Anti-Virus(백신) 프로그램에 의해서 재부팅이 유발될 수 있음

버그 리포트 : X... (더이상 개발 안해요 ㅜ_ㅜ)

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

온라인 게임 해킹( Cheating in On-line Games )에 관한 내용 자료들  (0) 2007.11.16
01 PE 파일 분석-헤더분석  (2) 2007.11.16
03 Network Monitor  (2) 2007.11.15
02 Key Launcher  (6) 2007.11.15
01 Virtual Desktop  (8) 2007.11.15

03 Network Monitor

원문 : http://kkamagui.springnote.com/pages/569916

 

들어가기 전에...

 

 

 네트워크 모니터링과 프로그램 테스트 및 디버깅용으로 만든 드라이버 및 프로그램이다. TCP/UDP 패킷을 캡쳐하여 화면에 표시하고 로그를 남겨주는 기능과 강제로 데이터를 송신하는 기능을 갖추고 있다.

 이 프로그램의 기능은 아래와 같다.

  • TCP/UDP 데이터 표시
  • IP/Port 정보 및 해당 포트의 상태정보 표시
  • 드라이버 수정 시 개인 방화벽 또는 네트워크 바이러스 필터로 적용 가능

 

로그화면.PNG

<로그 화면>

패킷_송신.PNG

<패킷 송신 화면>

 

실행파일 : 비공개

버그 리포트 : 비공개

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

01 PE 파일 분석-헤더분석  (2) 2007.11.16
04 System Monitor  (0) 2007.11.15
02 Key Launcher  (6) 2007.11.15
01 Virtual Desktop  (8) 2007.11.15
00 KKAMALENDAR(KKAMAGUI Calendar)  (11) 2007.11.15

02 Key Launcher

원문 :  http://kkamagui.springnote.com/pages/546563

 

들어가기 전에...

 

 내가 사용할 용도로 만든 간단한 단축 키 프로그램이다. 윈도우에서 사용이 그리 잦지 않는 "윈도우 키"를 사용해서 프로그램을 실행할 수 있도록 했다. 커맨드 라인 옵션까지 지원하므로 사용하는데 큰 무리는 없다.

 

 이 프로그램의 기능은 아래와 같다. 

  • F1 ~ F12, A ~ Z, 0 ~ 9 까지의 키 사용 가능 
  • 최대 12개까지 사용 가능
  • 커맨드 라인 옵션 및 윈도우 PATH를 이용한 프로그램 실행 가능
  • 트레이 아이콘 기능 및 프로그램 숨김 기능 

 

단축키.PNG

<실행 화면>

 

 사용방법은 아래와 같다.

  • 시작

    • 프로그램을 더블 클릭한 뒤 트레이 아이콘에 보면 검은색 컴퓨터 모양의 아이콘이 표시되는데, 그것을 왼쪽으로 클릭하면 위와 같은 화면이 표시된다.
  • 키 및 프로그램 or 폴더 등록 

    • 원하는 키를 앞부분의 콤보박스에서 선택하고 뒷부분의 에디트 박스에 실행할 프로그램 명이나 폴더 명을 explorer와 함께 적어주면 실행할 수 있다.
  • 윈도우 숨김 or 표시 

    • 최소화 버튼을 누르면 윈도우가 숨겨지면서 트레이 아이콘으로 이동한다.
    • 윈도우를 다시 표시하고 싶으면 트레이 아이콘에 왼쪽 버튼을 클릭한다. 
  • 프로그램 종료 

    • X 버튼이나 트레이 아이콘을 왼쪽으로 더블클릭한다.

 

실행파일 : KeyLauncher.zip

버그 리포트 : http://kkamagui.tistory.com/94

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

04 System Monitor  (0) 2007.11.15
03 Network Monitor  (2) 2007.11.15
01 Virtual Desktop  (8) 2007.11.15
00 KKAMALENDAR(KKAMAGUI Calendar)  (11) 2007.11.15
60 유용한 팁  (0) 2007.11.14

01 Virtual Desktop

원문 :  http://kkamagui.springnote.com/pages/391434

 

들어가기 전에...

 

 내가 사용할 용도로 만든 가상 데스크탑 프로그램이다. 최대 9개까지 가상화면을 만들어주고 남들한테는 없는 "항상 위" 기능을 가지고 있어서 창을 항상 위에 표시하게 하는 역할을 한다. 문서 작성시에 창을 겹쳐놓고 작업할때 유용하다.

 실행 시에 즉각 트레이아이콘으로 숨겨져서 화면에 아무것도 안보이는 당황(??)스러운 상황도 연출되는데... 일단 나뭇잎 아이콘을 왼쪽으로 더블클릭하면 화면에 표시된다.

 

 이 프로그램의 기능은 아래와 같다.

  • 가상 데스크탑 9개 생성기능
  • 컨트롤 + 알트 + 방향키로 3x3 매트릭스 이동가능. 이동 시에 화면 가운데 현재 창 번호 표시
  • 트레이 아이콘 기능. 트레이 아이콘을 오른쪽 마우스 버튼으로 더블클릭하면 종료 가능. 왼쪽으로 더블 클릭하면 토끼 윈도우 표시.
  • 토끼 윈도우의 좌우 버튼으로 이동 가능
  • 가상 데스크탑 실행 후 윈도우 창에 오른쪽 버튼을 클릭하면 토순이 메뉴와 항상위 메뉴를 추가.
  • 토순이 메뉴를 통해 창 이동 가능. 항상위 메뉴를 통해 항상 위 기능 사용/제거 가능

Virtual_Desktop.PNG

 

 

실행파일 : 가상_데스크탑.zip

버그 리포트 : http://kkamagui.tistory.com/93

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

03 Network Monitor  (2) 2007.11.15
02 Key Launcher  (6) 2007.11.15
00 KKAMALENDAR(KKAMAGUI Calendar)  (11) 2007.11.15
60 유용한 팁  (0) 2007.11.14
10 WinDbg 간단 사용법  (0) 2007.11.14

00 KKAMALENDAR(KKAMAGUI Calendar)

원문 :  http://kkamagui.springnote.com/pages/391432

 

들어가기 전에...

 

 학교에서 텀프로젝트를 해야 한다길래... 뭘 할까 고민하다가 복잡한 일정 때문에 일정관리가 필요해져서 만든 일정관리 프로그램이다.  기능은 아래와 같다.

  • 레인렌더(Rainlendar) 스타일의 나름 깔끔한 화면
  • 일정에 파일을 덧붙여 저장 가능
  • FTP를 통한 파일 업로드/다운로드 및 일정 업로드/다운로드 기능
  • 간단한 메모 저장 기능

 

수정사항

  • Version 1.1 (2008.04.04)

    • 윤달 문제 해결

 KKAMALENDAR.png

 

 실행파일 다운로드 : KKAMALENDAR.zip

 버그 리포트 : http://kkamagui.tistory.com/92

This article was written in springnote.

'Windows System Application' 카테고리의 다른 글

02 Key Launcher  (6) 2007.11.15
01 Virtual Desktop  (8) 2007.11.15
60 유용한 팁  (0) 2007.11.14
10 WinDbg 간단 사용법  (0) 2007.11.14
02 Device Driver Code  (0) 2007.11.14

1.NTSTATUS를 String으로 바꾸기

원문 :  http://kkamagui.springnote.com/pages/370106

 

들어가기 전에...


 

SUMMARY

 Most Kernel Mode API functions return NTSTATUS values. To translate these status values to messages by using the FormatMessage API function, you must reference the NtDLL.dll module in the parameter list.

 

MORE INFORMATION

The following code sample demonstrates how to obtain the system message string.


  1. void DisplayError(DWORD NTStatusMessage)
    {
    LPVOID lpMessageBuffer;
    HMODULE Hand = LoadLibrary("NTDLL.DLL");

    FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_FROM_HMODULE,
    Hand,
    Err,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR) &lpMessageBuffer,
    0,
    NULL );

    // Now display the string.

    // Free the buffer allocated by the system.
    LocalFree( lpMessageBuffer );
    FreeLibrary(Hand);
    }

 

2.DDK에서 문자열 처리 함수 

  • 표준 함수(비권장) 

    • strcpy, wcscpy, strncpy, wcsncpy 
    • strcat, wcscat, strncat, wcsncat
    • sprintf, swprintf, _snprintf, _snwprintf 
    • vsprintf, vswprintf, vsnprintf, _vsnwprintf
    • strlen, wcslen
  • 안전한 유니코드 함수(UNICODE) 

    • RtlStringCbCopyW, RtlStringCchCopyW 
    • RtlStringCbCatW, RtlStringCchCatW 
    • RtlStringCbPrintfW, RtlStringCchPrintfW 
    • RtlStringCbVPrintfW, RtlStringCchVPrintW 
    • RtlStringCbLengthW, RtlStringCchLengthW 
  • 안전한 ANSI 함수 

    • RtlStringCbCopyA, RtlStringCchCopyA 
    • RtlStringCbCatA, RtlStringCchCatA 
    • RtlStringCbPrintfA, RtlStringCchPrintfA 
    • RtlStringCbVPrintfA, RtlStringCchVPrintfA 
    • RtlStringCbLengthA, RtlStringCchLengthA 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

01 Virtual Desktop  (8) 2007.11.15
00 KKAMALENDAR(KKAMAGUI Calendar)  (11) 2007.11.15
10 WinDbg 간단 사용법  (0) 2007.11.14
02 Device Driver Code  (0) 2007.11.14
04 PE 파일 분석-Relocation 분석  (4) 2007.11.14

10 WinDbg 간단 사용법

원문 : http://kkamagui.springnote.com/pages/388856

참고 : "http://0range.net/entry/Windbg을-마스터-하자"

 

들어가기 전에...

 

웹 심볼(Web Symbol) 얻기

 SRV*D:\Symbol\WebSymbol*http://msdl.microsoft.com/download/symbols 를  Symbol Path에 넣으면 웹 심볼을 사용할 수 있다.

 

로드된 모듈 리스트 보기

 lm 명령을 이용하면 된다.

  • lm k : Kernel Mode 모듈 표시
  • lm u : User Mode 모듈 표시
  • lm m : 패턴을 검사하여 해당하는 것만 보여줌 <lm m my*>

 

lkd> lm
start    end        module name
00c80000 00c90000   NateOnHook40u   (export symbols)       C:\Program Files\NATEON\BIN\NateOnHook40u.dll
00cb0000 00cb9000   MgHookDll C (export symbols)       C:\Program Files\LG Software\On Screen Display\MgHookDll.dll
01000000 0106a000   windbg     (pdb symbols)          D:\Symbol\WebSymbol\windbg.pdb\D6EF677AA54441279479F0307F05A8941\windbg.pdb
016a0000 01784000   ext        (export symbols)       C:\Program Files\Debugging Tools for Windows\winext\ext.dll
01790000 017c1000   kext       (pdb symbols)          D:\Symbol\WebSymbol\kext.pdb\6B643FC4E9F94FF4ABA4CEF1FD6F89D61\kext.pdb

 

모듈의 심볼(Symbol) 검사

 x 모듈!패턴 을 입력하면 된다.

lkd> x nt!Ke*
804f8c02 nt!KeQuerySystemTime = <no type information>
804f8c9e nt!KeEnableInterrupts = <no type information>
80500e38 nt!KeSwitchKernelStack = <no type information>
804fad32 nt!KeReadStateProcess = <no type information>
804f9188 nt!KeReleaseInterruptSpinLock = <no type information>

 

데이터 타입(Date Type) 표시

 dt 데이터 타입 을 입력하면 된다.

lkd> dt _EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : Ptr32 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY
   +0x090 QuotaUsage       : [3] Uint4B
   +0x09c QuotaPeak        : [3] Uint4B
   +0x0a8 CommitCharge     : Uint4B

 

 

메모리 덤프(Memory Dump)

 d* 명령들을 이용하면 된다.

  • db : Byte 형식 + Ascii 로 표시
  • dd : 데이터를 4Byte 형식으로 표시

 

lkd> db 8053db18
8053db18  8b ff 55 8b ec 8b 45 08-8b 4d 0c 8b 55 14 89 48  ..U...E..M..U..H
8053db28  0c 8b 4d 10 89 48 10 03-ca 89 48 14 8b 4d 18 83  ..M..H....H..M..
8053db38  c1 fe 89 48 18 8b 4d 1c-89 48 20 66 8b 4d 20 66  ...H..M..H f.M f

 

 

디스어셈블리(Disassembly)

 u 주소 를 이용하면 된다. 특정 함수를 디스어셈블리 하고 싶으면 uf 주소 를 하면 된다.

  • u 주소 : 주소에서 일부분만 디스어셈블리
  • u 주소1 주소2 : 주소1에서 주소 2까지 디스어셈블리

 

lkd> u 8053db18 or uf nt!NtOpenProcess
nt!KeInitializeProfile:
8053db18 8bff             mov     edi,edi
8053db1a 55               push    ebp
8053db1b 8bec             mov     ebp,esp
8053db1d 8b4508           mov     eax,[ebp+0x8]
8053db20 8b4d0c           mov     ecx,[ebp+0xc]

 

메모리 영역 속성 보기(VA Dump)

 !vadump 명령을 사용하면 된다. 만약 특정 메모리의 속성을 보고 싶다면 !vprot 주소 명령을 사용하면 된다.

0:000> !vadump
BaseAddress:       00000000
RegionSize:        00010000
State:             00010000  MEM_FREE
Protect:           00000001  PAGE_NOACCESS

BaseAddress:       00010000
RegionSize:        00001000
State:             00001000  MEM_COMMIT
Protect:           00000004  PAGE_READWRITE
Type:              00020000  MEM_PRIVATE

 

0:000> !vprot 30c191c
BaseAddress: 030c1000
AllocationBase: 030c0000
AllocationProtect: 00000080 PAGE_EXECUTE_WRITECOPY
RegionSize: 00011000
State: 00001000 MEM_COMMIT
Protect: 00000010 PAGE_EXECUTE
Type: 01000000 MEM_IMAGE

 

프로세스 관련

 모든 프로세스를 보기위해서는 !process 0 0 를 입력하면 된다. 디버거를 특정 프로세스에 붙이고 싶으면 .process /i [pid] 를 입력하면 된다.

 

lkd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 8a3a3490  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00780000  ObjectTable: e1001c70  HandleCount: 521.
    Image: System

PROCESS 8a184158  SessionId: none  Cid: 03f0    Peb: 7ffdd000  ParentCid: 0004
    DirBase: 17a40020  ObjectTable: e163dd70  HandleCount:  20.
    Image: smss.exe

PROCESS 89df4da0  SessionId: 0  Cid: 0440    Peb: 7ffd5000  ParentCid: 03f0
    DirBase: 17a40040  ObjectTable: e1c6cb18  HandleCount: 626.
    Image: csrss.exe

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

00 KKAMALENDAR(KKAMAGUI Calendar)  (11) 2007.11.15
60 유용한 팁  (0) 2007.11.14
02 Device Driver Code  (0) 2007.11.14
04 PE 파일 분석-Relocation 분석  (4) 2007.11.14
03 PE 파일 분석-Export 분석  (0) 2007.11.14

02 Device Driver Code

원문 :  http://kkamagui.springnote.com/pages/570024

 

들어가기 전에...

 

 

1.CR0 Write Protect Managment Code

  1. //
    // 콘트롤 레지스터 관련 (IA-32 manual vol3, ch 2.5
    //    CR0 (Control Register Zero) 레지스터의 WP 비트(16)는 쓰기 속성제어에 사용됨
    // 
    #define   CR0_WP_MASK     0x0FFFEFFFF
  2.  
  3. /**
     Write Protect를 제거
    */
    VOID  ClearWriteProtect(VOID)

        __asm 
        {   
            push  eax;   
            mov   eax, cr0;   
            and   eax, CR0_WP_MASK; // WP 클리어   
            mov   cr0, eax;   
            pop   eax; 
        }
    }
  4. /**
     Write Protect를 설정
    */
    VOID  SetWriteProtect(VOID)

        __asm 
        {   
            push  eax;   
            mov   eax, cr0;   
            or    eax, not CR0_WP_MASK; // WP 비트 세팅   
            mov   cr0, eax;   
            pop   eax; 
        }
    }

 

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

60 유용한 팁  (0) 2007.11.14
10 WinDbg 간단 사용법  (0) 2007.11.14
04 PE 파일 분석-Relocation 분석  (4) 2007.11.14
03 PE 파일 분석-Export 분석  (0) 2007.11.14
02 PE 파일 분석-Import 분석  (0) 2007.11.14

04 PE 파일 분석-Relocation 분석

원문 :  http://kkamagui.springnote.com/pages/406762

 

들어가기 전에...

 

개요

 지난번에 PE 파일의 헤더구조 및 Import/Export 섹션에 대해서 알아보았다. 잘 기억이 안나면 01 PE 파일 분석-헤더분석 문서 및 02 PE 파일 분석-Import 분석, 그리고 03 PE 파일 분석-Export 분석 문서를 다시 보자.

 일단 들어가기 전에 재배치(Relocation)이 무엇인지 알아보자. 재배치는 코드에 특정 값을 더해줘서 다른 메모리 주소에서 실행 가능하게 해주는 것을 말한다. 말 그대로 코드를 다시 배치하는 과정인데, 왜 이런걸 해야 하는 걸까?

 EXE 파일의 경우 윈도우에서는 굳이 재배치를 할 필요가 없다. 왜냐하면 로더가 프로그램을 로딩할때 제일 먼저 EXE 파일을 위한 메모리를 할당해주기 때문이다. IMAGE_OPTIONAL_HEADER에 ImageBase라는 필드를 기억할지 모르겠다. 이것이 바로 PE 파일이 로딩될 Base 주소를 의미한다. EXE 파일의 경우 가장 먼저 메모리를 할당 받으므로 ImageBase(일반적으로 0x400000)에 로딩 가능하다.

 DLL의 경우는 어떨까? 실행파일이 사용하는 DLL이 어디 한두개일까? 여러개가 로딩이 되면 당연히 그중에 몇몇 DLL은 ImageBase에 로딩하지 못하는 경우도 발생한다. 이때 어쩔 수 없이 다른 메모리 주소에서 실행해야하는데 이 과정을 재배치 과정이라고 하고 재배치 섹션의 정보가 사용되는 것이다.

 이제 세부 구조에 대해서 알아보자

 

재배치 섹션의 시작

 재배치 정보는 다른 정보와 마찬가지로 IMAGE_OPTIONAL_HEADERData Directory에서 찾을 수 있고 0x05 인덱스(IMAGE_DIRECTORY_ENTRY_BASERELOC)에서 그 RVA를 구할 수 있다.

 재배치 섹션의 처음 시작은 IMAGE_BASE_RELOCATION 구조체로 시작하며 WinNT.h에 아래와 같이 정의되어있다.

  1. typedef struct _IMAGE_BASE_RELOCATION {
        DWORD   VirtualAddress;
        DWORD   SizeOfBlock;
    //  WORD    TypeOffset[1];
    } IMAGE_BASE_RELOCATION;
    typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

 각 항목은 위와 같이 정의되어있고 아래와 같은 의미를 가진다.

  • VirtualAddress : 재배치가 수행될 메모리 상의 RVA.
  • SizeOfBlock : 재배치 영역의 크기. IMAGE_BASE_RELOCATION 자신 크기를 포함한 전체 크기

 Export 섹션보다 더 간단한 구조를 가진다. 이후에 보면 알겠지만 재배치 데이터 같은 경우 IMAGE_BASE_RELOCATION 구조체 다음에 n개의 WORD 형태로 반복해서 나타나고 그중 하위 0xFFF는 Offset으로 사용된다.

 따라서 재배치할 영역이 크고 넓은 경우 IMAGE_BASE_RELOCATION + n개의 WORD의 형태가 반복되어서 나타나게 된다. 마지막은 역시 데이터가 0인가를 이용하여 판단한다.

 

재배치 정보

 그럼 IMAGE_BASE_RELOCATION 이후에 존재하는 n개의 WORD는 어떤식으로 구성될까?

 상위 4Bit는 재배치 Type으로 사용되며 하위 12Bit는 Offset으로 사용된다. 따라서 코드를 작성한다면 아래와 같이 쓸 수 있을 것이다.

  1. WORD wData;
  2. printf( "Type %X\n", ( wData & 0xF000 ) >> 12 );
  3. printf( "Offset %X\n", wData & 0xFFF );

 Type과 Offset은 아래와 같은 의미를 가진다.

  • Type : 재배치 정보의 타입. 사실 거의 의미가 없고 0일 경우 패딩 데이터
  • Offset : 실제 코드가 재배치 될 영역. VirtualAddress와 더해져서 수정해야할 RVA 값이 됨

 위에서 보듯 실제 코드가 수정되어야 하는 위치는 IMAGE_BASE_RELOCATION의 VirtualAddress와 Offset을 더한 값이 된다. 정말 간단하다.

 여기서 알아두어야 할 점은 Offset이 최대 0xFFF라는 것이다. 즉 4Kbyte까지 커버가 가능하므로 4Kbyte 이상이 되면 다시 IMAGE_BASE_RELOCATION을 만들어서 접근해야 한다.

 이것을 그림으로 보면 아래와 같다.

재배치3.PNG

 

재배치 수행

 위에서 메모리에 어디를 재배치 해야하는가에 대한 정보를 알아보았다. 그럼 과연 그 위치에서 무엇을 해야 정상적으로 동작될까? 개요에서 재배치를 수행하는 이유가 모듈의 시작 위치가 이동되기 때문이라고 했다. 그럼 당연히 이동한 거리만큼 값을 더해줘야 정상적으로 수행이 될 것이라는 것을 알 수 있다.

 재배치를 수행하는 과정은 아주 간단하다. 아래의 순서대로 수행하면 된다.

  1. 재배치가 수행되야 할 곳의 DWORD 값을 읽는다.
  2. 읽은 DWORD 값에서 현재 IMAGE_OPTIONAL_HEADER의 ImageBase를 뺀다. 빼는 순간 코드는 0을 기본 Base 주소로 하는 코드로 변한다.
  3. 뺀 값에 실제로 모듈이 로딩된 메모리 주소를 더한다. 더하는 순간 코드는 실제 모듈이 로딩된 위치에서 정상적으로 수행가능한 코드로 변한다.

 단순한 뺄셈과 덧셈만으로 재배치가 가능하다. 자료 구조가 간단한 만큼 처리 또한 간단하다.

 

실제 구현

 구조가 아주 간단한 만큼 코드도 아주 간단하다. IMAGE_BASE_RELOCATION의 정보가 0일때까지 모든 재배치 정보를 표시한다.

 

 아래는 실행 결과이다.

 재배치1.PNG

재배치2.PNG

 

마치면서...

 간단히 재배치 섹션에 대해서 알아보았다. 아주 심플한 자료구조와 반복된 작업을 수행하면 코드를 어디서든 실행가능하게 할 수 있다는 놀라운 사실을 알게 됬으니, 이제 실행 코드를 임의의 영역에 메모리를 할당 시키고 실행 시키는 것도 가능 할 것이다(왜 자꾸 말만하면 어둠(??)의 세계 이야기가 나오는지 모르겠다... ㅡ_ㅡ;;;; 이러면 안되는데...).

 다음은 기회가 되면 실행파일을 조작해서 특정한 일을 수행하는 내용을 하려 하는데, 약간 민감한 부분이 잇어서 언제가 될지는 모르겠다.

 

첨부

 

 

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

10 WinDbg 간단 사용법  (0) 2007.11.14
02 Device Driver Code  (0) 2007.11.14
03 PE 파일 분석-Export 분석  (0) 2007.11.14
02 PE 파일 분석-Import 분석  (0) 2007.11.14
00 윈도우 DLL 분석  (1) 2007.11.14

03 PE 파일 분석-Export 분석

원문 :  http://kkamagui.springnote.com/pages/406170#

 

들어가기 전에...

 

개요

 지난번에 PE 파일의 헤더구조 및 Import 섹션에 대해서 알아보았다. 잘 기억이 안나면 01 PE 파일 분석-헤더분석 문서 및 02 PE 파일 분석-Import 분석 을 다시 보자. 이번에 분석할 부분은 PE 파일에 포함된 Export 영역이다.

 Export 영역은 내가 다른 프로그램을 위한 기능을 제공하기위해 노출한 함수 목록이 들어있다. Import 영역과 비슷한 방법으로 IMAGE_NT_HEADER의 Data Directory를 찾아서 0번째 인덱스(IMAGE_DIRECTORY_ENTRY_EXPORT)를 찾으면 Export 섹션을 구할 수 있다. 역시 RVA를 파일 내의 오프셋(Pointer Of Raw Data)로 바꾸는 작업이 필요하다.

 

Export 섹션의 시작

 Export 섹션의 첫번째는 IMAGE_EXPORT_DIRECTORY 구조체로 되어있으며 WinNT.h에 아래와 같이 정의되어있다.

  1. typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;
        DWORD   Base;
        DWORD   NumberOfFunctions;
        DWORD   NumberOfNames;
        DWORD   AddressOfFunctions;     // RVA from base of image
        DWORD   AddressOfNames;         // RVA from base of image
        DWORD   AddressOfNameOrdinals;  // RVA from base of image
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

  각 항목의 역할은 아래와 같다.

  • Name : DLL의 이름을 나타내는 ASCII 문자열. RVA 값
  • Base : 아래에 오는 Address Of Name Ordinals의 시작 서수. AddressOfNameOridianals의 값은 Base의 값을 뺀 형태로 저장.
  • NumberOfFunctions : AddressOfFunctions가 가리키는 RVA 배열의 수
  • NumberOfNames : AddressOfNames가 가리키는 RVA 배열의 수
  • AddressOfFunctions : 함수의 실제 주소가 담긴 RVA 값의 배열. 배열의 인덱스는 아래 AddressOfNameOrdinals에서 구한 값이거나 서수에서 Base 값을 뺀 값
  • AddressOfNames : 함수의 실제 Ascii 문자열이 담긴 RVA 위치값의 배열
  • AddressOfNameOrdinals : 함수의 서수(Ordinal)값의 배열 위치. RVA 값이며 배열은 WORD크기. 실제 해당 함수의 서수는 AddressOfNameOrdinals에서 WORD의 값을 얻은 것에 Base의 값을 더해야 함

 Import 섹션보다 비교적 직관적이고 간단한 구조로 되어있음을 알 수 있다. 이것을 그림으로 보면 아래와 같다.

export2.PNG

 

Export된 함수 주소 찾기

 그럼 함수 이름과 서수를 가지고 어떻게 함수 주소를 찾을 수 있는지 알아보자. 함수의 실제 주소는 AddressOfFunctions 에 저장되어있다. 그럼 해당 함수가 AddressOfFunctions의 어디에 위치하는지 알아야 하는데 함수 이름을 이용해서 찾는 경우와 서수를 이용해서 찾는 경우가 다르다.

1. 함수 이름으로 함수 주소 찾기

 함수 이름은 AddressOfNames 필드를 이용해서 검색하면 함수 이름이 어느 인덱스에 위치하는지 알 수 있다. 이 인덱스로 서수가 들어있는 AddressOfNameOrdinals 에 접근하면 해당 함수 이름의 서수가 얼마인지 알 수 있다( 여기서 서수는 실제 서수값에서 Base를 뺀 상대 서수 값이다). 이 상대 서수값을 가지고 AddressOfFunctions 에 접근하면 함수가 존재하는 실 주소를 알 수 있다.

2. 서수로 함수 주소 찾기

 서수로 함수 이름을 찾는 방법은 아주 간단하다. AddressOfFunction의 함수 주소 인덱스는 서수에서 Base를 뺀 상대 서수값으로 되어있으므로 그냥 Base를 빼서 AddressOfFunction에 접근하면 된다.

3. 참고 : 모든 함수 주소 찾기

함수 이름과 함수 주소를 모두 찾을려면? NumberOfNames 필드 값을 이용해서 해당 Name의 스트링과 서수값을 구하고 그것으로 AddressOfFunctions에 접근하면 모두 구할 수 있다.

 

 아래는 위 3번 방식을 이용해서 간단히 Export된 함수를 Enumeration하는 소스코드이다.

  1. /**
        Export 섹션을 표시한다.
    */
    void DumpExportSection( CPEAnalyzer* pclAnalyzer )
    {
        PIMAGE_EXPORT_DIRECTORY pstImageExportDirectory;
        PIMAGE_NT_HEADERS pstImageNtHeader;
        DWORD dwFileMappedAddress;
        DWORD dwRVA;
        DWORD dwFileOffset;
        DWORD dwNumberOfNameOrdinal;
        DWORD dwOrdinalBase;
        DWORD* pdwAddressRVATable;
        DWORD* pdwNameRVATable;
        WORD* pwOrdinalTable;
        DWORD i;
  2.     pstImageNtHeader = pclAnalyzer->GetImageNtHeaders();
  3.     // Import Section에 대해서 실제 파일 내의 Offset을 얻는다.
        dwRVA = pstImageNtHeader->OptionalHeader.
            DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress;
        if( dwRVA == 0 )
        {
            printf( "\n=== No Export Section ===\n" );
            return ;
        }
  4.     dwFileOffset = pclAnalyzer->GetPointerOfRawDataFromRVA( dwRVA );
        dwFileMappedAddress = ( DWORD ) pclAnalyzer->GetMappingAddress();
        pstImageExportDirectory = ( PIMAGE_EXPORT_DIRECTORY )(
            dwFileMappedAddress + dwFileOffset );
  5.     printf( "\n==== IMAGE_EXPORT_DIRECTORY ====\n" );
  6.     // 실제 Name String을 출력한다.
        dwFileOffset = pclAnalyzer->GetPointerOfRawDataFromRVA( pstImageExportDirectory->Name );
        printf( "Characteristics       0x%X\n", pstImageExportDirectory->Characteristics );
        printf( "TimeDateStamp         0x%X\n", pstImageExportDirectory->TimeDateStamp );
        printf( "MajorVersion          0x%X\n", pstImageExportDirectory->MajorVersion );
        printf( "MinorVersion          0x%X\n", pstImageExportDirectory->MinorVersion );
        printf( "Name                  0x%X [%s]\n", pstImageExportDirectory->Name,
            dwFileMappedAddress + dwFileOffset );
        printf( "Base                  0x%X\n", pstImageExportDirectory->Base );
        printf( "NumberOfFunctions     0x%X\n", pstImageExportDirectory->NumberOfFunctions );
        printf( "NumberOfNames         0x%X\n", pstImageExportDirectory->NumberOfNames );
        printf( "AddressOfNameOrdinals 0x%X\n", pstImageExportDirectory->AddressOfNameOrdinals );
       
        // 모두 다 출력할 준비를 한다.
        dwNumberOfNameOrdinal = pstImageExportDirectory->NumberOfNames;
        dwOrdinalBase = pstImageExportDirectory->Base;
  7.     dwFileOffset = pclAnalyzer->GetPointerOfRawDataFromRVA(
            pstImageExportDirectory->AddressOfFunctions );
        pdwAddressRVATable = ( DWORD* ) ( dwFileMappedAddress + dwFileOffset );
  8.     dwFileOffset = pclAnalyzer->GetPointerOfRawDataFromRVA(
            pstImageExportDirectory->AddressOfNameOrdinals );
        pwOrdinalTable = ( WORD* ) ( dwFileMappedAddress + dwFileOffset );
  9.     dwFileOffset = pclAnalyzer->GetPointerOfRawDataFromRVA(
            pstImageExportDirectory->AddressOfNames );
        pdwNameRVATable = ( DWORD* ) ( dwFileMappedAddress + dwFileOffset );
  10.     // Ordinals를 돌면서 실제 함수 이름과 주소를 찍는다.
        for( i = 0 ; i < dwNumberOfNameOrdinal ; i++ )
        {
            printf( "--- Export Function[%d] ---\n", i );
            // 함수 이름
            if( pdwNameRVATable[ i ] != 0 )
            {
                dwFileOffset = pclAnalyzer->GetPointerOfRawDataFromRVA( pdwNameRVATable[ i ] );
  11.             printf( "Name                  0x%X [%s]\n", pdwNameRVATable[ i ],
                    ( dwFileMappedAddress + dwFileOffset ) );
            }
            else
            {
                printf( "Name                  0x%X []\n", pdwNameRVATable[ i ] );
            }
  12.         // 함수의 서수
            printf( "Ordinal               0x%X [0x%X]\n", pwOrdinalTable[ i ],
                pwOrdinalTable[ i ] + dwOrdinalBase );
  13.         // 함수의 주소
            printf( "Function Address      0x%X\n", pdwAddressRVATable[
                pwOrdinalTable[ i ] ] );
        }   
    }

 

실제 구현

 이제 Export 섹션을 출력해 보자. Import 섹션보다 간단하므로 출력하는데 큰 어려움이 없을 것이다.

 이 코드를 가지고 DLL을 출력해 보면 실제 함수가 있는 Address의 주소가 다른 것들이 보일지도 모른다. 이것은 해당 역할을 하는 함수가 다른 DLL이나 EXE의 함수로 포워드(Forward) 된 것으로 함수의 주소가 text 섹션이 아닌 특정 다른 섹션을 가리킨다. 이 값은 Forward된 dll.Function 형태의 스트링 주소를 가리키고 실제 표시를 해보면 그렇다는 것을 알 수 있을 것이다. 이러한 경우가 발생하면 위의 Function Address를 출력하는 부분을 조금 수정하여 스트링을 찍도록 하면 된다.

 

 아래는 실행한 결과이다.

export1.PNG

 

 

 

 

 

 

 

 

마치면서...

 이제 Import/Export에 대해서 모두 알아보았다. 지금까지 문서를 통해 DLL이나 EXE가 어떻게 다른 DLL이나 EXE의 함수를 호출하고 어떻게 제공하는지 대략적인 감을 잡을 것이라 생각한다. 이를 잘 생각하면 어떻게 내가 원하는 함수만 노출하고 다른 함수들은 노출을 줄일 수 있는가에 대한 부분도 어느정도 감이 올 것이다.

 다음은 DLL에서는 빠지지 않는 재배치(Relocation) 섹션에 대해서 알아보자.

 

첨부

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

02 Device Driver Code  (0) 2007.11.14
04 PE 파일 분석-Relocation 분석  (4) 2007.11.14
02 PE 파일 분석-Import 분석  (0) 2007.11.14
00 윈도우 DLL 분석  (1) 2007.11.14
01 FAT 파일 시스템(File System)  (4) 2007.11.14

02 PE 파일 분석-Import 분석

원문 : http://kkamagui.springnote.com/pages/404563

 

들어가기 전에...

 

개요

 지난번에 PE 파일의 헤더구조에 대해서 알아보았다. 잘 기억이 안나면 01 PE 파일 분석-헤더분석 문서를 다시 보자. 이번에 분석할 부분은 PE 파일에 포함된 Import 영역이다.

 Import 영역은 PE 파일이 실행될 때 외부로부터 당겨와서 사용하는 함수들의 목록이 포함되어있으며, Export 영역은 다른 모듈이 사용할 수 있게 노출해 놓은 함수들이 들어있다.

 일단 Import 영역부터 살펴보자.

 

Import 영역 분석

 Import 영역은 PE 파일내의 특정 섹션에 자리잡고 있으며, IMAGE_OPTIONAL_HEADER의 DataDirectory에서 위치를 찾을 수 있다. DataDirectory내의 인덱스는 0x01이며 IMAGE_DIRECTORY_ENTRY_IMPORT 매크로로 WinNT.h에 정의되어있다. Data Directory가 포함하는 정보는 해당 위치의 RVA 값과 크기 정보 이다.

 분석하는 데이터는 실제 파일의 형태로 되어있으므로, 여기서 부터는 섹션의 RVA와 PointerOfRawData의 값을 이용해서 찾아야 한다. RVA 값을 이용해서 어떻게 실제 섹션 데이터가 있는 파일 내의 위치를 찾을까? 답은 섹션 정보에있는 RVA값과 Virtual Size 그리고 PointerOfRawData의 값을 이용하는 것이다.

 그럼 함수를 하나 만들자. 함수의 원형은 아래와 같이 RVA를 넣어주면 실제 파일에서 존재하는 위치를 계산해 주는 것이다.

  1. DWORD GetPointerOfRawDataFromRVA( DWORD dwRVA );

 

 저 함수를 이용해서 실제 섹션내에 존재하는 Import 섹션의 위치를 찾아보자. 어떻게 해야 할까? Import 섹션은 IMAGE_OPTIONAL_HEADER의 Data Directory[ IMAGE_DIRECTORY_ENTRY_IMPORT ]에서 찾을 수 있다고 했다. Virtual Address를 위 함수에 넣으면 실제 파일내의 Offset을 구할 수 있다.

 Import 섹션은 IMAGE_IMPORT_DESCRIPTOR 구조체로 시작한다. 해당 구조체의 배열 형태로 구성되며 마지막은 NULL 구조체로 되어있어 끝을 표시한다. 아래는 WinNT.h에 정의된 내용이다.

  1. typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        union {
            DWORD   Characteristics;            // 0 for terminating null import descriptor
            DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
        };
        DWORD   TimeDateStamp;                  // 0 if not bound,
                                                // -1 if bound, and real date\time stamp
                                                //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                                // O.W. date/time stamp of DLL bound to (Old BIND)
  2.     DWORD   ForwarderChain;                 // -1 if no forwarders
        DWORD   Name;
        DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
    } IMAGE_IMPORT_DESCRIPTOR;
    typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

  중요 항목에 대한 설명은 아래와 같다

  • OriginalFirstThunkIMAGE_THUNK_DATA 구조체 RVA 주소를 가리킴. 이때 IMAGE_THUNK_DATA는 Import하는 함수 이름이나 서수(Ordinal)를 포함하는 구조체 IMAGE_IMPORT_BY_NAME을 가리킴
  • Name : Import한 DLL의 이름을 담고 있는 ASCII 문자열의 RVA 주소
  • FirstThunk : OriginalFirstThunk와 같이 IMAGE_THUNK_DATA 구조체의 RVA 주소를 가리키지만 PE 파일이 메모리에 맵핑되고 나면 Import 한 DLL 내의 함수 주소가지고 있는 IMAGE_THUNK_DATA를 가리킴

 

 위의 항목을 보면 Import 섹션에 외부로 부터 당겨쓰는 DLL이나 함수 정보를 모두 포함하고 있음을 알 수 있다. 그럼 OriginalFirstThunk 및 FirstThunk가 가리키는 구조체인 IMAGE_THUNK_DATA의 구조는 어떻게 되어있을까?

 WinNT.h에서 IMAGE_THUNK_DATA에 대한 구조체를 보면 아래와 같이 단순한 공용체임을 알 수 있다.

  1. typedef struct _IMAGE_THUNK_DATA64 {
        union {
            ULONGLONG ForwarderString;  // PBYTE
            ULONGLONG Function;         // PDWORD
            ULONGLONG Ordinal;
            ULONGLONG AddressOfData;    // PIMAGE_IMPORT_BY_NAME
        } u1;
    } IMAGE_THUNK_DATA64;
    typedef IMAGE_THUNK_DATA64 * PIMAGE_THUNK_DATA64;
  2. typedef struct _IMAGE_THUNK_DATA32 {
        union {
            DWORD ForwarderString;      // PBYTE
            DWORD Function;             // PDWORD
            DWORD Ordinal;
            DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME
        } u1;
    } IMAGE_THUNK_DATA32;
    typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

 

  공용체이기 때문에 상황에 따라 쓰임새가 다르다는 것을 알 수 있는데, 각 상황에 따라 아래와 같이 해석된다.

  • ForwarderString : 실제 Import 한 함수가 Forwarding된 함수일 경우. Forwarding에 대해서는 Export에서 설명
  • Function : FirstThunk의 경우 메모리에 로딩이 되면 실제 함수 주소를 가리키는 IMAGE_THUNK_DATA의 RVA값을 표시한다고 했는데, 이때 실제 Function의 주소가 포함된 부분
  • Ordinal : Import를 함수 명이 아니라 서수(Ordinal)로 한 경우. 0x80000000 값으로 마스크하면 최 상위 비트를 구할 수 있는데 이것이 1로 셋팅된 경우 서수로 판단
  • AddressOfData : 실제 Import 된 함수의 이름이 포함된 IMAGE_IMPORT_BY_NAME 구조체에 대한 RVA 주소 포함

 위의 공용체를 보면 크게 함수 이름과 서수를 통한 Import가 가능하다는 것을 알 수 있다. 이 말은 곧 export 시에 서수와 함수 이름 모두를 외부로 노출한다는 말인데, 후에 export 섹션을 분석하면서 차차 알아보자.

 이제 살펴볼 마지막은 실제 함수 이름을 포함하는 IMAGE_IMPORT_BY_NAME 구조체이다. 이 구조체는 WinNT.h에 아래와 같이 표시되어있다.

  1. typedef struct _IMAGE_IMPORT_BY_NAME {
        WORD    Hint;
        BYTE    Name[1];
    } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

 각 항목은 아래와 같다.

  • Hint : Import시 서수를 사용하지 않으면 임의로 설정되는 0 base의 숫자, Import 한 함수가 추가될때마다 1씩 증가. 별로 중요한 값은 아닌듯...
  • Name : NULL로 끝나는 Ascii 문자열. 실제 함수 이름을 포함

 

 굉장히 복잡한 구조체들이 얼기설기 엮여있는데, 이것을 메모리 로딩 전의 PE 파일과 메모리 로딩 후의 PE 파일을 비교해서 그림으로 보면 좀 간단하다.

Import3.PNG

<메모리에 로딩 전 PE 파일 구조>

 

 

Import4.PNG

<메모리 로딩 후 PE 파일의 구조>

  Import 섹션을 찾는 순서는 아래와 같다(위 그림을 참조하면서 같이보자).

  1. Data Directory 또는 섹션 헤더에서 Import 섹션의 시작을 찾는다.
  2. 시작부분은 IMAGE_IMPORT_DESCRIPTOR의 구조체로 시작하고 n개가 존재한다. 끝은 구조체의 모든 데이터가 0이면 끝이다.
  3. Name의 RVA를 따라가서 DLL 이름을 뽑는다.
  4. Original First Thunk 또는 First Thunk의 RVA를 따라가서 IMAGE_THUNK_DATA의 구조체 배열에 접근한다. IMAGE_IMPORT_DESCRIPTOR와 마찬가지로 n개가 존재하며 마지막은 구조체의 모든 데이터가 0인지로 판단한다.
  5. IMAGE_THUNK_DATA의 필드 값에 따라 파일명으로 함수를 Import 했는지 서수(Ordinal)로 Import 했는지 판단하여 해당 정보를 뽑는다.

 

실제 구현

 자 이로써 Import 섹션을 분석할 수 있는 모든 조건이 갖추어졌다. 실제 위에서 나온 구조체를 바탕으로 Import 섹션을 한번 분석해 보자.

 주의 할 것은 Borland 사의 링커의 경우 Original First Thunk를 아예 사용하지 않는 다는 것이다. 다행이도 First Thunk 항목은 다 연결되어있으니 First Thunk를 이용해서 덤프하는 것으로 하자. 사실 정확하게 구현을 하려면 Forwarder String까지 해야 하나 예가 드물어서 서수 아니면 함수명이라 가정하고 프로그램을 작성하였다. 혹 문제가 발생하면 ForwarderString 쪽을 처리하면 될 것 같다.

  • PEAnalyzer.h : PE 파일을 분석하는 클래스의 헤더 파일
  • PEAnalyzer.cpp : PE 파일을 분석하는 클래스의 소스 파일
  • main.cpp : 실제 사용하는 예제

 

 아래는 실행 결과이다.

Import1.PNG

<서수(Ordinal)로 Import 한 경우>

Import2.PNG

<이름으로 Import 한 경우>

 

마치면서

 지금까지 PE 파일에서 Import 한 함수들을 분석하는 방법을 알아보았다. Import 섹션은 보안 분야에서 상당히 중요하게 다뤄지고 있는 부분이다. 고전적인 루트킷 같은 경우, 실행 중인 프로세스에 DLL을 삽입하여 Import 섹션의 함수를 후킹해 정보를 빼내는 기능을 하였고, 실행 중인 프로세스에 Import 섹션의 함수를 모니터링 함으로써 후킹을 감시하는 기능도 할 수 있다.

 물론 명시적 로딩(Explicit Loading) 즉 LoadLibrary() 같은 함수를 이용하여 DLL을 로딩하고 함수를 사용하는 경우는 Import 섹션에 데이터가 그리 많이 존재하지 않겠지만 명시적 로딩을 사용하더라도 반드시 2개의 함수 즉 LoadLibrary(), GetProcAddress() 와 같은 함수는 필요하기 때문에 Import 섹션을 분석하는 것은 의미가 있다.

 다음은 Export 섹션에 대해서 알아보도록 하자.

 

첨부

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

'Windows System Application' 카테고리의 다른 글

04 PE 파일 분석-Relocation 분석  (4) 2007.11.14
03 PE 파일 분석-Export 분석  (0) 2007.11.14
00 윈도우 DLL 분석  (1) 2007.11.14
01 FAT 파일 시스템(File System)  (4) 2007.11.14
00 Window I/O 관련  (2) 2007.11.14

+ Recent posts