Long time no see!
Dual입니다. :0
아주 오~~랜만에 활동시작 겸 RE에 관한 글을 써보고자 합니다.
주제는? File CRC Check 검사 우회하기(?) 입니다.
대상은 GomEncoder로 잡았는데요, 별 다른 이유가 있는 것은 아닙니다.
그런데 GomEnc가 CRC 체크를 하는 이유는 모르겠습니다(바이러스에 의한 손상검사?)
아시는 분은 댓글 좀 알려주세요. ;0
먼저 한번 생각해 보죠.
저번에 간단히 프로세스의 CRC체크를 우회(?)하는 방법에 대해서 다루었었습니다.
다른 프로세스의 메모리에 CRC 체크를 하는 경우에는 메모리 관련 API들을 후킹했었죠.
이번엔 File이니, 파일관련 API에 브레이크 포인트를 걸고 접근하면 된다는 건
간단하게 파악할 수 있는 요소입니다.
파일관련 API라면? 아무래도 파일의 핸들을 얻기 위한 CreateFile() 이라던지,
파일을 읽어오기 위한 ReadFile() 등이 있겠죠..?
물런 훨씬 다양한 방법으로 파일을 읽어올수도 있겠습니다만,
많은 Win32에플리케이션 제작자들은 해당 API를 많이 사용합니다.

음.. 네 먼저 곰인코더라는 바탕화면에 있는 빠른실행은GomEnc.exe라는 실행파일로
연결 되있네요. 하지만 사실은 이것은 버젼확인과 CRC체크등을 하는 런쳐일뿐,
실제 알맹이(?)는 GomEncMain.exe입니다.
이제 PEID로 GomEnc.exe 와 GomEncMain.exe의 패킹 여부를 알아 보도록 하죠.


런쳐님께선 패킹이 안되있으시고, 알맹이(?)님께서는 y0da로 패킹이 되게시네요.
사실GomEncMain.exe의 패킹여부는 그닥 중요하지 않겠네요.
왜냐면 오늘 글에서는 GomEnc.exe를 공략하는 거니까요. ;0
GomEnc.exe는 패킹도 되어 있지 않으니 한번 올리디버거로 열어서 ReadFile과
CreateFile에 BP(브레이크 포인트)를 잡아 보겠습니다.

0013BE90 0013FB10 |FileName =
"C:\Program Files\GRETECH\GomEncoder\GomEncMain.exe"
0013BE94 80000000 |Access = GENERIC_READ
0013BE98 00000001 |ShareMode = FILE_SHARE_READ
0013BE9C 00000000 |pSecurity = NULL
0013BEA0 00000003 |Mode = OPEN_EXISTING
0013BEA4 08000000 |Attributes = SEQUENTIAL_SCAN
0013BEA8 00000000 \hTemplateFile = NULL
핸들을 열어오는 대상이 GomEncMain.exe니, 올바르게 접근해 온 모양입니다.
0013BE98 00000090 |FileHandle
0013BE9C 0013BEB8 |Buffer
0013BEA0 00001000 |nNumberOfBytes
0013BEA4 0013CEBC |lpNumberOfBytesRead
0013BEA8 00000000 |lpOverlapped
자, 여기서 CRC값을 계산해내는 코드를 찾기 위해서 중요한 값이 무엇일까요?
답은 Buffer의 주소입니다. 그곳에 읽어온 값이 저장될 것이고, 프로그램 내에서는
그 곳에 저장된 값들을 가지고 계산을 할 것임으로, 결국 그 메모리에 ReadAccess
하는 코드를 찾으면, 그곳이 바로 CRC값을 계산해네는 곳이 되겠습니다.

(클릭해서 보세요)
음 MZ가 있는 것으로 보아, 파일의 처음부터 1000바이트 씩 읽어오는군요.
가장 앞에 'M'에 하드웨어 브레이크 포인트를 걸겠습니다.

