Parse and Parse Assembly ( 어셈블리어입문자를위한 어셈블리어자료들의모음 ) ## 목차 ## 0x01. ----------Introduce----------- 0x02. 어셈블리언어란? & 배우는목적 0x03. 어셈블리언어를위한기본지식 0x04. 어셈블리명령어의구성 0x05. 주소지정방식의이해 0x06. 어셈블리명령어정리 0x07. 어셈블리명령어상세 0x08. 참조사이트및문서 0x09. 마치며... 작성자 : bobana E-mail : zeroone2000@korea.com 작성일 : 2007년 3월 30일
0x01. Introduce. ------------------------------------------------------------------------------------- 이문서의목적은저의공부( 시스템이해) 와레포트작성에있습니다. 또한, 인터넷및자료수집을통한문서들을종합적으로모으고, 기술합니다. 시스템의이해를목적으로하기때문에어셈블리프로그래밍관련글이아님을밝힙니다. 어셈블리는많은명령어를가지고있지만이글에서는기본적인약간의명령어만다루겠습니다. 어셈블리언어를익히고자함이아닌시스템분석을위한, 시스템의흐름을이해하기위해서는내부적으로컴퓨터가고급언어들을어떤식으로다루는지파악해야하기때문입니다. 거의 [ 펌] 수준이므로저작권은저에게없다고볼수있습니다.^^;; 전일종의편집자라고생각해주세요. 이문서에서의어셈블리는 AT&T 문법을따릅니다. 이후의문체는편의상반말로진행하겠습니다. :-) ------------------------------------------------------------------------------------- 0x02. 어셈블리언어란? & 배우는목적 CPU 에는해당프로세서에명령을내리기위해고유의명령어세트가마련되어있는데이명령어세트를기계어라고한다. 이기계어는숫자들의규칙조합임으로프로그래밍에상당히난해하다. 그래서이기계명령어를좀더이해하기쉬운기호코드로나타낸것( 기계어와 1:1 로대응된명령을기술하는언어) 이어셈블리어이다. 어셈블리언어는그코드가어떤일을할지를추상적이아닌, 직접적으로보여준다. 논리상의오류나, 수행속도, 수행과정에대해명확히해준다는점에서직관적인언어이다. 어셈블리언어를사용하면메모리에대한이해도도높아진다. 어셈블리를익히고, 배우는데있어서는여러가지목적이있을수있다. 컴퓨터시스템구조를좀더깊게이해하고 &, 메모리상의데이터나I/O기기를직접액세스하는등의고급언어에서는할수없는조작을위해서이다. 프로그램의최적화및리버스엔지니어링을위해서도필요하다. +2 줄요약+ - 어셈블리언어는기계어와 1:1 대응을하는언어이다. - 어셈블리언어를배우면시스템을이해하는데도움이된다. 0x03. 어셈블리를위한기본지식 (1) 기본적인하드웨어 1) CPU - 메모리에있는내용을읽고, 쓰고데이터를메모리와각레지스터로보낸다. 프로그램의명령을해석하고실행한다. 하나의프로세서는 12~14개의레지스터를가지고있으며, CPU 의연산, 논리장치는숫자와기호에관한연산자를인식한다. 보통이러한장치들은기본적인연산만을수행할수있다( 덧셈, 뺄셈, 곱셈, 나눗셈, 숫자비교). 퍼스널컴퓨터는한번에처리할수있는비트수(Word) 따라서분류된다. 2) RAM - 반도체로조립된셀들의집합. 프로세스가프로그램을실행시키고작동하기위해서필요한정보들을저장하는데쓰인다. 각각의셀들은숫자값을포함하고주소가정해질수있는형 식이며프로그램에서흔히메모리라고하는것들은메인메모리, 즉, 램이라고할수있다.
(2) 80x86 프로세서 1) CPU 레지스터종류 : 범용레지스터, 상태레지스터, 플래그레지스터 - 레지스터 : CPU내부의기억장소로 PC가정보를처리하기위해서는정보가특정한셀에저장되어있어야한다. 이러한셀을레지스터라고불린다. 레지스터들은 8 또는 16비트플립- 플롭회로들의집합이다. 플립-플롭회로란두단계의전압으로정보를저장할수있는장치이다. 낮은전압은 0.5 볼트이고높은전압은 5 볼트이다. 낮은단계의에너지는 0으로해석되고높은전압은 1이다. 이상태는보통비트로불리며컴퓨터의가장작은정보단위이다. 32 15 0 15 0 +-------+-------+-------AX------+ +---------------+ EAX AH AL CS +-------+-------+-------BX------+ +---------------+ EBX BH BL DS +-------+-------+-------CX-----+ +---------------+ ECX CH CL ES +-------+-------+-------DX-----+ +---------------+ EDX DH DL SS +-------+-------+-------+-------+ +---------------+ ESI SI GS +-------+-------+---------------+ +---------------+ EDI DI FS +-------+-------+---------------+ 32---------------0 EBP BP EFLAGS(32bits) +-------+-------+---------------+ +---------------+ ESP SP EIP(32bits) +-------+-------+---------------+ +---------------+ 32 15 0 < 레지스터의구조 > 1 데이터레지스터 - 데이터레지스터는각종데이터처리를대상으로하는하는 32비트레지스터및 16 비트레지스터일부를프로그래머가명령중에서자유롭게지정을할수있는범용레지스터이다. : EAX, EBX, ECX,EDX 2 포인터레지스터 : ESP, EBP, 3 인덱스레지스터 (Index register) : ESI, EDI 4 세그먼트레지스터 (segment register) : CS, DS, SS, ES
+ 범용레지스터 + 32Bit 16Bit 상위 8Bit 하위 8Bit 기능 EAX AX AH AL EBX BX BH BL ECX CX CH CL EDX DX DH DL ESI SI EDI DI ESP SP EBP BP 누산기(Accumulator, 중간결과를저장해놓음) 레지스터라불리며, 곱셈이나나눗셈연산에중요하게사용 베이스레지스터라불리며메모리주소지정시에사용 계수기(Counter) 레지스터라불리며, Loop 등의반복명령에사용됩니다. 데이터(Data) 레지스터라불리며곱셈, 나눗셈에서 EAX 와함께쓰이며부호확장명령등에사용 다량의메모리를옮기거나비교할때그소스(Source) 의주소를가진다 다량의메모리를옮기거나비교할때그목적지의주소를가리킨다. 스택포인터로스택의최종점을저장한다. Push, Pop 명령에의해늘었다줄었다한다. ESP를대신해스택에저장된함수의파라미터나지역변수의주소를가리키는용도로사용된다. + 세그먼트레지스터 + 16Bit ES CS SS DS 기능 보조세그먼트레지스터다. 두곳이상의데이터저장영역을가리켜야할때 DS 와함께사용된다. 하지만 32비트프로그램에서는 DS와 ES가같은영역역을가리키고있기때문에굳이신경쓰지않아도된다. 코드세그먼트를가리키는레지스터. 프로그래머의코드의시작주소를가지고있다. 스택세그먼트를가리키는레지스터. 스택의시작주소를담고있다. 스택조작에의해서데이터를처리하는동작이이루어진다. 데이터세그먼트를가리키는레지스터. 프로그래머가정해놓은데이터의시작주소를담고있다. FS 보조세그먼트레지스터. FS, GS는 286 이후에추가된것으로운영체제를 GS 작성하는게아니라면없듯이여겨도된다
+ 상태레지스터+ 32Bit 16Bit 기능 EIP는현재실행되고있는프로그램의실행코드가저장된메모리의 주소를가리키는레지스터로프로그램의실행이진행됨에따라자동 EIP IP 으로증가하고프로그램의실행순서가변경되는제어문이실행될때자동으로변경된다. 그래서직접접근해서값을저장하거나읽거나하는일이없기때문에응용프로그램에서는손댈일이없는레지스터이다. EFLAGS FLAGS 비트단위의플래그들을저장하는레지스터로아주특별한용도로 사용된다 0x04. 어셈블리명령어의구성 - 어셈블리는어셈블리어라고도부르는데이어셈블리어는명령어들의조합이다. 인텔 CPU 안에는이명령어들이회로로구현되어있어서어셈블리코드를실행할수있다.CPU는 2진수로모든것을처리하는데어셈블리명령어들도 2 진수로되어있다. 하지만 2진수로된것알아보기가힘들어 mov, add 와같은형태로변환하여보여진다. 아래그림을보자. L1: mov %eax, %ebx ;comment +-----+ +----------+ +-------------+ +-------------+ +----------+ Label 작동코드 제 1 오퍼랜드 제 2 오퍼랜드 설명문 +-----+ +----------+ +------+------+ +-------+-----+ +----------+ --------------- 조작의방향 명령어다음에오는레지스터이름이나값들은 operand 라고한다. mov %eax, %ebx 에서 %eax 를제1 오퍼랜드, %ebx를제2 오퍼랜드라고한다. mov %eax, %ebx는 C언어로보면 ebx = eax 의경우와같다. eax에저장된값을 ebx 에할당(assignment) 한다.( 특정장소( 주로메모리상에서) 에서특정장소( 주로레지스터) 로데이터를읽어와서적재(load)). L1: 과같은명령은직접적으로기계어코드로번역되지않고분기명령(jmp) 등에서참조될때에, 번지의계산에사용된다. 0x05. 주소지정방식의이해 - 어셈블리는메모리를직접다룰수있다는점에서우리가어셈블리를배우는큰이유가될수있다. 이메모리를다루기위해서다양한주소지정방식이있는데어떤식으로주소를사용하고, 참조하는지확인할필요가있다. 참고로 '0x04' 에서예를들었던 'mov %eax,%ebx' 의경우는레지스터어드레싱(register addressing) 이다.
1. 즉시지정방식(immediate addressing) - mov $0x1, %eax : eax 에 (16 진수)1 을값을넣는( 할당) 방식이다. - 이렇게메모리( 기억장치) 의주소의내용을꺼내지않고직접값을대응시키는방식을즉시지정방식이라고한다. 2. 레지스터지정방식(register addressing) - mov %esp, %ebp : 레지스터 ebp에레지스터 esp 의값을넣는다.( 할당개념) : 나중에알수있겠지만, 위의명령은스택포인터를베이스포인터에넣는명령으로함수가시작될때 ebp 의값( 일종의시작기준점) 을정하는명령이다. - 레지스터에서직접레지스터로값을대응시키는방식을레지스터지정방식이라고한다. - 속도는빠르지만레지스터의크기(32 비트) 로인해크기가제한된다. 3. 직접주소지정방식(directly addressing) - mov %eax, $0x80482f2 : 주소 0x80482f2에있는값을 eax 에할당한다. - 가장일반적인주소지정방식이며, 메모리의주소를직접지정해서바로찾아오는방식이다. 즉 eax레지스터에 0x80482f2 주소의내용을로드(load) 한다는의미이다. 4. 레지스터간접주소지정방식 - mov (%ebx), %eax : ebx 의값을주소로하여( 간접적으로) eax레지스터에할당 - () 가들어간다면간접지정이라고볼수있다. () 의의미는괄호안에들어간값의주소이다. 5. 베이스상대주소지정방식 - mov 0x4(%esi), %eax : esi레지스터에서 4(byte) 를더한주소의값을 eax 레지스터에할당한다. - 보통레지스터의크기가 4byte 이기때문에레지스터다음주소를의미한다. 문자열열산이나메모리블록전송등에나오는방식이다.
0x06. 어셈블리어명령어정리 명령어예제설명분류 push push %eax eax 의값을스택에저장. 스택조작 pop pop %eax 스택가장상위에있는값을꺼내서 eax에저장 스택조작 mov mov %eax, %ebx 메모리나레지스터의값을옮길때사용데이터이동 lea leal(%esi), %ecx %esi 의주소값을 %ecx 에옮긴다. 주소이동 inc inc %eax %eax의값을 1 증가시킨다. 데이터조작 dec dec %eax %eax의값을 1 감소시킨다. 데이터조작 add add %eax, %ebx 레지스터나메모리의값을덧셈할때쓰인다. 논리, 연산 sub sub $0x8, %esp 레지스터나메모리의값을뺄셈할때쓰인다. 논리, 연산 call call proc 프로시져를호출한다. 프로시져 ret ret 호출했던바로다음지점으로이동. 프로시져 cmp cmp %eax, %ebx 레지스터와레지스터값을비교비교 jmp jmp proc 특정한곳으로분기분기 int int $0x80 OS에할당된인터럽트영역을 system call 인터럽트 nop nop 아무동작도하지않는다.(No Operation) 0x07. 어셈블리명령어상세 - 명령어의분류 1) 데이터이동 : mov, lea 2) 논리, 연산 : add, sub, inc, dec 3) 흐름제어 : cmp,jmp 4) 프로시져 : call, ret 5) 스택조작 : push, pop 6) 인터럽트 : int 1) 데이터전송 1. mov (move data) - 형식 : mov SOURCE, DESTINATION - 기능 : SOURCE위치에들어있는데이터를복사하여 DESTINATION 위치에저장. - 원칙 : 메모리와레지스터( 모든연산은레지스터에저장된뒤이루어진다.) 사이의데이터이동, 레지스터와레지스터사이의데이터이동이나값을메모리나레지스터에대입할때사용한다. (SOURCE와 DESTINATION 의크기가동일해야한다.)! DESTINATION 레지스터가 CS 가될수없다.( 프로그램실행위치가변경되기때문) (CS의변경은 int, jmp, call, ret 등의명령으로가능)! SOURCE와 DESTINATION 이전부메모리를가르칠수없다. ( 설계상불가능)
! SOURCE가직접지정방식일경우에는 DESTINATION은 CS 일수없다. 2. lea - 형식 : lea SOURCE, DESTINATION - 기능 : SOURCE OPERAND에서지정된주소를 DESTINATION 으로로드한다. LEA 의주된용도는매개변수나지역변수의주소를얻어오는것이다. 예를들어 C 언어에서지역변수나매개변수에 & 연산자를사용한다면컴파일러는 lea 명령어를생성한다. - 원칙 : SOURCE OPERAND 는메모리에위치해야하며, 변경될주소는 index register나 DESTINATION 에정의된주소여야한다. 2) 논리, 연산 : add, sub, inc, dec 1. add - 형식 : add opr1, opr2 - 기능 : opr2의내용에 op1의내용이더해져서그결과를 opr2 에저장. - 원칙:! 두개의오퍼랜드모두에메모리로조합되는것은불가능. 2. sub (subtract) - 형식 : sub opr1, opr2 - 기능 : 첫번째오퍼랜드로부터 2번째오퍼랜드의내용을뺀다음결과를첫번째오퍼 - 원칙 :! 메모리끼리는뺄셈을할수없다. 3. inc (Increment) - 형식 : inc DESTINATION - 기능 : DESTINATION을 1 증가시키고결과값을다시저장 4. dec (decrement) - 형식 : dec DESTINATION - 기능 : DESTINATION을 1 감소시키고결과값을다시저장 3) 흐름제어 : jmp, cmp - 형식 : jmp proc - 기능 : 프로그램의흐름을바꿀때사용. proc 의주소로가서그곳의명령어를실행. if/else 문, loop 문( 루프가아직끝나지않았을때, 처음위치로돌아가기위해) 등에서나타난다. 2. cmp - 형식 : cmp value, value ex) cmp %eax, 0 (eax레지스터의값을 0 과비교한다.) je start ( 비교결과가같다면 start 로분기한다.) ( 같지않다면 je 다음에오는명령어를실행한다.) - 기능 : 두값을비교하고비교결과에따라분기한다. 보통레지스터나메모리및숫자의
크기를비교한다. cmp 명령어는 Zero, Sign, Overflow 등의플래그를 set or clear 한다. 이플래그의결과에의해서 Jcc 명령어들은분기할것인지를결정한다. 보통 CMP 명령어다음에 JE, JNE 등의 jmp 관련명령어가위치한다. - 원칙 : cmp 명령은혼자사용되지않고언제나조건점프명령어나조건이동(mov) 명령어와함께사용된다. - 조건점프명령어 : cmp 명령어의결과에따라점프하는명령어. * 참고 * Unsigned 계열 ( 부호가없는값) je : jump equal - 비교결과가같을때점프 jne : jump not equal - 비교결과가다를때점프 jz : jump zero - 결과가 0 일때점프, je 와같음. (cmp 명령에서결과가같으면 0 을출력) jnz : jump not zero - 결과가0이아닐때점프 ja : jump above - cmp a, b에서 a가클때점프 jae : jump above or equal - 크거나같을때점프 jna : jump not above - 크지않을때점프 jnae : jump not above or equal - 크지않거나같지않을때점프 jb : jump below - cmp a, b에서 a가작을때점프 jbe : jump below or equal - 작거나같을때점프 jnb : jump not below - 작지않을때점프 jnbe : jump not below or equal - 작지않거나같지않을때점프 jc : jump carry - 캐리플래그가 1일때점프 jnc : jump not carry - 캐리플래그가 0일때점프 jnp/jpo : jump not parity / parity odd - 패리티플래그가 0 일때 / 홀수일때점프 jp/jpe : jump parity / parity even - 패리티플래그가 1 일때 / 짝수일때점프 jecxz : jump ecx zero - ecx 레지스터가 0일때점프 Signed 계열 ( 부호가있는값) jg : jump greater - cmp a, b에서 a가클때점프 jge : jump greater or equal - 크거나같을때점프 jng : jump not greater - 크지않을때점프 jnge : jump not greater or equal - 크지않거나같지않을때점프 jl : jump less - cmp a, b에서a가작을때점프
jle : jump less or equal - 작거나같을때점프 jnl : jump not less - 작지않을때점프 jnle : jump not less or equal - 작지않거나같지않을때점프 jo/jno : jump overflow / not overflow - 오버플로플래그가 1 일때 / 0일때점프 js/jns : jump sign / not sign - 사인부호 ( ) 플래그가1 일때음수 ( ) / 0 일때양수 ( ) 점프 조건점프명령을조합하여 if ( a > b ), for, while등의조건문구현 4) 프로시져 : call, ret 1. call - 형식 : call Target - 기능 : 스택상에서 CS를다음에오는명령의오프셋어드레스를 PUSH하고 target으로이동한다. 즉, 다른함수로제어를옮긴다는뜻이다. CALL 명령어다음에오는명령어의주소를스택에 PUSH 하고주어진주소로제어를옮긴다는뜻(EIP를변경시킴 ) # CALL명령은 CALL명령다음위치에있는명령의주소를스택에 push 한다. 2. ret (return) - 형식 : ret - 기능 : 호출된함수에서호출한함수로복귀. esp 에있는값을꺼내서(pop) EIP레지스터에할당한다. 즉, call명령당시 push되었던주소를 pop하여 eip 에넣는것이다. 5) 스택조작 : push, pop 1. pop - 형식 : pop DESTINATION - 기능 : 스택맨윗부분(top) 에서하나의워드를 DESTINATION 에로드(load) 그리고스택포인터는그바로전의데이터를가리킨다 (point). 2. push - 형식 : push DESTINATION - 기능 : 메모리상에설정된스택이라는공간에데이터를저장한다. 스택의가장윗부분에데이터를저장. 스택포인터(esp) 도워드크기만큼증가한다. 6) 인터럽트 : int - 형식 : int (interrupt-type) - 기능 : 운영체제에할당된인터럽트영역을 system call.
0x08. 참조사이트및문서 1. 김병희 님이쓰신문서. ( 제목이나와있지않네요) 2. Lecture Note in Assembly Language Written by Han, Kwang-Rok 3. 블루님의매크로어셈이야기 4. Just Enough Assembly Language to Get By, Part 1,2 by Matt Pietrek 5. 김성훈님의 C 프로그래머가알아야할것들 - Chapter 7 어셈블리 6. 유용수님의어셈블리강좌 7. 김영빈님의 헥커가되자 8. C를어셈블리어로 (http://blog.naver.com/earlyhungki?redirect=log&logno=20033888653) 9. Assembly Tutor (http://blog.naver.com/koreahjg?redirect=log&logno=60034750188) 10. http://blog.naver.com/berg76?redirect=log&logno=130001429195 0x09. 마치며... 분량은그리많지않지만, 의외로작업시간이길었던것같습니다. 그래도많은자료들을모 아서나름대로정리를했다는데의의를두죠 ^^; C 에서의어셈블리사용이라던지, 함수의 호출및복귀시스택사용에서의분석도추가하고싶었지만, 나름대로할일이있어하지못 했네요. 후에기회가된다면, 조금더내용을추가시켜서업데이트하도록노력할게요. 다른 분들에게는많은도움은못되겠지만, 그래도조금이라도도움이되셨으면합니다. 읽어주셔 서감사합니다. 위의참조사이트및문서저자분들에게미리말씀못드렸는데괜찮은지모 르겠네요. 모두열심히공부해요~ ^^)/