태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

리버싱의 기초 정리

CAT-Security/미분류|2013.07.23 23:13

  지금부터 이루어지는 포스팅은  IA-32 Processor Architecture 기반입니다.

 

1.레지스터 - CPU 내부에 있는 8,16,32Bit 고속 저장소를 말하며 일반적으로 사용하고 있는

                 메모리 보다 데이터를 훨씬 빨리 Read ,Write 할 수 있음.

 

범용 레지스터 (General-Purpose Register) : 8

EAX, EBX, ECX, EDX, ESI, EDI레지스터는 우리 마음대로 쓸 수 있는 레지스터이다.

EAX : Accumulator Register. 곱셈나눗셈 명령에 쓰임.

EBX : Base Register.

ECX : Counter Register. 루프 카운터로 쓰임.

EDX : Data Register.

ESI : Source Index. 고속의 메모리 복사에 쓰임.

EDI : Destination Index. 고속의 메모리 복사에 쓰임.

 

ESP,EBP레지스터는 스택레지스터라고 불림.

ESP : Stack Pointer의 약자스택의 탑 가르킴.2개

EBP : Base Pointer. 고급 언어에서 사용하는 함수 파라미터와 지역변수를 가리키는 데 쓰일 것이

      다일반적인 산술이나 데이터 전송에 쓰여서는 안됨.

 

세그먼트 레지스터 (Segment Register) : 6

프로그램 수행에 필요한 내용들이 미리 메모리에 할당되어 있는 데 그곳의 주소를 갖고 있음.

-세그먼트 레지스터는 자세히 알 필요 없음

 

EIP Register = 명령 포인터 (Instruction Pointer) : 다음에 수행되어야 할 명령문의 주소

                    를 갖고 있게 된다. (우리가 흔히 알고 있는 PC=Program Counter와 같음.)

 

EFLAGS Register : EFLAGS의 각각의 비트는 1(set)이 되거나 0(clear)이 될 수 있

                      음예를 들어, Sign Flag라는 비트는 계산 결과가 음수인지 아 닌지를 표

                      현해줌.

                      즉이 레지스터를 통해 여러 가지 상태를 알 수 있다. (음수인 지 양수인

                      지오버플로우가 발생하였는지 등)

 

 

 

2.바이트 순서

-Little-Endian (리틀 인디언) : 주소의 낮은 자릿수를 기록하고주소값이 증가할수록 높은

                                   자릿수를 기록하는 것인텔 계열이 주로 사용

                                   Ex) 0x12345678 => 78 56 34 12

                                  

-Big Endian (빅 인디언) : 정수로 정렬된 큰 수에 대한 비교를 메모리의 작은 주소부터 큰 주

                             소 방향으로 읽으면서 바로 비교할 수 있어 더 빨리 할 수 있으며,

                             모든 정수와 문자열을 같은 순서 방향으로 읽을 수 있다는 장점 있

                             음.Motorola나 Sun, Sparc등 RISC에서 사용.

                             Ex) 0x12345678 => 12 34 56 78

 

 

 

3.Calling Conventions

-스택에 파라미터를 어떠한 순서로 넣을 것인가?

 전달되어진 파라미터를 어느 곳에서 해제할 것인가?

이 두가지에 따라 여러 가지 방식이 있는데 이를 콜링 컨벤션이라고 함.

 

_cdecl

파라미터 전달 방향오른쪽->왼쪽

파라미터 해제 호출한 쪽(Caller)

 

_stdcall

파라미터 전달 방향 오른쪽 ->왼쪽

파라미터 해제 호출 당항 쪽(Callee)

 

_fastcall

처음 두 개까지의 파라미터는 스택을 사용하지 않고 ECX와 EDX레지스터 사용.

파라미터 전달 방향 오른쪽->왼쪽

파라미터 해제 호출 당한 쪽(Callee)


명령어1

명령어2

설명

부등호 조건

Flag 조건

JA

JNBE

크면 분기

부호 없이 비교[unsigned] )

OP1>OP2면 분기

CF=0 & ZF=0

JAE

JNB

크거나 같으면 분기

부호 없이 비교[unsigned] )

OP1OP2면 분기

CF=0 | ZF=1

JB

JNAE

작으면 분기

부호 없이 비교[unsigned] )

OP1<OP2면 분기

