Microsoft PowerPoint - windbg쉤무2(맋운톬로ífl—로엸엜Callingê·œìŁ½).pptx

Similar documents
hlogin2

No Slide Title

Deok9_Exploit Technique

WinDBG 실무

INTRO Basic architecture of modern computers Basic and most used assembly instructions on x86 Installing an assembly compiler and RE tools Practice co

Microsoft PowerPoint - a8a.ppt [호환 모드]

Microsoft Word - FunctionCall

CKKeyPro 적용가이드

=

PowerPoint 프레젠테이션

Microsoft PowerPoint - a6.ppt [호환 모드]

WinDBG 실무

02.Create a shellcode that executes "/bin/sh" Excuse the ads! We need some help to keep our site up. List Create a shellcode that executes "/bin/sh" C

Microsoft PowerPoint - a2.ppt [호환 모드]

IDA 5.x Manual hwp

Microsoft Word - ExecutionStack

Microsoft Word - Heap_Spray.doc

3.20 테러 악성코드바이너리분석 손충호 (StolenByte) WOWHACKER Group 해당문서는 WOWHACKER Group 의문서이므로, 무단도용및수 정및변조는할수없습니다. 페이지 1 / 20

<BEEEBCC0BAEDB8AEBEEEC1A4B8AE2E687770>

Microsoft PowerPoint - a10.ppt [호환 모드]

Microsoft PowerPoint - a9.ppt [호환 모드]

금오공대 컴퓨터공학전공 강의자료

Microsoft PowerPoint - hy2-12.pptx

WinDBG 실무

°ø±â¾Ð±â±â

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Microsoft Word - building the win32 shellcode 01.doc

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

특허청구의 범위 청구항 1 앵커(20)를 이용한 옹벽 시공에 사용되는 옹벽패널에 있어서, 단위패널형태의 판 형태로 구성되며, 내부 중앙부가 후방 하부를 향해 기울어지도록 돌출 형성되어, 전면이 오 목하게 들어가고 후면이 돌출된 결속부(11)를 형성하되, 이 결속부(11

학습목차 r 컴퓨터본체에서 CPU 의위치살펴보기 r CPU 의성능 r CPU 의기능 r CPU 의조직 r 레지스터의조직 r 명령어사이클 r 명령어파이프라이닝 컴퓨터구조 2 9. CPU 조직과기능

01.The basics technic of Shellcode Excuse the ads! We need some help to keep our site up. List Shellcode The basics of shellcode(ubuntu-16.04) C ASM M

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap01-C언어개요.pptx

Microsoft PowerPoint - chap06-5 [호환 모드]

(Microsoft Word - \270\256\271\366\275\314 \271\370\277\252.doc)

Microsoft PowerPoint - a5a.ppt [호환 모드]

Microsoft PowerPoint - chap06-2pointer.ppt

설계란 무엇인가?

Microsoft PowerPoint - a4.ppt [호환 모드]

PowerPoint Template

12 강. 문자출력 Direct3D 에서는문자를출력하기위해서 LPD3DXFONT 객체를사용한다 LPD3DXFONT 객체생성과초기화 LPD3DXFONT 객체를생성하고초기화하는함수로 D3DXCreateFont() 가있다. HRESULT D3DXCreateFont

목차 1. 소개... 3 가. BOF란?... 3 나. 윈도우 BOF 개발환경및사용툴 Shellcode 작성하기... 4 가. cmd 쉘 ) 소스코드작성 ) 디스어셈블리 ) 어셈블리코드편집 간단

<4D F736F F D20B9D9C0CCB7B5B9D9C0CCB7AFBDBA5FBCF6C1A42E646F63>

01.ROP(Return Oriented Programming)-x86 Excuse the ads! We need some help to keep our site up. List Return Oriented Programming(ROP) -x86 Gadgets - PO

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

Microsoft Word - Static analysis of Shellcode.doc

Microsoft PowerPoint - a4.ppt [호환 모드]

1 1,.,

목 차 1. 개요 취약점분석추진배경 취약점요약 취약점정보 취약점대상시스템목록 분석 공격기법및기본개념 시나리오 공격코드

10-2 삼각형의닮음조건 p270 AD BE C ABC DE ABC 중 2 비상 10, 11 단원도형의닮음 (& 활용 ) - 2 -

API 매뉴얼

(1) 주소지정방식 Address Mode 메모리접근 분기주소 명령어 직접번지 Reg. 지정 Reg. 간접 Base Index 간접 Immediate 상대번지 절대번지 Long 주소 Reg. 간접 Byte Access Bit Access 내부 Data M

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

문서의 제목 나눔고딕B, 54pt

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

Microsoft Word - 1. ARM Assembly 실습_xp2.doc

3. 1 포인터란 3. 2 포인터변수의선언과사용 3. 3 다차원포인터변수의선언과사용 3. 4 주소의가감산 3. 5 함수포인터

제 9 도는 6제어항목의 세팅목표의 보기가 표시된 레이더 챠트(radar chart). 제 10 도는 제 6 도의 함수블럭(1C)에서 사용되는 각종 개성화 함수의 보기를 표시하는 테이블. 제 11a 도 제 11c 도까지는 각종 조건에 따라 제공되는 개성화함수의 변화의

Microsoft Word - Reversing Engineering Code with IDA Pro-4-1.doc

<4D F736F F F696E74202D204B FC7C1B7CEB1D7B7A55F F6E48616E646C6572B8A6C5EBC7D1BFA1B7AFB0CBC3E2B9D7BCF6C1A

(01-16)유형아작중1-2_스피드.ps

Microsoft PowerPoint - ch07 - 포인터 pm0415

PowerPoint 프레젠테이션

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

학습목표 함수프로시저, 서브프로시저의의미를안다. 매개변수전달방식을학습한다. 함수를이용한프로그래밍한다. 2

2015 CodeGate 풀이보고서 김성우 1. systemshock strcat(cmd, argv[1]); 에서스택버퍼오버플로우가발생합니다

저자는 코드나 정보제공에 있어서의 모든 행동에 대해 책임을 지지 않습니다

본 발명은 중공코어 프리캐스트 슬래브 및 그 시공방법에 관한 것으로, 자세하게는 중공코어로 형성된 프리캐스트 슬래브 에 온돌을 일체로 구성한 슬래브 구조 및 그 시공방법에 관한 것이다. 이를 위한 온돌 일체형 중공코어 프리캐스트 슬래브는, 공장에서 제작되는 중공코어 프

