코드엔진 사이트에 들어가 basic7 문제를 다운로드 받고 압축을 푼다(비밀번호 : codeengn)
우선 Exeinfo PE로 파일을 확인해보자.
패킹은 되어있지 않으니 olldbg로 정확한 분석 ㄱ
를 하기전에 프로그램을 실행시켜 보면
시리얼 넘버를 입력받아 맞으면 통과 아니면 에러인 단순한 프로그램 인 것 같다.
진짜로 ollydbg로 정확한 분석 ㄱㄱ
Text Strings 를 확인해보면 에러, 통과 분기점과 시리얼 넘버처럼 보이는 숫자들이 보인다.
이동해서 확인해보자.
여러 함수들이 보인다.
정리해보자.
(더보기를 눌러주세용 (__) )
-(0040106C ~ 00401078) GetDIgItemTextA
UINT WINAPI GetDlgItemText(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_Out_ LPTSTR lpString, /* 입력받은 텍스트를 저장하는 부분 */
_In_ int nMaxCount
);
대화상자에서 텍스트에 관한 정보를 얻는 함수인 GetDlgItemText 를 이용해서 사용자가 입력한 시리얼에 대한 정보를 얻고있는 부분. 어셈블리어 코드를 통해서 보면 아래와 같이 입력되어 있다.
0040106C | PUSH 25 | Count=25 (37.) | nMaxCount |
0040106E | PUSH 07.00402324 | Buffer=07.00402324 | IpString |
00401073 | PUSH 68 | ControlID=68 (104.) | nIDDIgItem |
00401075 | PUSH DWORD PTR SS:[EBP+8] | hWnd | hDlg |
00401078 | CALL <JMP.&USER32.GetDlgItemTextA> | GetDIgItemTextA | GetDIgltemText |
=> 우리가 시리얼 입력칸에 입력한 값이 07.00402324 주소에 저장된다.
-(0040107D ~ 00401099) GetVolumeInformationA
BOOL WINAPI GetVolumeInformation(
_In_opt_ LPCTSTR lpRootPathName,
_Out_opt_ LPTSTR lpVolumeNameBuffer, /* 이름을 저장하는 버퍼 */
_In_ DWORD nVolumeNameSize,
_Out_opt_ LPDWORD lpVolumeSerialNumber,
_Out_opt_ LPDWORD lpMaximumComponentLength,
_Out_opt_ LPDWORD lpFileSystemFlags,
_Out_opt_ LPTSTR lpFileSystemNameBuffer,
_In_ DWORD nFileSystemNameSize
);
지정된 루트 디렉터리에 관한 시스템 볼륨 정보를 얻는 함수인 GetVolumeInformation 를 이용해서 볼륨 정보를 얻고 있는부분이다.
다양한 정보가 입력되지만 우리가 주목할부분은 드라이브의 이름에 대한 부분이다. 여기서는 VolumeNameBuffer에 드라이브의 이름이 저장된다.
0040107D | PUSH 0 | pFileSystemNameSize = NULL | nFileSystemNameSize |
0040107F | PUSH 0 | pFileSystemNameBuffer = NULL | lpFileSystemNameBuffer |
00401081 | PUSH 07.004020C8 | pFileSystemFlags = 07.004020C8 | lpFileSystemFlags |
00401086 | PUSH 07.00402190 | pMaxFilenameLength = 07.00402190 | lpMaximumComponentLength |
0040108B | PUSH 07.00402194 | pVolumeSerialNumber = 07.00402194 | lpVolumeSerialNumber |
00401090 | PUSH 32 | MaxVolumeNameSize = 32 (50.) | nVolumeNameSize |
00401092 | PUSH 07.0040225C | VolumeNameBuffer = 07.0040225C | lpVolumeNameBuffer |
00401097 | PUSH 0 | RootPathName = NULL | lpRootPathName |
00401099 | CALL 00401153 | GetVolumeInformationA | GetVolumeInformation |
=> 우리가 원하는 드라이브의 이름은 0040225C에 저장된다. 이 주소를 이용하면 드라이브 이름을 임의로 변경 할 수 있다.
-(0040109E ~ 004010A8) Istrcat
LPTSTR WINAPI lstrcat(
_Inout_ LPTSTR lpString1, /* ConcatString */
_In_ LPTSTR lpString2 /* StringToAdd */
);
lpString1(ConcatString) + lpString2(StringToAdd) 값을 반환하는 함수. 어셈블리 코드를 통해서 보면 아래와 같다.
0040109E | PUSH 07.004023F3 | StringToAdd = "4562-ABEX" | IpString2 |
004010A3 | PUSH 07.0040225C (디스크 이름) | ConcatString = "" | IpString1 |
004010A8 | CALL <JMP.&KERNEL32.IstrcatA> | IstrcatA | Istrcat |
" " + "4562-ABEX" 값인 "4562-ABEX" 를 반환해 0040225C에 저장한다.
![](https://blog.kakaocdn.net/dn/lmP50/btqC5n5HNSH/v9xNP8y29dQsmFiPACPN9K/img.png)
-(004010AD ~ 004010CD) 연산
0040225C ~ 0040225F 값들을 어셈블리 명령어로 아래와 같이 연산한다.
004010AD | MOV DL,2 | DL 의 값을 2로 설정한다. |
004010AF | ADD DWORD PTR DS:[40225C],1 | 40225C 값에 1을 더한다. |
004010B6 | ADD DWORD PTR DS:[40225D],1 | 40225D 값에 1을 더한다. |
004010BD | ADD DWORD PTR DS:[40225E],1 | 40225E 값에 1을 더한다. |
004010C4 | ADD DWORD PTR DS:[40225F],1 | 40225F 값에 1을 더한다. |
004010CB | DEC DL | DL 의 값에서 1을 뺀다. |
004010CD | JNZ SHORT 07.004010AF | DL의 값이 0인지검사하고 0이 아니면 004010AF로 점프한다. |
=> 0040225C (디스크 이름 저장 주소) 의 4자리 값들에 대해서 2씩 더해주는 연산을하고 있는것이다. 만약에 디스크이름이 Codeengn 이라면 Code 값이 2번 증가한 값 + "engn" 이 될것이다.
-(004010CF ~ 004010E8) IstractA
"L2C - 5781" 과 "6784 - ABEX" 값을 더해서 "LC2 - 57816784 - ABEX" 값을 더해서 00402000에 주소에 반환한다. (위에서 서술한 내용과 같으므로 생략)
![](https://blog.kakaocdn.net/dn/yILbe/btqC5poYykY/Xh8UYN2yh3UDUWPBDxrm1k/img.png)
-(004010ED ~ 004010F7) IstrcmpiA
사용자가 입력한 시리얼값과 위에서 만들어진 시리얼값(LC2 - 57816784 - ABEX)을 IstrcmpiA 함수를 이용해 비교한다.
![](https://blog.kakaocdn.net/dn/pEJS2/btqC79MbmQg/PYO070TvizqCCPcFvjSn31/img.png)
위의 과정을 거쳐 입력값과 시리얼값이 같다면 인증 성공!
#004010FF 의 점프 분기문을 무조건 성공 MessageBoxA로 점프시키면 어떤 시리얼 값을 넣어도 인증 성공되는 크랙버젼을 만들 수 있다.
'[Riversing] > [코드엔진] BASIC' 카테고리의 다른 글
[코드엔진] basic9 (0) | 2020.03.31 |
---|---|
[코드엔진] basic8 (0) | 2020.03.31 |
[코드엔진] basic6 (0) | 2020.03.25 |
[코드엔진] basic5 (0) | 2020.03.25 |
[코드엔진] basic4 (0) | 2020.03.24 |