CF=1

JBE

JNA

작거나 같으면 분기

부호 없이 비교[unsigned] )

OP1OP2면 분기

CF=1 | ZF=1

JG

JNLE

크면 분기

부호 있는 비교[signed] )

OP1>OP2면 분기

ZF=0&SF ==OF

JGE

JNL

크거나 같으면 분기

부호 있는 비교[signed] )

OP1OP2면 분기

SF==OF

JL

JNGE

작으면 분기

부호 있는 비교[signed] )

OP1<OP2면 분기

SF!=OF

JLE

JNG

작거나 같으면 분기

부호 있는 비교[signed] )

OP1OP2면 분기

ZF==1|SF!=OF

JE

 

같으면 분기

OP1=OP2면 분기

ZF==1

JNE

 

같지 않으면 분기

OP1OP2면 분기

ZF==0

JC

 

Carry Flag가 Set되면 분기

 

CF==1

JNC

 

Carry Flag가 해제되어 있으면 분기

 

CF==0

JO

 

Overflow가 Set되어 있으면 분기

 

OF==1

JNO

 

Overflow가 해제되어 있으면 분기

 

OF==0

JS

 

Sign Flag가 Set되어 있으면(음수이면분기

 

SF==1

JNS

 

Sign Flag가 해제되어 있으면(양수이면분기

 

SF==0

JZ

 

Zero Flag가 Set되어 있으면 분기

 

ZF==1

JNZ

 

Zero Flag가 해제되어 있으면 분기

 

ZF==0

JP

 

Parity Flag가 Set되어 있으면 분기

 

PF==1

JNP

 

Parity Flag가 해제되어 있으면 분기

 

PF==0


ADD oper1, oper2 - oper1에 oper2를 더한뒤 결과값을 oper1에 저장.

                   ex) add eax, 1000h   <-eax = eax+0x1000

 

SUB oper1, oper2 - oper1에서 oper2를 빼고 결과 값을 oper1에 저장.

                   ex) mov eax, 5

                       sub eax, 5   <-결과는 0이됨.

 

MUL / IMUL oper - MUL은 부호 없는 곱셈 명령을 수행.

                  IMUL은 부호 있는 곱셈 명령을 수행.

                  EAX에 저장되어진 값과 oper을 곱한 결과를 아래와 같이 저장한다.

                  - 8비트 연산은 AX에 저장

                    16비트 연산은 DX:AX에 저장

                    32비트 연산은 EDX:EAX에 저장

                  ->곱셈 결과가 두배가 되어 자리수를 넘어가기 때문에 곱셈을 하였을때 두배

                    크기의 공간에 저장됨. (자리수를 넘어가면 캐리 또는 오버플로우 발생.)

 

ADC oper1, oper2 - ADD와 유사하나 캐리 플래그가 이용됨.

                   oper1 = oper1 + (oper2 + 캐리 플래그)

                   캐리비트는 0으로 리셋됨.

                   ex) mov ebx, 5

                       mov eax, 0

                       stc   <-CF=1(캐리 플래그)

                       sbb ebx, eax   <-ebx=4

          

SBB oper1, oper2 - SUB와 유사하나 캐리플래그가 이용됨.

                   oper1 = oper1 - (oper2 + 캐리 플래그)

                   연산이 끝나면 캐리비트는 0으로 리셋됨.

 

INC oper - Increment

           oper의 값이 1만큼 증가.

           ex) mov eax, 1

               inc eax   <-eax의 값이 2로 값이 증가.

 

DEC oper - Decrement

           oper의 값이 1만큼 감소.

           ex) mov eax, 1

               dec eax   <-eax의 값이 0으로 감소.

 

STD - Set Direction.

      DF를 1로 설정.

 

CLD - Clear Direction.

      DF를 0으로 설정.

 

CMC - Complement Carry

      캐리 플래그를 반전시킨다.

      1이면 0, 0이면 1로 만든다.

 

STC - Set Carry

      캐리 플래그를 1로 만든다.

 

CLC - Clear Carry

      캐리 플래그를 0으로 만든다.



출처- http://blog.naver.com/coool219?Redirect=Log&logNo=60114153387

[출처] 리버싱 기초 1 |작성자 초딩코딩


'CAT-Security > 미분류' 카테고리의 다른 글