hlogin7

ISP and CodeVisionAVR C Compiler.hwp

익스플로잇실습 / 튜토리얼 Easy RM to MP3 Converter ROP [ Direct RET VirtualProtect() 함수사용 ] By WraithOfGhost

Microsoft Word - AntiCrackingTechnique.doc

Reusing Dynamic Linker For Exploitation Author : Date : 2012 / 05 / 13 Contact : Facebook : fb.me/kwonpwn

<BDC3B8AEBEF320B9F8C8A320C0DBBCBA20B7E7C6BEC0BB20BBCCBEC6B3BBBCAD D466F E687770>

17장 클래스와 메소드

03장.스택.key

Microsoft PowerPoint - 00_(C_Programming)_(Korean)_Computer_Systems

Microsoft PowerPoint - Lecture_Note_7.ppt [Compatibility Mode]

Microsoft PowerPoint - additional01.ppt [호환 모드]

untitled

(001~007)수능기적(적통)부속


/* */

쉽게 풀어쓴 C 프로그래밍

9

Data Structure

G5 G25 H5 I5 J5 K5 AVERAGE B5 F5 AVERAGE G5 G24 MAX B5 F5 MIN B5 F5 $G$ $H$25 $G$25 $G$ $H$25 G24 H25 H24 I24 J24 K24 A5 A24 G5 G24, I5

Microsoft Word - Reverse Engineering Code with IDA Pro-2-1.doc

Eureka Mail Client_v2.2.q를이용하여오믈렛에그헌팅에대하여알아볼것이다. 익스플로잇을위해구성된환경은아래와같다. - Windows XP Professional SP3 KOR - Python Ollydbg 1.x, Immunity Debugg

11장 포인터

Cogame 취약점 보고

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

기본자료형만으로이루어진인자를받아서함수를결과값으로반환하는고차함수 기본자료형과함수를인자와결과값에모두이용하는고차함수 다음절에서는여러가지예를통해서고차함수가어떤경우에유용한지를설명한다. 2 고차함수의 예??장에서대상체만바뀌고중간과정은동일한계산이반복될때함수를이용하면전체연산식을간 단

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

슬라이드 1

버퍼오버플로우-왕기초편 10. 메모리를 Hex dump 뜨기 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습

(Microsoft Word - \301\337\260\243\260\355\273\347.docx)

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A634C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

Transcription:

본강의 PDF 는하제소프트다운로드자료실에서받아보실수있습니다 하제소프트 주식회사하제소프트 (www.hajesoft.co.kr) 강사이봉석

과정소개 윈도우응용프로그램, 윈도우서비스프로그램, 윈도우디바이스드라이버를개발하는개발자들로하여금고급디버깅기술을제공하는 윈도우디버거 (WinDBG) 사용방법을익히게하여, 고급시스템프로그래머를양성하는데있습니다 윈도우디버거 (WinDBG) 를사용하는개발자는실무에서고급시스템프로그래머가갖추어야할중요한디버깅지식을습득함과동시에시간과비용을최대한아끼는프로그래밍습관과우수한결과물을만들어낼수있습니다

강사약력 본강사 ( 이봉석 ) 는기업교육 ( 삼성첨단기술센터, LG러닝센터, MDS테크놀러지 ) 과사설교육등에서 13년강사이력을가지고있으며, 현재주식회사하제소프트대표이사를역임하고있습니다. 저서로는, 윈도우디바이스드라이버, 실전윈도우디바이스드라이버, 고급개발자들만이알고있던디바이스드라이버구조와원리, 그리고제작노하우, 실전윈도우 CE 가이드, USB 너뭐니 가있습니다. 주식회사하제소프트는 17년간업체들이필요로하는윈도우디바이스드라이버, 리눅스디바이스드라이버그리고훰웨어를개발, 제공하는업체입니다.

과정진행목차 WinDBG 환경준비 Visual Studio 2015, WDK(Windows Driver Kit), WinDBG WinDBG 심볼설정 마이크로프로세서 Calling 규약 x86 CPU 에서 C 함수호출과어셈블리어연관성분석 x64 CPU 에서 C 함수호출과어셈블리어연관성분석 WinDBG 로칼디버깅 응용프로그램, 서비스프로그램디버깅 BSOD(BlueScreen Of Death) 커널덤프파일 커널덤프파일생성설정및덤프분석 WinDBG 원격디버깅 서비스프로그램, 커널디바이스드라이버디버깅 하드웨어와관련된 WinDBG 주요명령어 PCI, USB 버스를사용하는하드웨어를다룰때, 유용한 WinDBG 확장명령어를소개합니다 WinDBG 확장모듈 확장기능을제공하는모듈구현

2 강 마이크로프로세서 하제소프트 Calling 규약 (Convention) Calling 규약 (Calling Convention) 을배워보도록합니다 디스어셈블리된문맥 ( 코드 ) 을이해하는것은디버깅의기술을한차원올려줍니다 ( 늘고급언어로만볼수는없습니다 ) 디스어셈블리코드는대부분함수의내용이거나함수를호출하는문장으로구성되어있습니다 조금어렵게느껴질수있으니, 부담스러운학생들은함수호출시파라미터전달부분위주로만보세요 ^^

