키젠 만들기 두번재 (어려운거)
요번에 크랙하려는 프로그램은 이전 문서와 별로 다른 부분이 없습니다.
단지, 키젠을 생성하는 루틴이 조금 어려울 뿐 입니다.
이전 문서까지는 이 문서를 보시는 분들이 정말로 처음 접한다고 생각하면서 설명을 하였지만
지금까지 올리 디버거에 기초적인 인터페이스와 크랙 방법에 대해서 어느정도 설명이 되었다고 생각하여 중요한 부분에 대해서만 적을까합니다.
( 물론 설명이 되지 않는 부분이 있다면 이전과 같은 방식으로 매우 자세하게 설명할 생각입니다. )
위에 파일을 풀어보시면 키젠도 같이 만들어져 있으며 Delphi7로 컴파일되어 있습니다.
밑에 코드는 키젠을 만들기 위해 분석해야 할 Exe파일의 디스어셈블링 된 코드이며 관련 된 부분은 모두 주석으로 처리되어 있습니다.
0040144E . 8D85 E0FEFFFF LEA EAX,DWORD PTR SS:[EBP-120] ; SS:[EBP-120] 의 이름을 넣을 버퍼 주소
00401454 . 50 PUSH EAX
00401455 . 68 AD124000 PUSH Make_Key.004012AD ; /format = "%s"
0040145A . E8 19040000 CALL <JMP.&MSVCRT.SCANF> ; \scanf 함수를 이용해서 이름을 읽어들임
0040145F . 83C4 10 ADD ESP,10 ; scanf 함수 호출 후 SS:[EBP-120] 의 이름이 들어감
00401462 . 83C4 F4 ADD ESP,-0C
00401465 . 8D85 E0FEFFFF LEA EAX,DWORD PTR SS:[EBP-120] ; 이름의 주소를 EAX 에 넣는다.
0040146B . 50 PUSH EAX ; /s
0040146C . E8 FF030000 CALL <JMP.&MSVCRT.STRLEN> ; \strlen - 이름의 길이를 체크한다.
00401471 . 83C4 10 ADD ESP,10 ; 이름의 길이가 EAX 레지스터에 들어간다.
00401474 . 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX ; "aaaa" 라고 입력했다면 길이는 4 이다.
00401477 . 837D E8 03 CMP DWORD PTR SS:[EBP-18],3 ; 이름의 길이와 3 이라는 값을 비교한다.
0040147B . 7E 08 JLE SHORT Make_Key.00401485 ; 이름의 길이가 3 보다 작거나 같다면 0x401485 로 점프
0040147D . 837D E8 0E CMP DWORD PTR SS:[EBP-18],0E ; 이름의 길이와 14 라는 값을 비교한다.
00401481 . 7F 02 JG SHORT Make_Key.00401485 ; 이름의 길이가 14 보다 크다면 0x401485
00401483 . EB 2B JMP SHORT Make_Key.004014B0 ; 길이를 체크하는 조건이 일치했다면 0x4014B0 로 점프
00401485 > 83C4 F4 ADD ESP,-0C ; 이름의 길이가 3 보다 작을 때 이 부분이 실행된다.
00401488 . 68 B0124000 PUSH Make_Key.004012B0 ; /format = "
Attention ! 3 < Nom < 15
"
0040148D . E8 EE030000 CALL <JMP.&MSVCRT.PRINTF> ; \printf
00401492 . 83C4 10 ADD ESP,10
00401495 . 83C4 F4 ADD ESP,-0C
00401498 . 68 CC124000 PUSH Make_Key.004012CC ; /command = "pause"
0040149D . E8 C6030000 CALL <JMP.&MSVCRT.SYSTEM> ; \system
004014A2 . 83C4 10 ADD ESP,10
004014A5 . 31C0 XOR EAX,EAX
004014A7 . E9 B4020000 JMP Make_Key.00401760
004014AC 8D7426 00 LEA ESI,DWORD PTR DS:[ESI]
004014B0 > 83C4 F4 ADD ESP,-0C ; 길이를 체크하고 조건에 맞으면 시리얼을 입력받음
004014B3 . 68 D2124000 PUSH Make_Key.004012D2 ; /format = "[x] Serial : "
004014B8 . E8 C3030000 CALL <JMP.&MSVCRT.PRINTF> ; \printf
004014BD . 83C4 10 ADD ESP,10
004014C0 . 83C4 F8 ADD ESP,-8
004014C3 . 8D85 A0FAFFFF LEA EAX,DWORD PTR SS:[EBP-560] ; SS:[EBP-560] 의 시리얼키를 넣을 버퍼 주소
004014C9 . 50 PUSH EAX
004014CA . 68 AD124000 PUSH Make_Key.004012AD ; /format = "%s"
004014CF . E8 A4030000 CALL <JMP.&MSVCRT.SCANF> ; \scanf
004014D4 . 83C4 10 ADD ESP,10 ; scanf 함수 호출 후 SS:[EBP-560] 의 이름이 들어감
004014D7 . C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0 ; SS:[EBP-4] 에 값을 0 으로 초기화
004014DE . 89F6 MOV ESI,ESI
004014E0 > 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18] ; 이름의 길이가 SS:[EBP-18] 에 들어가 있다.
004014E3 . 89C2 MOV EDX,EAX ; EDX = EAX = 이름의 길이
004014E5 . 8D0412 LEA EAX,DWORD PTR DS:[EDX+EDX] ; 잘은 모르겠으나 EAX = EDX + EDX 와 같은 명령어
004014E8 . 3945 FC CMP DWORD PTR SS:[EBP-4],EAX ; 0 과 (이름의 길이 x 2) 을 비교한다.
004014EB . 7C 03 JL SHORT Make_Key.004014F0 ; (이름의 길이 x 2) 보다 0 이 작다면
004014ED . EB 31 JMP SHORT Make_Key.00401520 ; 이 부분에서 루프가 끝난다.
004014EF 90 NOP
004014F0 > 8D85 A0FDFFFF LEA EAX,DWORD PTR SS:[EBP-260] ; 잘은 모르겠지만 위에 코드 무시하고 여기서부터 실행
004014F6 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4] ; EDX = 0
004014F9 . 8D8D E0FEFFFF LEA ECX,DWORD PTR SS:[EBP-120] ; 이름의 주소를 ECX 에 넣음
004014FF . 8B5D F8 MOV EBX,DWORD PTR SS:[EBP-8] ; EBX = 0
00401502 . 8A0C0B MOV CL,BYTE PTR DS:[EBX+ECX] ; 이름의 첫 번째 값의 아스키 코드를 CL 에 저장
00401505 . 880C02 MOV BYTE PTR DS:[EDX+EAX],CL ; DS:[EDX+EAX] 는 아마도 프로그램상에 버퍼 공간
00401508 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; EAX = 0, 바로 위에 코드에서 이름의 첫 번째 값이 [EDX+EAX]
0040150B . 40 INC EAX ; EAX = 1
0040150C . 8D95 A0FDFFFF LEA EDX,DWORD PTR SS:[EBP-260] ; 아까와 같이 버퍼 공간의 주소를 EDX 에 저장
00401512 . C60410 20 MOV BYTE PTR DS:[EAX+EDX],20 ; [EAX+EDX][0] = 이름의 첫 번째 값, [EAX+EDX][1] = 0x20
00401516 . FF45 F8 INC DWORD PTR SS:[EBP-8] ; int 형 변수일 가능성이 높고 코드 실행 후 반드시 1 을 가짐
00401519 . 8345 FC 02 ADD DWORD PTR SS:[EBP-4],2 ; int 형 변수일 가능성이 높고 코드 실행 후 반드시 2 을 가짐
0040151D .^EB C1 JMP SHORT Make_Key.004014E0 ; 무조건 0x4014E0 으로 점프하는데 계속 루프를 돈다.
0040151F 90 NOP ; 밑에 스페이스바가 띄어진 것임에 유의
00401520 > 90 NOP ; SS:[EBP-260] = "이름[0] 이름[1] 이름[2] ".................
00401521 . C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0 ; SS:[EBP-4] 를 0 으로 초기화. int 형일 가능성 99%
00401528 > 83C4 F4 ADD ESP,-0C
0040152B . 8D85 A0FEFFFF LEA EAX,DWORD PTR SS:[EBP-160] ; 알 수 없는 이상한 값이 들어가 있다.
00401531 . 50 PUSH EAX ; /"-[#]]=}&&&+(=$*,,)&.*/+++[][;/.." + char($A7) + char($30)
00401532 . E8 39030000 CALL <JMP.&MSVCRT.STRLEN> ; \strlen
00401537 . 83C4 10 ADD ESP,10 ; 길이를 검사하는데 무조건 0x22 이다.
0040153A . 89C0 MOV EAX,EAX ; 아무런 의미가 없는 코드이며 CPU 가 아깝다.
0040153C . 3945 FC CMP DWORD PTR SS:[EBP-4],EAX ; ( 0x22 ) 루프를 다 돌았는가?
0040153F . 72 02 JB SHORT Make_Key.00401543 ; 않 돌았다.
00401541 . EB 2D JMP SHORT Make_Key.00401570 ; 루프를 다 돌았다. EBX = 0x31
00401543 > 8D85 A0FEFFFF LEA EAX,DWORD PTR SS:[EBP-160] ; "-[#]]=}&&&+(=$*,,)&.*/+++[][;/.." + char($A7)
00401549 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4] ; EDX = 0
0040154C . 8D8D A0FEFFFF LEA ECX,DWORD PTR SS:[EBP-160] ; "-[#]]=}&&&+(=$*,,)&.*/+++[][;/.." + char($A7)
00401552 . 8B5D FC MOV EBX,DWORD PTR SS:[EBP-4] ; EBX = 0
00401555 . 899D 9CFAFFFF MOV DWORD PTR SS:[EBP-564],EBX
0040155B . 8BB5 9CFAFFFF MOV ESI,DWORD PTR SS:[EBP-564] ; ESI = 0
00401561 . 8A1C0E MOV BL,BYTE PTR DS:[ESI+ECX] ; MOV BL, 0x2D 와 같은 문장
00401564 . FEC3 INC BL ; BL = 2E
00401566 . 881C02 MOV BYTE PTR DS:[EDX+EAX],BL ; 아무래도 BL 을 건드리는 루프 인 것 같다.
00401569 . FF45 FC INC DWORD PTR SS:[EBP-4] ; SS:[EBP-4] = 1
0040156C .^EB BA JMP SHORT Make_Key.00401528 ; 무조건 0x401528 로 점프.. 이부분에서 루프를 돈다.
0040156E 89F6 MOV ESI,ESI ; 위에 루프에서 문자열을 옮길때 맨 마지막에 쓰레기값이 들어감.
00401570 > 90 NOP ; "-[#]]=}&&&+(=$*,,)&.*/+++[][;/.." + char($A7) + char($30)
00401571 . C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0 ; SS:[EBP-4] = 0
00401578 > 83C4 F4 ADD ESP,-0C
0040157B . 8D85 A0FDFFFF LEA EAX,DWORD PTR SS:[EBP-260] ; SS:[EBP-260] = "이름[0] 이름[1] 이름[2] ".................
00401581 . 50 PUSH EAX ; /s
00401582 . E8 E9020000 CALL <JMP.&MSVCRT.STRLEN> ; \strlen
00401587 . 83C4 10 ADD ESP,10 ; 길이 체크.. 이름 길이 x 2 값이 EAX 에 들어감
0040158A . 89C0 MOV EAX,EAX ; "-[#]]=}&&&+(=$*,,)&.*/+++[][;/.." + char($A7) + char($30) 를 1 증가시킴
0040158C . 3945 FC CMP DWORD PTR SS:[EBP-4],EAX ; 증가시키면 ".\$^^>~''',)>%+--*'/+0,,,\^\<0//@" 이 된다.
0040158F . 72 02 JB SHORT Make_Key.00401593
00401591 . EB 41 JMP SHORT Make_Key.004015D4
00401593 > 8D85 A0FEFFFF LEA EAX,DWORD PTR SS:[EBP-160] ; ECX = SS[EBP-260] 이 들어간 상태
00401599 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
0040159C . 8D8D A0FDFFFF LEA ECX,DWORD PTR SS:[EBP-260] ; ECX 레지스터는 이름을 가르킨다.
004015A2 . 8B7D FC MOV EDI,DWORD PTR SS:[EBP-4]
004015A5 . 89BD 9CFAFFFF MOV DWORD PTR SS:[EBP-564],EDI
004015AB . 8DB5 A0FEFFFF LEA ESI,DWORD PTR SS:[EBP-160]
004015B1 . 8B5D FC MOV EBX,DWORD PTR SS:[EBP-4]
004015B4 . 899D 8CFAFFFF MOV DWORD PTR SS:[EBP-574],EBX
004015BA . 8BBD 9CFAFFFF MOV EDI,DWORD PTR SS:[EBP-564] ; 변경 된 이름의 값을 이상한 값과 xor 연산 시킨다.
004015C0 . 8A1C0F MOV BL,BYTE PTR DS:[EDI+ECX] ; char S[100] = ".\$^^>~''',)>%+--*'/+0,,,\^\<0//@";
004015C3 . 8BBD 8CFAFFFF MOV EDI,DWORD PTR SS:[EBP-574] ; S[i] = Name[i] Xor S[i]
004015C9 . 321C37 XOR BL,BYTE PTR DS:[EDI+ESI]
004015CC . 881C02 MOV BYTE PTR DS:[EDX+EAX],BL
004015CF . FF45 FC INC DWORD PTR SS:[EBP-4]
004015D2 .^EB A4 JMP SHORT Make_Key.00401578
004015D4 > 90 NOP ; 여기서부터 주석달기 귀찮음으로 그냥 대충 달기로 한다.
004015D5 . 83C4 F4 ADD ESP,-0C
004015D8 . 8D85 A0FEFFFF LEA EAX,DWORD PTR SS:[EBP-160]
004015DE . 50 PUSH EAX ; /s
004015DF . E8 8C020000 CALL <JMP.&MSVCRT.STRLEN> ; \strlen
004015E4 . 83C4 10 ADD ESP,10
004015E7 . 89C0 MOV EAX,EAX ; 무조건 0x22
004015E9 . 8D50 FF LEA EDX,DWORD PTR DS:[EAX-1]
004015EC . 8955 FC MOV DWORD PTR SS:[EBP-4],EDX ; EDX = SS:[EBP-4] = 0x21
004015EF . 90 NOP
004015F0 > 837D FC 00 CMP DWORD PTR SS:[EBP-4],0 ; SS:[EBP-4] = 0x21
004015F4 . 7D 02 JGE SHORT Make_Key.004015F8
004015F6 . EB 20 JMP SHORT Make_Key.00401618
004015F8 > 8D85 A0FCFFFF LEA EAX,DWORD PTR SS:[EBP-360]
004015FE . 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
00401601 . 8D8D A0FEFFFF LEA ECX,DWORD PTR SS:[EBP-160] ; ECX 는 알 수 없는 문자열
00401607 . 8B5D FC MOV EBX,DWORD PTR SS:[EBP-4] ; EBX = 0x21
0040160A . 8A0C0B MOV CL,BYTE PTR DS:[EBX+ECX]
0040160D . 880C02 MOV BYTE PTR DS:[EDX+EAX],CL
00401610 . FF45 F4 INC DWORD PTR SS:[EBP-C]
00401613 . FF4D FC DEC DWORD PTR SS:[EBP-4]
00401616 .^EB D8 JMP SHORT Make_Key.004015F0
00401618 > 90 NOP
00401619 . C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0
00401620 > 83C4 F4 ADD ESP,-0C
00401623 . 8D85 A0FCFFFF LEA EAX,DWORD PTR SS:[EBP-360] ; SS:[EBP-360] 에는 알 수 없는 문자열
00401629 . 50 PUSH EAX ; /s
0040162A . E8 41020000 CALL <JMP.&MSVCRT.STRLEN> ; \strlen
0040162F . 83C4 10 ADD ESP,10
00401632 . 89C0 MOV EAX,EAX
00401634 . 3945 FC CMP DWORD PTR SS:[EBP-4],EAX
00401637 . 72 07 JB SHORT Make_Key.00401640
00401639 . EB 45 JMP SHORT Make_Key.00401680
0040163B 90 NOP
0040163C 8D7426 00 LEA ESI,DWORD PTR DS:[ESI]
00401640 > 8D85 A0FBFFFF LEA EAX,DWORD PTR SS:[EBP-460] ; EAX = SS:[EBP-460]
00401646 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4] ; EDX = 0
00401649 . 8D8D A0FCFFFF LEA ECX,DWORD PTR SS:[EBP-360] ; ECX 는 알 수 없는 문자열
0040164F . 8B5D F0 MOV EBX,DWORD PTR SS:[EBP-10] ; EBX = 0
00401652 . 8A0C0B MOV CL,BYTE PTR DS:[EBX+ECX] ; [EBP-360][i] 을 CL 로
00401655 . 880C02 MOV BYTE PTR DS:[EDX+EAX],CL ; [EBP-360][i] 을 EBP-460 으로
00401658 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; i
0040165B . 40 INC EAX ; i = i + 1;
0040165C . 8D95 A0FBFFFF LEA EDX,DWORD PTR SS:[EBP-460] ; EDX = EBP-460
00401662 . 8D8D A0FEFFFF LEA ECX,DWORD PTR SS:[EBP-160] ; ECX = EBP-160
00401668 . 8B5D EC MOV EBX,DWORD PTR SS:[EBP-14] ; EBX = 0
0040166B . 8A0C0B MOV CL,BYTE PTR DS:[EBX+ECX] ; CL = EBP-160[i]
0040166E . 880C10 MOV BYTE PTR DS:[EAX+EDX],CL ; EBP-460[i] = EBP-160[j]
00401671 . FF45 F0 INC DWORD PTR SS:[EBP-10]
00401674 . FF45 EC INC DWORD PTR SS:[EBP-14]
00401677 . 8345 FC 02 ADD DWORD PTR SS:[EBP-4],2
0040167B .^EB A3 JMP SHORT Make_Key.00401620
0040167D 8D76 00 LEA ESI,DWORD PTR DS:[ESI]
00401680 > 90 NOP
00401681 . C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0 ; SS:[EBP-4] 를 0 으로 초기화
00401688 > 83C4 F4 ADD ESP,-0C ; 이 부분에서부터 루프를 도는 것으로 추정
0040168B . 8D85 A0FBFFFF LEA EAX,DWORD PTR SS:[EBP-460] ; 알 수 없는 값이 들어가 있음.
00401691 . 50 PUSH EAX ; /s
00401692 . E8 D9010000 CALL <JMP.&MSVCRT.STRLEN> ; \strlen
00401697 . 83C4 10 ADD ESP,10 ; 무조건 길이는 0x22 고 EAX 에 들어감
0040169A . 89C0 MOV EAX,EAX
0040169C . 3945 FC CMP DWORD PTR SS:[EBP-4],EAX
0040169F . 72 02 JB SHORT Make_Key.004016A3 ; SS:[EBP-4] < 0x22 라면 점프
004016A1 . EB 32 JMP SHORT Make_Key.004016D5
004016A3 > 8D85 A0FBFFFF LEA EAX,DWORD PTR SS:[EBP-460] ; 문자열을 하나하나씩 비교
004016A9 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4] ; EDX = 0
004016AC . 803C02 1F CMP BYTE PTR DS:[EDX+EAX],1F ; 1F 보다 작은가? 작다면 0x4016C3
004016B0 . 7E 11 JLE SHORT Make_Key.004016C3
004016B2 . 8D85 A0FBFFFF LEA EAX,DWORD PTR SS:[EBP-460]
004016B8 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
004016BB . 803C02 7A CMP BYTE PTR DS:[EDX+EAX],7A ; 0x7A 보다 큰가? 크다면 0x4016C3 으로 점프
004016BF . 7F 02 JG SHORT Make_Key.004016C3
004016C1 . EB 0D JMP SHORT Make_Key.004016D0 ; ( 비교값 <=1F ) and ( 비교값 > 0x7A ) 이라면 0x4016D0 으로 점프
004016C3 > 8D85 A0FBFFFF LEA EAX,DWORD PTR SS:[EBP-460]
004016C9 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
004016CC . C60402 36 MOV BYTE PTR DS:[EDX+EAX],36
004016D0 > FF45 FC INC DWORD PTR SS:[EBP-4]
004016D3 .^EB B3 JMP SHORT Make_Key.00401688
004016D5 > 90 NOP
004016D6 . C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0
004016DD . 8D76 00 LEA ESI,DWORD PTR DS:[ESI]
004016E0 > 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004016E3 . 3B45 E8 CMP EAX,DWORD PTR SS:[EBP-18] ; EAX 와 SS:[EBP-18] 을 비교해서, SS:[EBP-18] 이름의 길이
004016E6 . 7C 08 JL SHORT Make_Key.004016F0 ; EAX < SS:[EBP-18] 라면 루프를 계속 돈다.
004016E8 . EB 4B JMP SHORT Make_Key.00401735
004016EA 8DB6 00000000 LEA ESI,DWORD PTR DS:[ESI]
004016F0 > 8D85 A0FAFFFF LEA EAX,DWORD PTR SS:[EBP-560]
004016F6 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
004016F9 . 8D8D A0FBFFFF LEA ECX,DWORD PTR SS:[EBP-460]
004016FF . 8B5D FC MOV EBX,DWORD PTR SS:[EBP-4]
00401702 . 8A0402 MOV AL,BYTE PTR DS:[EDX+EAX]
00401705 . 3A040B CMP AL,BYTE PTR DS:[EBX+ECX]
00401708 . 74 26 JE SHORT Make_Key.00401730
0040170A . 83C4 F4 ADD ESP,-0C
0040170D . 68 E0124000 PUSH Make_Key.004012E0 ; /format = "
Mauvais mot de passe !
"
00401712 . E8 69010000 CALL <JMP.&MSVCRT.PRINTF> ; \printf
00401717 . 83C4 10 ADD ESP,10
0040171A . 83C4 F4 ADD ESP,-0C
0040171D . 68 CC124000 PUSH Make_Key.004012CC ; /command = "pause"
00401722 . E8 41010000 CALL <JMP.&MSVCRT.SYSTEM> ; \system
00401727 . 83C4 10 ADD ESP,10
0040172A . 31C0 XOR EAX,EAX
0040172C . EB 32 JMP SHORT Make_Key.00401760
0040172E 89F6 MOV ESI,ESI
00401730 > FF45 FC INC DWORD PTR SS:[EBP-4]
00401733 .^EB AB JMP SHORT Make_Key.004016E0
00401735 > 83C4 F4 ADD ESP,-0C
00401738 . 68 FA124000 PUSH Make_Key.004012FA ; /format = "
Yeah, c'est bon :]
"
0040173D . E8 3E010000 CALL <JMP.&MSVCRT.PRINTF> ; \printf
00401742 . 83C4 10 ADD ESP,10
00401745 . 83C4 F4 ADD ESP,-0C
00401748 . 68 CC124000 PUSH Make_Key.004012CC ; /command = "pause"
0040174D . E8 16010000 CALL <JMP.&MSVCRT.SYSTEM> ; \system
00401752 . 83C4 10 ADD ESP,10
00401755 . 31C0 XOR EAX,EAX
00401757 . EB 07 JMP SHORT Make_Key.00401760
00401759 . 8DB426 0000000>LEA ESI,DWORD PTR DS:[ESI]
00401760 > 8DA5 68FAFFFF LEA ESP,DWORD PTR SS:[EBP-598]
Microsoft Office OneNote 2007을 사용하여 작성했습니다.
모든 노트 및 정보를 한 곳에서 볼 수 있습니다.