[Defcon 21 ctf] policebox  (0) 2014.04.08
Python 예외처리  (0) 2014.01.09
리버싱의 기초 정리  (0) 2013.07.23
MBR 덤프해서 16비트 어셈블리 코드로 보는방법  (0) 2013.07.22
MBR (Master Boot Record) 정리  (0) 2013.07.22
ASProtect 2.1 MUP 정리  (1) 2013.06.18

댓글(0)

MBR 덤프해서 16비트 어셈블리 코드로 보는방법

CAT-Security/미분류|2013.07.22 13:09

MBR 덤프해서 ASSEMBLY 코드로 보는방법


1. HxD 다운 / NASM 다운

HxD

NASM

2. HxD로 MBR Binary 덤프
HxD 설치 후 DISK 아이콘 선택
1440
디스크 중에서 물리 디스크 - MBR 분석할 물리 디스크를 선택 후 수락
1440
읽어보면 0000:0000부터 섹터 0만큼(512BYTE)가 MBR 영역이므로 해당 영역만 복사해서 새 파일로 만듬.
1440
새 파일 - 붙여넣기로 512바이트 영역 생성
1440
다른 이름으로 저장 - mbr.bin
1440
설치된 nasm 폴더내의 ndisasm.exe로 바이너리 이미지를 16비트 어셈블리로 변경
ndisasm.exe -b16(16비트 어셈블리) -o7c00h(base index지정) -a -s7c3eh mbr.bin > mbr.asm
680
나온 어셈블리 파일을 확인


'CAT-Security > 미분류' 카테고리의 다른 글

Python 예외처리  (0) 2014.01.09
리버싱의 기초 정리  (0) 2013.07.23
MBR 덤프해서 16비트 어셈블리 코드로 보는방법  (0) 2013.07.22
MBR (Master Boot Record) 정리  (0) 2013.07.22
ASProtect 2.1 MUP 정리  (1) 2013.06.18
AsPack MUP 정리  (2) 2013.04.05

댓글(0)

MBR (Master Boot Record) 정리

CAT-Security/미분류|2013.07.22 02:05

 

 
운영체제가 부팅될 때 POST(Power On Self-Test) 과정을 마친 후 저장매체의 첫 번째 섹터를 호출되는데 이때 해당 부트 코드가 수행된다. 부트 코드의 주 역할은 파티션 테이블에서 부팅 가능한 파티션을 찾아 해당 파티션의 부트 섹터(boot sector)를 호출해주는 역할을 한다. 만약, 부팅 가능한 파티션이 없을 경우에는 미리 정의된 에러 메시지를 출력한다.

다음 표는 MBR 각 영역에 대한 세부적인 데이터구조를 나타낸다.

범위 (Byte Range) 설명 (Decription)크기 (Size)
10 진수16 진수
 0 – 445 0×0000 – 0x01BD Boot code 446 bytes
 446 – 461 0x01BE – 0x01CD Partition table entry #1 16 bytes
 462 – 477 0x01CE - 0x01DD Partition table entry #2 16 bytes
 478 – 493 0x01DE – 0x01ED Partition table entry #3 16 bytes
 494 – 509 0x01EE – 0x01FD Partition table entry #4 16 bytes
 510 – 511 0x01FE – 0x01FF Signature (0x55AA) 2 bytes

 
파티션 테이블은 각각 16 바이트씩 4개의 엔트리를 가지고 있다. 따라서 이러한 구조만 가진다면 하나의 볼륨(MBR을 갖는 볼륨)에서 파티션은 4개 밖에 생성할 수 없을 것이다. 과연 그럴까?

부팅 가능한 주 파티션을 생성한다면 4개 밖에 생성할 수 없다. 따라서, 멀티부팅을 할 경우 총 4개까지 운영체제를 설치 할 수 있을 것이다. 다만, 별도의 프로그램을 통해 MBR 영역이 아닌 볼륨의 다른 영역에 주 파티션 정보를 기록하여 연결해주는 경우도 있지만 사용해본 결과 별로 권하고 싶지는 않다.주 파티션이 아닌 데이터 저장을 위한 논리 파티션은 4개 이상 생성하는 것이 가능하다. 이는 다음 포스팅에서 자세히 살펴볼 것이다.

다음은 16 바이트의 파티션 테이블 엔트리의 세부적인 데이터구조이다.