1. x86 과 Calling 규약 x86 CPU에서 C 함수를작성한뒤, 어셈블리어로변환시켜보도록합니다 int main() { int Sum; // 지역변수선언 Sum = SummaryFunction(1, 2); // 1 과 2 를함수에인자로입력 // SummaryFunction 함수의결과를 Sum 지역변수에담습니다 return 0;

1.1 레지스터 x86 CPU에서사용되는대표적인레지스터들입니다 프로그램코드실행위치 eax=00000000 ebx=00000000 ecx=63250000 edx=00000000 esi=00d91b80 edi=00819000 eip=77a0748c esp=007ef488 ebp=007ef4b4 iopl=0 nv up ei pl zr na pe nc <= Flag 레지스터중대표적 cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 Dword (4Bytes) EAX AX Byte AH Word (2Bytes) Byte AL

32비트 하위 16비트 8비트 의미 EAX AX AH, AL Accumulator EBX BX BH, BL Base Register ECX CX CH, CL Count Register EDX DX DH, DL Double Precision Register ESI SI Source Index Register EDI DI Destination Index Register EBP BP Base Pointer Register ESP SP Stack Pointer EIP IP Instruction Pointer Flags Flag Register

1.2 Disassemby 연습 C 코드로작성된예재와이를어셈블리어로번역한내용을서로비교해보도록하겠습니다. 이과정을전부이해하기가곤란한학생들은함수를호출하는부분위주로살펴보면되겠습니다

1.2.1 C 소스코드예재 HRESULT CUserView::CloseView(void) { if (m_fdestroyed) return S_OK; BOOL fviewobjectchanged = FALSE; ReleaseAndNull(&m_pdtgt); if (m_psv) { m_psb->enablemodelesssb(false); if(m_pws) m_pws->viewreleased(); IShellView* psv; HWND hwndcapture = GetCapture(); if (hwndcapture && hwndcapture == m_hwnd) { SendMessage(m_hwnd, WM_CANCELMODE, 0, 0); m_fhandsoff = TRUE; m_frecursing = TRUE; NotifyClients(m_psv, NOTIFY_CLOSING); m_frecursing = FALSE; m_psv->uiactivate(svuia_deactivate); psv = m_psv; m_psv = NULL; ReleaseAndNull(&_pctView);

HRESULT CUserView::CloseView(void) {. if (m_pvo) { IAdviseSink *psink; if (SUCCEEDED(m_pvo->GetAdvise(NULL, NULL, &psink)) && psink) { if (psink == (IAdviseSink *)this) m_pvo->setadvise(0, 0, NULL); psink->release(); fviewobjectchanged = TRUE; ReleaseAndNull(&m_pvo); if (psv) { psv->saveviewstate(); psv->destroyviewwindow(); psv->release(); m_hwndview = NULL; m_fhandsoff = FALSE; if (m_pcache) { GlobalFree(m_pcache); m_pcache = NULL; m_psb->enablemodelesssb(true); CancelPendingActions(); ReleaseAndNull(&_psf); if (fviewobjectchanged) NotifyViewClients(DVASPECT_CONTENT, -1); if (m_psztitle) { LocalFree(m_pszTitle); m_psztitle = NULL; SetRect(&m_rcBounds, 0, 0, 0, 0); return S_OK; 하제소프트

1.2.2 Disassembly HRESULT CUserView::CloseView(void) SAMPLE!CUserView CloseView: 71517134 55 push ebp 71517135 8bec mov ebp,esp [esp+0] = return address [esp+4] = this [ebp+0] = previous ebp pushed on stack [ebp+4] = return address [ebp+8] = this 71517137 51 push ecx 71517138 51 push ecx 71517139 56 push esi 7151713a 8b7508 mov esi,[ebp+0x8] ; esi = this 7151713d 57 push edi ; 임시저장 if (m_fdestroyed) 7151713e 33ff xor edi,edi ; edi = 0 71517140 39beac000000 cmp [esi+0xac],edi ; this->m_fdestroyed == 0? 71517146 7407 jz NotDestroyed (7151714f) ; 같으면 jump return S_OK; 71517148 33c0 xor eax,eax ; eax = 0 = S_OK 7151714a e972010000 jmp ReturnNoEBX (715172c1) ; EBX 레지스터값을스택에서 POP 하지않고 return

BOOL fviewobjectchanged = FALSE; ReleaseAndNull(&m_pdtgt); NotDestroyed: 7151714f 8d86c0000000 lea eax,[esi+0xc0] ; eax = &m_pdtgt 71517155 53 push ebx 71517156 8b1d10195071 mov ebx,[_imp ReleaseAndNull] 7151715c 50 push eax ; ReleaseAndNull() 함수를위한파라미터준비 7151715d 897dfc mov [ebp-0x4],edi ; fviewobjectchanged = FALSE 71517160 ffd3 call ebx ; call ReleaseAndNull if (m_psv) { 71517162 397e74 cmp [esi+0x74],edi ; this->m_psv == 0? 71517165 0f8411010000 je No_Psv (7151727c) ; jump if zero m_psb->enablemodelesssb(false); 7151716b 8b4638 mov eax,[esi+0x38] ; eax = this->m_psb 7151716e 57 push edi ; FALSE 7151716f 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 71517170 8b08 mov ecx,[eax] ; ecx = m_psb->lpvtbl 71517172 ff5124 call [ecx+0x24] ; stdcall EnableModelessSB if(m_pws) m_pws->viewreleased(); 71517175 8b8614010000 mov eax,[esi+0x114] ; eax = this->m_pws 7151717b 3bc7 cmp eax,edi ; eax == 0? 7151717d 7406 jz NoWS (71517185) ; 같다면 jump 7151717f 8b08 mov ecx,[eax] ; ecx = m_pws->lpvtbl 71517181 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 71517182 ff510c call [ecx+0xc] ; stdcall ViewReleased NoWS: HWND hwndcapture = GetCapture(); 71517185 ff15e01a5071 call [_imp GetCapture] ; call GetCapture

if (hwndcapture && hwndcapture == m_hwnd) { SendMessage(m_hwnd, WM_CANCELMODE, 0, 0); 7151718b 3bc7 cmp eax,edi ; hwndcapture == 0? 7151718d 7412 jz No_Capture (715171a1) ; 같으면 jump 7151718f 8b4e44 mov ecx,[esi+0x44] ; ecx = this->m_hwnd 71517192 3bc1 cmp eax,ecx ; hwndcapture = ecx? 71517194 750b jnz No_Capture (715171a1) ; 다르면 jump 71517196 57 push edi ; 0 71517197 57 push edi ; 0 71517198 6a1f push 0x1f ; WM_CANCELMODE 7151719a 51 push ecx ; hwndcapture 7151719b ff1518195071 call [_imp SendMessageW] ; SendMessage No_Capture: m_fhandsoff = TRUE; m_frecursing = TRUE; 715171a1 66818e0c0100000180 or word ptr [esi+0x10c],0x8001 ; 최적화어셈블리된모습. 한번에두값을 TRUE로기록 NotifyClients(m_psv, NOTIFY_CLOSING); 715171aa 8b4e20 mov ecx,[esi+0x20] ; ecx = (CNotifySource*)this.vtbl 715171ad 6a04 push 0x4 ; NOTIFY_CLOSING 715171af 8d4620 lea eax,[esi+0x20] ; eax = (CNotifySource*)this 715171b2 ff7674 push [esi+0x74] ; m_psv 715171b5 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 715171b6 ff510c call [ecx+0xc] ; stdcall NotifyClients

m_frecursing = FALSE; 715171b9 80a60d0100007f and byte ptr [esi+0x10d],0x7f m_psv->uiactivate(svuia_deactivate); 715171c0 8b4674 mov eax,[esi+0x74] ; eax = m_psv 715171c3 57 push edi ; SVUIA_DEACTIVATE = 0 715171c4 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 715171c5 8b08 mov ecx,[eax] ; ecx = vtbl 715171c7 ff511c call [ecx+0x1c] ; stdcall UIActivate psv = m_psv; m_psv = NULL; 715171ca 8b4674 mov eax,[esi+0x74] ; eax = m_psv 715171cd 897e74 mov [esi+0x74],edi ; m_psv = NULL 715171d0 8945f8 mov [ebp-0x8],eax ; psv = eax ReleaseAndNull(&_pctView); 715171d3 8d466c lea eax,[esi+0x6c] ; eax = &_pctview 715171d6 50 push eax ; parameter 715171d7 ffd3 call ebx ; call ReleaseAndNull f (m_pvo) { 715171d9 8b86a8000000 mov eax,[esi+0xa8] ; eax = m_pvo 715171df 8dbea8000000 lea edi,[esi+0xa8] ; edi = &m_pvo 715171e5 85c0 test eax,eax ; eax == 0? 715171e7 7448 jz No_Pvo (71517231) ; jump if zero if (SUCCEEDED(m_pvo->GetAdvise(NULL, NULL, &psink)) && psink) { 715171e9 8b08 mov ecx,[eax] ; ecx = m_pvo->lpvtbl 715171eb 8d5508 lea edx,[ebp+0x8] ; edx = &psink 715171ee 52 push edx ; parameter 715171ef 6a00 push 0x0 ; NULL 715171f1 6a00 push 0x0 ; NULL 715171f3 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 715171f4 ff5120 call [ecx+0x20] ; stdcall GetAdvise 715171f7 85c0 test eax,eax ; test bits of eax 715171f9 7c2c jl No_Advise (71517227) ; 작으면 jump 715171fb 33c9 xor ecx,ecx ; ecx = 0 715171fd 394d08 cmp [ebp+0x8],ecx ; _psink == ecx? 71517200 7425 jz No_Advise (71517227)

if (psink == (IAdviseSink *)this) 71517202 8d46ec lea eax,[esi-0x14] ; eax = -(IAdviseSink*)this 71517205 8d5614 lea edx,[esi+0x14] ; edx = (IAdviseSink*)this 71517208 f7d8 neg eax ; eax = -eax (sets carry if!= 0) 7151720a 1bc0 sbb eax,eax ; eax = eax - eax - carry 7151720c 23c2 and eax,edx ; eax = NULL or edx neg sbb and add r r, r r, (val1 - val2) r, val2 7151720e 394508 cmp [ebp+0x8],eax ; psink == (IAdviseSink*)this? 71517211 750b jnz No_SetAdvise (7151721e) ; 같지않으면 jump m_pvo->setadvise(0, 0, NULL); 71517213 8b07 mov eax,[edi] ; eax = m_pvo 71517215 51 push ecx ; NULL 71517216 51 push ecx ; 0 71517217 51 push ecx ; 0 71517218 8b10 mov edx,[eax] ; edx = m_pvo->lpvtbl 7151721a 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 7151721b ff521c call [edx+0x1c] ; stdcall SetAdvise No_SetAdvise: psink->release(); 7151721e 8b4508 mov eax,[ebp+0x8] ; eax = psink 71517221 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 71517222 8b08 mov ecx,[eax] ; ecx = psink->lpvtbl 71517224 ff5108 call [ecx+0x8] ; stdcall Release No_Advise:

fviewobjectchanged = TRUE; ReleaseAndNull(&m_pvo); 71517227 57 push edi ; &m_pvo 71517228 c745fc01000000 mov dword ptr [ebp-0x4],0x1 ; fviewobjectchanged = TRUE 7151722f ffd3 call ebx ; call ReleaseAndNull No_Pvo: if (psv) { 71517231 8b7df8 mov edi,[ebp-0x8] ; edi = psv 71517234 85ff test edi,edi ; edi == 0? 71517236 7412 jz No_Psv2 (7151724a) ; 같으면 jump psv->saveviewstate(); 71517238 8b07 mov eax,[edi] ; eax = psv->lpvtbl 7151723a 57 push edi ; 멤버함수호출시숨겨진파라미터 "this" 7151723b ff5034 call [eax+0x34] ; stdcall SaveViewState psv->destroyviewwindow(); 7151723e 8b07 mov eax,[edi] ; eax = psv->lpvtbl 71517240 57 push edi ; 멤버함수호출시숨겨진파라미터 "this" 71517241 ff5028 call [eax+0x28] ; stdcall DestroyViewWindow psv->release(); 71517244 8b07 mov eax,[edi] ; eax = psv->lpvtbl 71517246 57 push edi ; 멤버함수호출시숨겨진파라미터 "this" 71517247 ff5008 call [eax+0x8] ; stdcall Release No_Psv2: m_hwndview = NULL; 7151724a 83667c00 and dword ptr [esi+0x7c],0x0 ; m_hwndview = 0

m_fhandsoff = FALSE; 7151724e 83a60c010000fe and dword ptr [esi+0x10c],0xfe if (m_pcache) { 71517255 8b4670 mov eax,[esi+0x70] ; eax = m_pcache 71517258 85c0 test eax,eax ; eax == 0? 7151725a 740b jz No_Cache (71517267) ; 같으면 jump GlobalFree(m_pcache); 7151725c 50 push eax ; m_pcache 7151725d ff15b4135071 call [_imp GlobalFree] ; call GlobalFree m_pcache = NULL; 71517263 83667000 and dword ptr [esi+0x70],0x0 ; m_pcache = 0 No_Cache: m_psb->enablemodelesssb(true); 71517267 8b4638 mov eax,[esi+0x38] ; eax = this->m_psb 7151726a 6a01 push 0x1 ; TRUE 7151726c 50 push eax ; 멤버함수호출시숨겨진파라미터 "this" 7151726d 8b08 mov ecx,[eax] ; ecx = m_psb->lpvtbl 7151726f ff5124 call [ecx+0x24] ; stdcall EnableModelessSB CancelPendingActions(); 하제소프트

71517272 8d4eec lea ecx,[esi-0x14] ; ecx = (CUserView*)this 71517275 e832fbffff call CUserView::CancelPendingActions (71516dac) ; thiscall ReleaseAndNull(&_psf); 7151727a 33ff xor edi,edi ; edi = 0 (for later) No_Psv: 7151727c 8d4678 lea eax,[esi+0x78] ; eax = &_psf 7151727f 50 push eax ; parameter 71517280 ffd3 call ebx ; call ReleaseAndNull if (fviewobjectchanged) 71517282 397dfc cmp [ebp-0x4],edi ; fviewobjectchanged == 0? 71517285 740d jz NoNotifyViewClients (71517294) ; 같으면 jump NotifyViewClients(DVASPECT_CONTENT, -1); 71517287 8b46ec mov eax,[esi-0x14] ; eax = ((CUserView*)this)->lpVtbl 7151728a 8d4eec lea ecx,[esi-0x14] ; ecx = (CUserView*)this 7151728d 6aff push 0xff ; -1 7151728f 6a01 push 0x1 ; DVASPECT_CONTENT = 1 71517291 ff5024 call [eax+0x24] ; thiscall NotifyViewClients NoNotifyViewClients: if (m_psztitle) 71517294 8b8680000000 mov eax,[esi+0x80] ; eax = m_psztitle 7151729a 8d9e80000000 lea ebx,[esi+0x80] ; ebx = &m_psztitle (for later) 715172a0 3bc7 cmp eax,edi ; eax == 0? 715172a2 7409 jz No_Title (715172ad) ; 같으면 jump LocalFree(m_pszTitle); 715172a4 50 push eax ; m_psztitle 715172a5 ff1538125071 call [_imp LocalFree] m_psztitle = NULL; 715172ab 893b mov [ebx],edi ; m_psztitle = 0 No_Title: SetRect(&m_rcBounds, 0, 0, 0, 0); 715172ad 57 push edi ; 0 715172ae 57 push edi ; 0 715172af 57 push edi ; 0 715172b0 81c6fc000000 add esi,0xfc ; esi = &this->m_rcbounds 715172b6 57 push edi ; 0 715172b7 56 push esi ; &m_rcbounds 715172b8 ff15e41a5071 call [_imp SetRect]

return S_OK; 715172be 33c0 xor eax,eax ; eax = S_OK 715172c0 5b pop ebx ; 스택으로부터 restore ReturnNoEBX: 715172c1 5f pop edi ; restore 715172c2 5e pop esi ; restore 715172c3 c9 leave ; 한번에스택으로부터 EBP, ESP레지스터를복원 715172c4 c20400 ret 0x4 ; 호출자로돌아가자마자스택주소값을 4만큼증가한다. Ret + (ESP+4)

1.3 파라미터와지역변수 x86 CPU에서 C 함수가사용하는파라미터와지역변수는다음과같은규칙을사용합니다 지역변수 파라미터 첫번째 [EBP-0xX] [EBP+0x8] 두번째 [EBP-0xN] [EBP+0xC] 세번째 [EBP-0xM] [EBP+0x10] 4 바이트씩증가합니다 지역변수는 [EBP-XX] 형태를가집니다. 하지만, 사용되는 XX 값은정해진규칙이없습니다 함수파라미터는 [EBP+XX] 형태를가집니다. 파라미터는사용되는순서에따라서 0x8 부터 4 바이트씩증가하는주소를사용합니다

현재 EBP 레지스터 int Function(..) { 스택위치 TOP TOP+0x04 TOP+0x08 TOP+0x0C TOP+0x10 값 Old EBP 리턴주소파라미터A 파라미터B 파라미터C [EBP+0x8] : A [EBP+0xC] : B [EBP+0x10] : C D = Function(A,B,C); return Z;

int main() { int Sum; push ebp mov ebp,esp sub esp,0cch push ebx push esi push edi 하제소프트 지역변수는 [EBP-XX] 형태로나타납니다 두번째파라미터 (2) 첫번째파라미터 (1) Sum = SummaryFunction(1,2); push 2 push 1 call 010f1320 // SummaryFunction add esp,8 // 두번의 PUSH를복원합니다 mov dword ptr [ebp-8],eax return 0; xor pop pop pop add cmp mov pop ret 지역변수 (Sum) 에담습니다 eax,eax edi esi ebx esp,0cch ebp,esp esp,ebp ebp 함수를호출합니다 함수리턴값은 EAX 레지스터에담겨집니다 C 함수를호출할때, 파라미터는스택에역순으로 PUSH 합니다함수를호출하는문장은 CALL XXXXX 형태를가집니다함수가리턴되면, 리턴값은 EAX 레지스터에담겨집니다리턴된값 (EAX) 을지역변수 (EBP-XX) 에담습니다

int SummaryFunction(int i, int j) { int c; // 지역변수선언 c = i + j; // 첫번째파라미터 i, 두번째파라미터 j 의값을더해서지역변수 c 에넣습니다 return c; // 지역변수의 c 의값을리턴합니다. 호출자에게되돌려줍니다 하제소프트 int SummaryFunction( int i, int j) { push ebp mov ebp,esp 지역변수 (c) 를위한영역이초기화 int c; sub push push push esp,0cch ebx esi edi 파라미터변수는 [EBP+XX] 형태로나타납니다 EAX 레지스터 <= 첫번째파라미터 (i), [EBP+8] c = i + j; return c; mov add mov mov pop pop pop mov pop ret eax,dword ptr [ebp+8] eax,dword ptr [ebp+0ch] dword ptr [ebp-8],eax eax,dword ptr [ebp-8] edi esi ebx esp,ebp ebp EAX 레지스터 += 두번째파라미터 (j), [EBP+C] 지역변수 (c), [EBP-8] <= EAX 레지스터 지역변수는 [EBP-XX] 형태로나타납니다 EAX 레지스터 <= 지역변수 (c), [EBP-8] 함수의리턴값은 EAX 레지스터에담겨집니다

1.4 디스어셈블리윤각 x86 CPU에서 C 함수가사용되는문장을디스어셈블리했을때나타나는윤각에대해서정리합니다 xxxxxx( ) // 피호출되는함수의내용 { mov [EBP+8], // 첫번째파라미터접근 mov [EBP+C], // 두번째파라미터접근 mov [EBP-8], // 지역변수접근 { // 함수를호출하는문장을담고있는내용 push??? // 마지막파라미터전달 push??? // 첫번째파라미터전달 call xxxxxx // 함수호출 add ESP, 파라미터수 * 4 // 스택을복원합니다 mov [EBP-8], EAX // 리턴값과지역변수접근 항상 [EBP+N] 형태는파라미터를접근하는행동입니다. 사용되는 N 값을보면, 몇번째파라미터인지를알수있습니다 항상 [EBP-N] 형태는지역변수를접근하는행동입니다 함수가리턴되면리턴값은항상 EAX 레지스터에담겨집니다

2. x64 과 Calling 규약 x64 CPU에서 C 함수를작성한뒤, 어셈블리어로변환시켜보도록합니다 하제소프트 비교를위해서 x86 과같은 C 소스를사용합니다 int main() { int Sum; // 지역변수선언 Sum = SummaryFunction(1, 2); // 1 과 2 를함수에인자로입력 // SummaryFunction 함수의결과를 Sum 지역변수에담습니다 return 0;

2.1 레지스터 x64 CPU 에서사용되는대표적인레지스터들입니다 프로그램코드실행위치 rax=00000000cccccccc rbx=0000000000000000 rcx=0000000000000001 rdx=0000000000000002 rsi=0000000000000000 rdi=000000085f2ffb28 rip=00007ff786111680 rsp=000000085f2ffa18 rbp=000000085f2ffa40 r8=000001d9e8038ec0 r9=00007ff80d30bbc0 r10=0000000000000000 r11=000000085f2ffad0 r12=0000000000000000 r13=0000000000000000 r14=0000000000000000 r15=0000000000000000 iopl=0 nv up ei pl nz na pe nc <= Flag 레지스터중대표적 cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 Qword RAX (8Bytes) EAX Dword (4Bytes) Word (2Bytes) AX AH AL

64 비트하위 32 비트하위 16 비트 8 비트의미 RAX EAX AX AH, AL Accumulator RBX EBX BX BH, BL Base Register RCX ECX CX CH, CL Count Register RDX EDX DX DH, DL Double Precision Register RSI ESI SI Source Index Register RDI EDI DI Destination Index Register RBP EBP BP Base Pointer Register RSP ESP SP Stack Pointer RIP EIP IP Instruction Pointer Flags Flag Register R8..R15 R8D..R15D R8W..R15W R8B..R15B Common Register

2.2 Disassemby 연습 C 코드로작성된예재와이를어셈블리어로번역한내용을서로비교해보도록하겠습니다. 이과정을전부이해하기가곤란한학생들은함수를호출하는부분위주로살펴보면되겠습니다

2.2.1 C 소스코드예재 int Simple(int i, int j) { return i*5 + j + 3; 간단한소스이므로이곳에서바로 Disassembly 하도록하겠습니다 01001080 lea eax,[rdx+rcx*4] ; eax = rdx+rcx*4 01001083 lea eax,[rcx+rax+0x3] ; eax = rcx+rax+3 01001087 ret

HRESULT Meaningless(IDispatch *pdisp, DISPID dispid, BOOL funique, LPCWSTR pszexe) { IQueryAssociations *pqa; HRESULT hr = AssocCreate(CLSID_QueryAssociations, IID_IQueryAssociations, (void**)&pqa); if (SUCCEEDED(hr)) { hr = pqa->init(assocf_init_byexename, pszexe, NULL, NULL); if (SUCCEEDED(hr)) { WCHAR wszname[max_path]; DWORD cchname = MAX_PATH; hr = pqa->getstring(0, ASSOCSTR_FRIENDLYAPPNAME, NULL, wszname, &cchname); if (SUCCEEDED(hr)) { VARIANTARG rgvarg[2] = { 0 ; V_VT(&rgvarg[0]) = VT_BSTR; V_BSTR(&rgvarg[0]) = SysAllocString(wszName); if (V_BSTR(&rgvarg[0])) { DISPPARAMS dp; LONG lunique = InterlockedIncrement(&lCounter); V_VT(&rgvarg[1]) = VT_I4; V_I4(&rgvarg[1]) = funique? lunique : 0; dp.rgvarg = rgvarg; dp.cargs = 2; dp.rgdispidnamedargs = NULL; dp.cnamedargs = 0; hr = pdisp->invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL); VariantClear(&rgvarg[0]); VariantClear(&rgvarg[1]); else { hr = E_OUTOFMEMORY; pqa->release(); return hr; 하제소프트

2.2.2 Disassembly Meaningless: 010010e0 push rbx ; 스택으로레지스터를임시로 save 010010e1 push rsi ; save 010010e2 push rdi ; save 010010e3 push r12d ; save 010010e5 push r13d ; save 010010e7 push r14d ; save 010010e9 push r15d ; save 010010eb sub rsp,0x2c0 ; 지역변수를위해서스택위치를조정 010010f2 mov rbx,r9 ; rbx = pszexe 010010f5 mov r12d,r8d ; r12 = funique (zero-extend) 010010f8 mov r13d,edx ; r13 = dispid (zero-extend) 010010fb mov rsi,rcx ; rsi = pdisp IQueryAssociations *pqa; HRESULT hr = AssocCreate(CLSID_QueryAssociations, IID_IQueryAssociations, (void**)&pqa); 010010fe movdqu xmm0,oword ptr [CLSID_QueryAssociations (01001060)] 01001106 movdqu oword ptr [rsp+0x60],xmm0 ; 임시 buffer에첫번째파라미터를보관 0100110c lea r8,[rsp+0x58] ; arg3 = &pqa 01001111 lea rdx,[iid_iqueryassociations (01001070)] ; arg2 = &IID_IQueryAssociations 01001118 lea rcx,[rsp+0x60] ; arg1 = &temporary ( 임시 buffer 에서값을끄집어냄 ) 0100111d call qword ptr [_imp_assoccreate (01001028)] ; call if (SUCCEEDED(hr)) { 01001123 test eax,eax 01001125 jl ReturnEAX (01001281)

hr = pqa->init(assocf_init_byexename, pszexe, NULL, NULL); 0100112b mov rcx,[rsp+0x58] ; arg1 = pqa 01001130 mov rax,[rcx] ; rax = pqa.vtbl 01001133 xor r14d,r14d ; r14 = 0 01001136 mov [rsp+0x20],r14 ; arg5 = 0 0100113b xor r9d,r9d ; arg4 = 0 0100113e mov r8,rbx ; arg3 = pszexe 01001141 mov r15d,0x2 ; r15 = 2 (for later) 01001147 mov edx,r15d ; arg2 = 2 (ASSOCF_INIT_BY_EXENAME) 0100114a call qword ptr [rax+0x18] ; call Init method if (SUCCEEDED(hr)) { 0100114d mov ebx,eax ; ebx = hr 0100114f test ebx,ebx ; FAILED? 01001151 jl ReleasePQA (01001274) ; 작으면 jump ( 음수 ) WCHAR wszname[max_path]; DWORD cchname = MAX_PATH; hr = pqa->getstring(0, ASSOCSTR_FRIENDLYAPPNAME, NULL, wszname, &cchname); if (SUCCEEDED(hr)) { 01001157 mov dword ptr [rsp+0x50],0x104 ; cchname = MAX_PATH 0100115f mov rcx,[rsp+0x58] ; arg1 = pqa 01001164 mov rax,[rcx] ; rax = pqa.vtbl 01001167 lea rdx,[rsp+0x50] ; rdx = &cchname 0100116c mov [rsp+0x28],rdx ; arg6 = cchname 01001171 lea rdx,[rsp+0xb0] ; rdx = &wszname[0] 01001179 mov [rsp+0x20],rdx ; arg5 = &wszname[0] 0100117e xor r9d,r9d ; arg4 = 0 01001181 mov r8d,0x4 ; arg3 = 4 (ASSOCSTR_FRIENDLYNAME) 01001187 xor edx,edx ; arg2 = 0 01001189 call qword ptr [rax+0x20] ; call GetString method 0100118c mov ebx,eax ; ebx = hr 0100118e test ebx,ebx ; FAILED? 01001190 jl ReleasePQA (01001274) ; 작으면 jump ( 음수 )

VARIANTARG rgvarg[2] = { 0 ; 01001196 lea rdi,[rsp+0x82] ; rdi = &rgvarg 0100119e xor eax,eax ; rax = 0 010011a0 mov ecx,0x2e ; rcx = sizeof(rgvarg) 010011a5 rep stosb ; 0 값으로기록한다 (memset) V_VT(&rgvarg[0]) = VT_BSTR; V_BSTR(&rgvarg[0]) = SysAllocString(wszName); if (V_BSTR(&rgvarg[0])) { 010011a7 mov word ptr [rsp+0x80],0x8 ; V_VT(&rgvarg[0]) = VT_BSTR 010011b1 lea rcx,[rsp+0xb0] ; arg1 = &wszname[0] 010011b9 call qword ptr [_imp_sysallocstring (01001010)] ; call 010011bf mov [rsp+0x88],rax ; V_BSTR(&rgvarg[0]) = result 010011c7 test rax,rax ; SysAllocString 함수의리턴값이있으면, 010011ca je OutOfMemory (0100126f) ; 이값이 0 이면, Jump DISPPARAMS dp; LONG lunique = InterlockedIncrement(&lCounter); 010011d0 lea rax,[lcounter (01002000)] 010011d7 mov ecx,0x1 010011dc lock xadd [rax],ecx ; 배타적접근을위한 interlocked exchange 와 add 010011e0 add ecx,0x1 V_VT(&rgvarg[1]) = VT_I4; V_I4(&rgvarg[1]) = funique? lunique : 0; 010011e3 mov word ptr [rsp+0x98],0x3 ; V_VT(&rgvarg[1]) = VT_I4; 010011ed mov eax,r14d ; rax = 0 (r14d 값은현재 0 입니다 ) 010011f0 test r12d,r12d ; funique 값이기록되어있는가? 010011f3 cmovne eax,ecx ; 만일그렇다면 set rax=lcounter 010011f6 mov [rsp+0xa0],eax ; V_I4(&rgvarg[1]) =...

dp.rgvarg = rgvarg; dp.cargs = 2; dp.rgdispidnamedargs = NULL; dp.cnamedargs = 0; 010011fd lea rax,[rsp+0x80] ; rax = &rgvarg[0] 01001205 mov [rsp+0x60],rax ; dp.rgvarg = rgvarg 0100120a mov [rsp+0x70],r15d ; dp.cargs = 2 (r15 is still 2) 0100120f mov [rsp+0x68],r14 ; dp.rgdispidnamedargs = NULL 01001214 mov [rsp+0x74],r14d ; dp.cnamedargs = 0 hr = pdisp->invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL); 01001219 mov rax,[rsi] ; rax = pdisp.vtbl 0100121c mov [rsp+0x40],r14 ; arg9 = 0 01001221 mov [rsp+0x38],r14 ; arg8 = 0 01001226 mov [rsp+0x30],r14 ; arg7 = 0 0100122b lea rcx,[rsp+0x60] ; rcx = &dp 01001230 mov [rsp+0x28],rcx ; arg6 = &dp 01001235 mov word ptr [rsp+0x20],0x1 ; arg5 = 1 (DISPATCH_METHOD) 0100123c xor r9d,r9d ; arg4 = 0 0100123f lea r8,[guid_null (01001080)] ; arg3 = &IID_NULL 01001246 mov edx,r13d ; arg2 = dispid 01001249 mov rcx,rsi ; arg1 = pdisp 0100124c call qword ptr [rax+0x30] ; call Invoke method 0100124f mov ebx,eax ; hr = result VariantClear(&rgvarg[0]); VariantClear(&rgvarg[1]); 01001251 lea rcx,[rsp+0x80] ; arg1 = &rgvarg[0] 01001259 call qword ptr [_imp_variantclear (01001018)] 0100125f lea rcx,[rsp+0x98] ; arg1 = &rgvarg[1] 01001267 call qword ptr [_imp_variantclear (01001018)] 0100126d jmp ReleasePQA (01001274)

else { hr = E_OUTOFMEMORY; OutOfMemory: 0100126f mov ebx,0x8007000e ; hr = E_OUTOFMEMORY pqa->release(); ReleasePQA: 01001274 mov rcx,[rsp+0x58] ; arg1 = pqa 01001279 mov rax,[rcx] ; rax = pqa.vtbl 0100127c call qword ptr [rax+0x10] ; release return hr; 0100127f mov eax,ebx ; rax = hr ( 리턴값을준비합니다 ) ReturnEAX: 01001281 add rsp,0x2c0 ; 지역변수를위해사용하던스택을복원합니다 01001288 pop r15d ; 함수진입시보관했던레지스터값들을 restore 0100128a pop r14d ; restore 0100128c pop r13d ; restore 0100128e pop r12d ; restore 01001290 pop rdi ; restore 01001291 pop rsi ; restore 01001292 pop rbx ; restore 01001293 ret ; 호출자에게돌아갑니다

X64 CPU 환경에서는호출시규약은지켜지지만피호출함수내에서파라미터접근방법 (RBP+xx) 은지켜지지않습니다 2.3 파라미터와지역변수 하제소프트 x64 CPU에서 C 함수가사용하는파라미터와지역변수는다음과같은규칙을사용합니다 파라미터의경우, 함수를호출할때와, 피호출자의입장이조금다릅니다 파라미터가전달되는규칙은지켜집니다 함수진입점에서스택에 PUSH 합니다 지역변수호출시, 파라미터피호출, 파라미터 첫번째 [RBP+MM] RCX(ECX) RCX=>[RBP+0x100] 두번째 [RBP+NN] RDX(EDX) RDX=>[RBP+0x108] 세번째 [RBP+SS] R8(R8D) R8=>[RBP+0x110] 네번째 [RBP+KK] R9(R9D) R9=>[RBP+0x118] 다섯번째 [RBP+PP] PUSH [RBP+0x120] 여섯번째 [RBP+QQ] PUSH [RBP+0x128] * ( ) 는 32 비트데이터의경우

파라미터가전달되는규칙은지켜집니다 RCX, RDX, R8, R9 레지스터값에파라미터값을보관합니다. 이후파라미터는스택에보관됩니다 D = Function(A,B,C); 스택위치 값 TOP... 지역변수영역. TOP+0xF0 TOP+0xF8 TOP+0x100 TOP+0x108 TOP+0x110 TOP+0x118 TOP+0x120 현재 RBP 레지스터 Old RBP 리턴주소 파라미터 A 파라미터 B 파라미터 C 4 번째파라미터 5 번째파라미터 int Function(..) { 하제소프트 RCX, RDX, R8, R9 레지스터값을스택에보관합니다 ( 디버그버젼 ) [RBP+0x100] : A [RBP+0x108] : B [RBP+0x110] : C [RBP+0x118] : 4 th Param [RBP+0x120] : 5 th Param return Z; [RBP+xx] 접근방법은지켜지지않습니다

int main() { push rbp push rdi 하제소프트 지역변수는 [RBP+XX] 형태로나타납니다 int Sum; sub lea mov rsp,108h rbp,[rsp+20h] rdi,rsp 두번째파라미터 (2). int 타입이기에 EDX 를사용합니다첫번째파라미터 (1). int 타입이기에 ECX 를사용합니다 Sum = SummaryFunction(1,2); mov edx,2 mov ecx,1 call 00007ff6`ebbd1087 // SummaryFunction mov dword ptr [rbp+4],eax return 0; xor lea pop pop ret 지역변수 (Sum) 에담습니다 eax,eax rsp,[rbp+0e8h] rdi rbp 함수를호출합니다 함수리턴값은 EAX 레지스터에담겨집니다 (int 리턴 ) C 함수를호출할때, 파라미터는순서대로, ECX(RCX), EDX(RDX), R8, R9 에담겨집니다. 이후파라미터는스택에 PUSH 됩니다. ECX(32 비트 ), RCX(64 비트 ) 로구분됩니다

X64 CPU 환경에서는피호출함수내에서파라미터접근방법 (RBP+xx) 은지켜지지않습니다 int SummaryFunction(int i, int j) { int c; // 지역변수선언 c = i + j; // 첫번째파라미터 i, 두번째파라미터 j 의값을더해서지역변수 c 에넣습니다 return c; // 지역변수의 c 의값을리턴합니다. 호출자에게되돌려줍니다 int SummaryFunction( int i, int j) { mov dword ptr [rsp+10h],edx mov dword ptr [rsp+8],ecx push rbp push rdi 하제소프트 전달받은첫번째, 두번째파라미터를스택에 PUSH 하는코드를사용합니다 지역변수 (c) 를위한영역이초기화 파라미터변수는 [RBP+1XX] 형태로나타납니다 int c; sub mov mov rsp,0e8h rbp,rsp rdi,rsp EAX 레지스터 <= 두번째파라미터 (j), [RBP+108] c = i + j; return c; mov mov add mov mov mov lea pop pop ret eax,dword ptr [rbp+108h] ecx,dword ptr [rbp+100h] ecx,eax eax,ecx dword ptr [rbp+4],eax eax,dword ptr [rbp+4] rsp,[rbp+0e8h] rdi rbp ECX 레지스터 <= 첫번째파라미터 (i), [RBP+100] ECX += EAX EAX <= ECX 지역변수 (c), [RBP+4] <= EAX EAX 레지스터 <= 지역변수 (c), [RBP+4] 함수의리턴값은 EAX 레지스터 (int 타입 ) 에담겨집니다

X64 CPU 환경에서는피호출함수내에서파라미터접근방법 (RBP+xx) 은지켜지지않습니다 하제소프트 2.4 디스어셈블리윤각 x64 CPU에서 C 함수가사용되는문장을디스어셈블리했을때나타나는형태에대해서정리합니다 xxxxxx( ) // 피호출되는함수의내용 { mov [RBP+100], // 첫번째파라미터접근 mov [RBP+108], // 두번째파라미터접근 mov [RBP+KK], // 지역변수접근 { // 함수를호출하는문장을담고있는내용 mov RDX,??? // 두번째파라미터전달 mov RCX,??? // 첫번째파라미터전달 call xxxxxx // 함수호출 mov [RBP+TT], RAX // 리턴값과지역변수접근 함수진입점을거친뒤엔 [RBP+XXX] 형태는파라미터를접근하는행동입니다. 사용되는 X 값을보면, 몇번째파라미터인지를알수있습니다 항상 [RBP+KK] 형태는지역변수를접근하는행동입니다 함수가리턴되면리턴값은항상 RAX(EAX) 레지스터에담겨집니다

본강의 PDF 는하제소프트다운로드자료실에서받아보실수있습니다 하제소프트 주식회사하제소프트 (www.hajesoft.co.kr) 강사이봉석