이제 디버기를 run 시키면, 다음과 같은 코드에 와있게 됩니다.
0040102E 8BF0 MOV ESI,EAX
00401030 836D 10 08 SUB DWORD PTR SS:[EBP+10],8
00401034 23F1 AND ESI,ECX
00401036 33F3 XOR ESI,EBX
00401038 8BD8 MOV EBX,EAX
0040103A C1EB 08 SHR EBX,8
0040103D 8B04B5 90204000 MOV EAX,DWORD PTR DS:[ESI*4+402090]
00401044 33C3 XOR EAX,EBX
00401046 42 INC EDX
00401047 8BF0 MOV ESI,EAX
00401049 0FB61A MOVZX EBX,BYTE PTR DS:[EDX]
0040104C 23F1 AND ESI,ECX
0040104E 33F3 XOR ESI,EBX
00401050 0FB65A 01 MOVZX EBX,BYTE PTR DS:[EDX+1]
00401054 8B34B5 90204000 MOV ESI,DWORD PTR DS:[ESI*4+402090]
0040105B C1E8 08 SHR EAX,8
0040105E 33F0 XOR ESI,EAX
00401060 42 INC EDX
00401061 8BC6 MOV EAX,ESI
00401063 23C1 AND EAX,ECX
00401065 33C3 XOR EAX,EBX
00401067 0FB65A 01 MOVZX EBX,BYTE PTR DS:[EDX+1]
0040106B 8B0485 90204000 MOV EAX,DWORD PTR DS:[EAX*4+402090]
00401072 C1EE 08 SHR ESI,8
00401075 33C6 XOR EAX,ESI
00401077 42 INC EDX
00401078 8BF0 MOV ESI,EAX
0040107A 23F1 AND ESI,ECX
0040107C 33F3 XOR ESI,EBX
0040107E 0FB65A 01 MOVZX EBX,BYTE PTR DS:[EDX+1]
00401082 8B34B5 90204000 MOV ESI,DWORD PTR DS:[ESI*4+402090]
00401089 C1E8 08 SHR EAX,8
0040108C 33F0 XOR ESI,EAX
0040108E 42 INC EDX
0040108F 8BC6 MOV EAX,ESI
00401091 23C1 AND EAX,ECX
00401093 33C3 XOR EAX,EBX
00401095 0FB65A 01 MOVZX EBX,BYTE PTR DS:[EDX+1]
00401099 8B0485 90204000 MOV EAX,DWORD PTR DS:[EAX*4+402090]
004010A0 C1EE 08 SHR ESI,8
004010A3 33C6 XOR EAX,ESI
004010A5 42 INC EDX
004010A6 8BF0 MOV ESI,EAX
004010A8 23F1 AND ESI,ECX
004010AA 33F3 XOR ESI,EBX
004010AC 0FB65A 01 MOVZX EBX,BYTE PTR DS:[EDX+1]
004010B0 8B34B5 90204000 MOV ESI,DWORD PTR DS:[ESI*4+402090]
004010B7 C1E8 08 SHR EAX,8
004010BA 33F0 XOR ESI,EAX
004010BC 42 INC EDX
004010BD 8BC6 MOV EAX,ESI
004010BF 23C1 AND EAX,ECX
004010C1 33C3 XOR EAX,EBX
004010C3 0FB65A 01 MOVZX EBX,BYTE PTR DS:[EDX+1]
004010C7 8B0485 90204000 MOV EAX,DWORD PTR DS:[EAX*4+402090]
004010CE C1EE 08 SHR ESI,8
004010D1 33C6 XOR EAX,ESI
004010D3 42 INC EDX
004010D4 8BF0 MOV ESI,EAX
004010D6 23F1 AND ESI,ECX
004010D8 33F3 XOR ESI,EBX
004010DA C1E8 08 SHR EAX,8
004010DD 8B34B5 90204000 MOV ESI,DWORD PTR DS:[ESI*4+402090]
004010E4 33C6 XOR EAX,ESI
004010E6 42 INC EDX
004010E7 4F DEC EDI
004010E8 ^ 0F85 3DFFFFFF JNZ GomEnc.0040102B
드디어!! CRC 체크 루틴에 도달한 것이죠.
이후의 File Check를 우회하는 방법은 프로세스에서 하는 방식과 같습니다.
프로세스 내에 메모리를 할당하고 원본의 내용을 카피한 후, 그 내용으로
베이스 어드레스를 바꾸어 주면 됩니다. 이 경우에는 edx가 베이스 인데요,
edx에 할당한 메모리 주소를 줘도 됩니다.
정말 쉽죠? :)
간단하게 해당 주소에 BP를 건 후, BP가 걸리면 EDX레지스터의 값을
대상 프로세스에 메모리를 할당하고, 거기에 .bak파일을 열어서 복사해 넣은
주소로 옮겨서 CRC체크를 우회하는 코드를 만들어 봤습니다.
-_-; 소스를 보시면서 원리를 참고 하시는게 더 도움이 되는 분이 많겠죠.
간단한 테스트를 해보겠습니다.
먼저 다음과 같이 .bak 파일을 만들었습니다.

그리고 GomEncMain.exe 의 내용을 다음과 같이 바꿔봤습니다.

먼저 CRC 체크 우회기를 키기 전에, GomEnc.exe를 그냥 실행시켜 봤습니다.

이제 우회기를 키고 한번 해보겠습니다.


WoW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
소스 다운로드 :
-----------------------------------------------------------
그 외의 GomEnc의 CRC 체크를 우회하기 위한 방법들로는,
CreateFile을 할때 파일명을 GomEncMain.bak 로 주고,
GomEncMain.exe를 해당 파일명으로 복사해준 후,
GomEncMain.exe는 마음껏 수정해줘도 되는 방법이 있겠고,
GomEnc.ini에 저장되있는 CRC값을 변조된 GomEncMain.exe의
CRC값으로 바꿔주는 방법도 있고 하지만,
이런건 아무래도 이 경우에만 쓸 수 있는 꼼수겠죠 -_-;
여담이지만... 곰인코더에서 GPL 를 쓴다면, 곰인코더를 상용화해서 사용하기
위해서는 소스공개를 해야되는 것 아닌지요? -_-;
그리고, 무료버젼에서의 유일한 단점인 워터마크를 사용자가 컨트롤 할 수 있도록
해놓은 점이 사실상 이해가 잘 가지를 않네요..
setting.ini
[WATERMARK]
START_TIME
END_TIME
POS_X
POS_Y
MARGIN_X
MARGIN_Y
개선되어져야 할 부분들 같습니다..
Posted by Dual
CRC.zip