범위 (Byte Range) 설명 (Decription)크기 (Size)
10 진수16 진수
 0 – 0 0×0000 – 0×0000 Boot Indicator

00 = do not use for booting

80 = system partition

 1 byte
 1 – 3 0×0001 – 0×0003 Starting CHS address 3 bytes
 4 – 4 0×0004 - 0×0004 Partition type 1 byte
 5 – 7 0×0005 – 0×0007 Ending CHS address 3 bytes
 8 – 11 0×0008 – 0x000B Starting LBA address 4 bytes
 12 – 15 0x000C – 0x000F Total sectors 4 bytes

 
부트 지시자(boot indecator)는 해당 파티션이 부탕 가능한 파티션인지를 나타낸다. 0×80 값을 가질 경우 부팅 가능한 파티션을 의미하고, 0×00 값을 가질 경우 부팅이 가능하지 않은 파티션을 나타낸다. 그리고 CHS 주소 값이 나오는데 현재는 거의 대부분 LBA 모드를 사용하므로 사용되지 않고 있다. 그리고 해당 파티션의 시작 위치를 가르키는 LBA 주소 값과 파티션 전체의 섹터 수가 나온다. CHS와 다르게 LBA 주소의 마지막을 표시하지 않는 이유는 시작 LBA 주소에 섹터의 크기를 더하면  마지막 주소를 알 수 있기 때문이다.

4번째 바이트는 해당 파티션의 타입을 나타낸다. 4번째 필드를 System ID와 Partition type으로 구분하는 경우도 있지만 여기서는 파티션 타입으로 모두 정의한다.

 16진수 설명 (Description)
 00h Empty
 01h DOS 12-bit FAT
 02h XENIX root file system
 03h XENIX /usr file system (obsolete)
 04h DOS 16-bit FAT (up to 32M)
 05h DOS 3.3+ extended partition
 06h DOS 3.31+ Large File System (16-bit FAT, over 32M)
 07h Advanced Unix
 07h exFAT
 07h OS/2 HPFS
 07h Windows NT NTFS
 08h OS/2 (v1.0-1.3 only)
 08h AIX bootable partition, SplitDrive
 08h Commodore Dos
 08h DELL partition spanning multiple drives
 09h AIX data partition
 0Ah OPUS
 0Ah Coherent swap partition
 0Ah OS/2 Boot Manager
 0Bh Windows 95 with 32-bit FAT
 0Ch Windows 95 with 32-bit FAT (using LBA-mode INT 13 extensions)
 0Eh VFAT logical-block-addressable VFAT (same as 06h but using LBA)
 0Fh Extended LBA partition (same as 05h but using LBA)
 10h OPUS
 11h FAT12 OS/2 Boot Manager hidden 12-bit FAT partition
 12h Compaq Diagnostics partition
 14h FAT16 OS/2 Boot Manager hidden sub-32M 16-bit FAT partition
 16h FAT16 OS/2 Boot Manager hidden over-32M 16-bit FAT partition
 17h OS/2 Boot Manager hidden HPFS partition
 17h hidden NTFS partition
 18h ASTSuspend AST special Windows swap file (“Zoro-Volt Suspend” partition)
 19h Willowtech Willowtech Photon coS
 1Bh Windows hidden Windows95 FAT32 partition
 1Ch Windows hidden Windows 95 FAT32 partition (LBA-mode)
 1Eh Windows hidden LBA VFAT partition
 20h Willowsoft Overture File System (OFS1)
 21h [reserved] officially listed as reserved
 21h FSo2
 23h [reserved] officially listed as reserved
 24h NEC MS-DOS 3.x
 26h [reserved] officially listed as reserved
 31h [reserved] officially listed as reserved
 33h [reserved] officially listed as reserved
 34h [reserved] officially listed as reserved
 36h [reserved] officially listed as reserved
 38h Theos
 3Ch PowerQuest PartitionMagic recovery partition
 40h VENIX 80286
 41h Personal RISC Boot
 41h PowerPC boot partition
 42h SFS(Secure File System) by Peter Gutmann
 45h EUMEL/Elan
 46h EUMEL/Elan
 47h EUMEL/Elan
 48h EUMEL/Elan
 4Fh Obron boot/data partition
 50h OnTrack Disk Manager, read-only partition
 51h OnTrack Disk Manager, read/write partition
 51h NOVELL
 52h CP/M
 52h Microport System V/386
 53h OnTrack Disk Manager, write-only partition
 54h OnTrack Disk Manager (DDO)
 55h EZ-Drive (see also INT 13/AH=FFh “EZ-Drive”)
 56h GoldenBow VFeature
 5Ch Priam EDISK
 61h SpeedStor
 63h Unix SysV/386, 386/ix
 63h Mach, MtXinu BSD 4.3 on Mach
 63h GNU-HURD
 64h Novell Netware 286
 64h SpeedStore
 65h Novell NetWare (3.11)
 67h Novell
 68h Novell
 69h Novell NSS Volume
 70h DiskSecure Multi-Boot
 71h [reserved] officially listed as reserved
 73h [reserved] officially listed as reserved
 74h [reserved] officially listed as reserved
 75h PC/IX
 76h [reserved] officially listed as reserved
 7Eh F.I.X
 80h Minix v1.1 – 1.4a
 81h Minix v1.4b+
 81h Linux
 81h Mitac Advanced Disk Manager
 82h Linux Swap partition
 82h Prime
 82h Solaris (Unix)
 83h Linux native file system (ex2fs/xiafs)
 84h DOS OS/2-renumbered type 04h partition (hiding DOS C: drive)
 85h Linux EXT
 86h FAT16 volume/stripe set (Windows NT)
 87h HPFS Fault-Tolerant mirrored partition
 87h NTFS volume/stripe set
 93h Amoeba file system
 94h Amoeba bad block table
 98h Datalight ROM-DOS SuperBoot
 99h Mylex EISA SCSI
 A0h Phoenix NoteBIOS Power Management “Save-to-Disk” partition
 A1h [reserved] officially listed as reserved
 A3h [reserved] officially listed as reserved
 A4h [reserved] officially listed as reserved
 A5h FreeBSD, BSD/386
 A6h OpenBSD
 A9h NetBSD
 B1h [reserved] officially listed as reserved
 B3h [reserved] officially listed as reserved
 B4h [reserved] officially listed as reserved
 B6h [reserved] officially listed as reserved
 B6h Windows NT mirror set (master), FAT16 file system
 B7h BSDI file system (secondarily swap)
 B7h Windows NT mirror set (master), NTFS file system
 B8h BSDI swap partition (secondarily file system)
 BEh Solaris boot partition
 C0h CTOS
 C0h DR-DOS/Novell DOS secured partition
 C1h DR-DOS6.0 LOGIN.EXE-secured 12-bit FAT partition
 C4h DR-DOS6.0 LOGIN.EXE-secured 16-bit FAT partition
 C6h DR-DOS6.0 LOGIN.EXE-secured 12-bit Huge partition
 C6h corrupted FAT16 volume/stripe set (Windows NT)
 C6h Windows NT mirror set (slave), FAT16 file system
 C7h Syurinx Boot
 C7h corrupted NTFS volume/stripe set
 C7h Windows NT mirror set (slave), NTFS file system
 CBh DR-DOS/OpenDOS secured FAT32
 CCh DR-DOS secured FAT32 (LBA)
 CEh DR-DOS secured FAT16 (LBA)
 D0h Multiuser DOS secured FAT12
 D1h Old Multiuser DOS secured FAT12
 D4h Old Multiuser DOS secured FAT16 (<=32M)
 D5h Old Multiuser DOS secured extended partition
 D6h Old Multiuser DOS secured FAT16 (>32M)
 D8h CP/M-86
 DBh Concurrent CP/M, Concurrent DOS
 DBh CTOS (Convergent Technologies OS)
 E1h SpeedStor 12-bit FAT extended partition
 E2h DOS read-only (Florian Painke’s XFDISK 1.0.4)
 E3h DOS read-only
 E3h Storage Dimensions
 E4h SpeedStor 16-bit FAT extended partition
 E5h [reserved] officially listed as reserved
 E6h [reserved] officially listed as reserved
 EBh BeOS BFS (BFS1)
 F1h Storage Dimensions
 F2h DOS 3.3+ secondary partition
 F3h [reserved] officially listed as reserved
 F4h SpeedStor
 F4h Storage Dimensions
 F5h Prologue
 F6h [reserved] officially listed as reserved
 FBh VMware partition
 FEh LANstep
 FEh IBM PS/2 IML (Initial Microcode Load) partition
 FFh Xenix bad block table
 FMh VMware raw partition

(http://www.datarecovery.com/hexcodes.asp)
 
다음은 실제 내 컴퓨터의 MBR영역이다.

가운데 파란색으로 표시된 영역이 부트 코드를 수행하면서 정상적이지 않은 동작이 발생할 경우 출력하는 3가지 종류의 에러 메시지들이다.

  • Invalid partition table
  • Error loading operating system
  • Missing operationg system

다음 초록색으로 표시된 부분은 파티션 테이블을 나타낸다. 현재 해당 볼륨에 두개의 파티션이 존재하며, 첫 번째 파티션은 부팅가능한 파티션임을 알 수 있다. 각 파티션의 용량을 계산하면 다음과 같다.

  • Partition #1 : Total Sectors (07 53 04 62) = 58 GB
  • Partition #2 : Total Sectors (15 C9 40 E0) = 174 GB

각 파티션의 타입과 파티션의 시작위치를 살펴보면 다음과 같다.

  • Partition #1 : Type (07h = Windows NT NTFS), Starting LBA addresses (00 00 00 3F)
  • Partition #2 : Type (05h = DOS extended partition), Starting LBA addresses (07 53 04 A1)

그리고 마지막으로 MBR의 시그니처 값인 0x55AA가 오는 것을 알 수 있다.
 
 
그렇다면 파란색과 초록색 사이의 부분은 어떤 역할을 하는 걸까?

결론은 OS 버전에 따라 추가적인 부트 코드와 에러 메시지 지정, 장치의 GUID 값을 저장하고 있다. Windows 2000 (with SP3) 의 경우 해당 영역에 “C:WINNT\System32dmadmin.exe” 파일을 호출하는 코드가 들어간다. 이외에도 각 OS 버전에 따라 추가적인 파일을 호출하는 구문이 들어간다. http://thestarman.narod.ru/asm/mbr/WTC.htm

그리고 추가적인 코드 외에도 기본으로 에러 메시지 지정 코드와 장치의 GUID 값을 저장한다. 위의 MBR 덤프를 살펴보면 오프셋 437 – 439 위치에 “2C 44 64″ 값이 오는 것을 알 수 있다. 이것은 부트 코드 수행도중 에러 발생 시 에러 메시지의 위치를 지정하기 위한 것이다. MBR 영역은 부팅과 함께 메모리의 0000:7C00 번지에 로드된 후 0000:0600 번지로 이동한다.

이동한 상태에서 각 값의 위치(“072C”, “0744″, “0763″)는 각 에러메시지의 위치를 나타낸다. 이것에 대한 적당한 용어가 없으므로 에러 메시지 네비게이터(Error Message Navigator)라고 하자.

0000:072C : “Invalid partition table”
0000:0744 : “Error loading operating system”
0000:0763 : “Missing operating system”

하지만 이 값은 Windows 영문버전에서만 적용된다. 다음과 같이 독일어 버전에서는 오류메시지의 길이의 변화로 인해 값이 다르다. 그렇다면 한국어 버전에서는 왜 영어가 출력될까? 한글은 2 바이트를 쓰기 때문에 16 비트의 BIOS 상에서 해당 오류메시지를 출력하려면 기존에 설계된 코드 외에 추가적으로 많은 수정이 필요하기 때문일 것이다.

(http://thestarman.narod.ru/asm/mbr/Win2kmbr.htm)

그리고 에러 메시지 네이게이터 다음에 오는 4 바이트 (오프셋 440 – 443)은 마운트된 장치의 GUID 값으로 사용된다. MBR GUID에 대해서는 이전 글(Mounted Devices GUID Analysis)을 참조하자.

Tagged with: 





'CAT-Security > 미분류' 카테고리의 다른 글

리버싱의 기초 정리  (0) 2013.07.23
MBR 덤프해서 16비트 어셈블리 코드로 보는방법  (0) 2013.07.22
MBR (Master Boot Record) 정리  (0) 2013.07.22
ASProtect 2.1 MUP 정리  (1) 2013.06.18
AsPack MUP 정리  (2) 2013.04.05
[api]모달과 모달리스의 차이  (0) 2013.03.25

댓글(0)