본 강좌의 저작권은 저에게 있지만 그걸 왈가왈부 할만한 가치가 있다고는 생각되지 않으므로
마음껏 퍼가셔도 좋습니다. 대신 제이름과 출처를 꼭 밝혀주시길 바랍니다.

덧붙여 제 개인적인 경험을 바탕으로 한것이므로 정석이 아닐 수 있으며 다른 더 좋은 방법들이
있을 수 있습니다. 잘못된 점이나 더 좋은 방법이 있다면 언제라도 태클 환영합니다. 질문은
질답게시판에 해주세요. 아는 범위 내에서 답해드리겠습니다.

====================================================================================

지난 시간에는 PLI.paq에서 파일 목록을 불러오는것까지 했습니다.
이번엔 파일 정보를 직접 읽어보도록 하겠습니다.

지난 강좌까지 진행됐다고 가정하고 이어서 설명을 시작하겠습니다.

파일목록을 메모리에 덤프하고 계속 F8을 눌러 진행하면 반복되는 루틴이
나오는 것을 알 수 있습니다.



어떤 작업을 하는지 하나씩 진행하면서 알아보도록 하겠습니다.

0040FE9F |> 8B5424 20 MOV EDX,DWORD PTR SS:[ESP+20]
// ESP+20의 주소(스택)에서 1바이트를 읽어 EDX에 저장합니다. (우리가 읽고자 하는 파일명)

0040FEA3 |. 83C9 FF OR ECX,FFFFFFFF
// ECX 를 FFFFFFFF로 초기화

0040FEA6 |. 8BFA MOV EDI,EDX
// EDX값을 EDI로 옮김

0040FEA8 |. 33C0 XOR EAX,EAX
// EAX 초기화

0040FEAA |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
// EDI를 1비트씩 읽음(어떤연산인지는 정확히 모르겠지만 여기서는 파일명의 길이를 계산하는데 사용됩니다. 즉, 읽으면서 ECX 값을 하나씩 줄임)

0040FEAC |. F7D1 NOT ECX
// ECX의 보수를 구함. 즉, 위의 연산에 의한 파일명의 길이가 나타납니다.

0040FEAE |. 49 DEC ECX
// ECX 값을 1 감소

0040FEAF |. 51 PUSH ECX
// 스택에 ECX값을 저장

0040FEB0 |. 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+14]
// ESP+14의 주소(스택)에서 1바이트를 읽어 ECX에 저장 (어카이브에서 불러온 파일목록에서 하나의 파일명을 불러옴)

0040FEB4 |. 52 PUSH EDX
// EDX를 스택에 저장 (우리가 읽고자 하는 파일명)

0040FEB5 |. 51 PUSH ECX
// ECX를 스택에 저장 (어카이브에서 불러온 파일목록에서 읽어온 파일명)

0040FEB6 |. E8 55810000 CALL PolyLove.00418010
// 목록을 확인하는 루틴 호출

일단 CALL 하기전까지 살펴보면

EDX에는 실행파일에 내장되어 있는, 불러와서 읽을 파일명이 들어있고
ECX에는 어카이브에서 읽어온 목록중에 하나가 들어가게 됩니다.

그렇다면 CALL에서는 이 두 파일명이 동일한지를 확인하게 되겠죠?
사실 이부분은 그렇게 어려운 부분이 아니고 그다지 중요하지 않으므로 같은 파일명을 찾았다고
가정하고 진행하도록 하겠습니다. 궁금하신분들은 직접 들어가셔서 확이해 보시면 됩니다.
루틴이 그리 길지 않으니 금방 이해하실 수 있으실 겁니다.


이제 동일한 파일명을 찾았습니다. 그러면 자동으로 위의 루틴을 벗어나게 될겁니다.




계속진행하면 갑자기 점프하게 됩니다. 이제부터 본격적으로 파일을 읽어내는 작업을 하게 됩니다.


일단 보이는 함수는 SetFilePointer, VirtualAlloc, ReadFile이군요.

다른건 이미 아실테고 SetFilePointer는 ReadFile함수가 읽어올 파일 포인터의 위치를

잡아주는 역할을 합니다. (확실하지 않음..^^;)

하나씩 살펴보죠.

0040FF1B |> 8B07 MOV EAX,DWORD PTR DS:[EDI]
//EDI에서 1바이트를 읽어와 EAX에 저장(어카이브파일의 두번째 1바이트를 읽어옴)

0040FF1D |. 6A 01 PUSH 1 ; /Origin = FILE_CURRENT
0040FF1F |. 6A 00 PUSH 0 ; |pOffsetHi = NULL
0040FF21 |. 50 PUSH EAX ; |OffsetLo = 69F4 (27124.)
//EAX(오프셋 정보)를 스택에 저장

0040FF22 |. 56 PUSH ESI ; |hFile
0040FF23 |. FF15 AC004200 CALL DWORD PTR DS:[<&KERNEL32.SetFilePo>; SetFilePointer


처음부분을 보면 EDI에서 1바이트를 읽는것을 알 수 있습니다. 그런데 EDI에 저장되어 있는 주소는
스택이 아닌 어카이브를 덤프한 메모리 주소입니다. 그 주소의 메모리창을 살펴보면 여기서는 F4 69 00 00가 나오는 군요




SetFilePointer함수에 들어가는 오프셋은 69F4로 들어갑니다. 이건 리틀엔디안에 따른 것인데 크게 신경쓸필요는 없고
그냥 뒤에서 부터 읽는다고 생각하시면 됩니다.

그럼 파일 포인터가 69F4로 잡히겠죠? 그런데 여기서 끝나지 않고 계속 루틴을 도는 것을 알 수 있습니다.
다음부분을 살펴보죠.

0040FF29 |. 8B4424 20 MOV EAX,DWORD PTR SS:[ESP+20]
//ESP+20의 주소(스택)에서 1바이트를 읽어와 EAX에 저장(우리가 읽고자하는 파일명이 몇번째 위치하고 있는지에 대한 정보가 들어있다.

0040FF2D |. 83C7 18 ADD EDI,18
//EDI에 0x18을 더함 (다음 파일 오프셋을 읽기위함)

0040FF30 |. 48 DEC EAX
//EAX 값을 1 감소 (파일 하나를 이미 읽었음을 뜻함)

0040FF31 |. 894424 20 MOV DWORD PTR SS:[ESP+20],EAX
//EAX 값을 스택에 다시 저장

0040FF35 |.^75 E4 JNZ SHORT PolyLove.0040FF1B
//루틴 반복

우리가 읽으려고 하는 파일(Im_txt24.Jzp)이 어카이브 파일 목록에서 세번째에 위치하고 있으므로
이같은 루틴을 세번 반복할 것입니다. 그리고 여기서 알 수 있는 것은 각각의 파일명 앞부분에는
그 파일의 크기가 저장되어 있음을 알 수 있습니다.

따라서 원하는 파일의 위치는 그 전의 파일 크기를 모두 더한 값 바로 다음에 위치하게 됩니다.
여기서 주의해야할 것은 처음부터 더하면 안되고 파일목록이 끝난 위치부터 계산해야합니다.

직접 손으로 한번 찾아보도록 하겠습니다.

헥스 에디터로 PLI.paq파일을 엽니다. 그러면 세번째 바이트에 F4690000이 보일겁니다. 일단 적어두고
그다음 파일명 앞부분을 살펴보면 089C0100을 찾을 수 있습니다. 이두개를 더합니다.

뒤에서부터 거꾸로 읽어(69F4, 019C08) 계산기를 사용해 더해보면 205FC가 나옴을 알 수 있습니다.
그럼 한번 찾아봅시다. 처음부터 찾는 것이 아니라 파일목록이 끝난 다음부터 계산해야하므로
아래의 위치에서 오른쪽 클릭 -> GO TO -> OFFSET을 클릭한 후 Current position을 선택하고 오프셋에
아까 계산한 값(205FC)을 입력합니다.




go를 누르면 그 오프셋으로 가게 되는데 여기서부터가 이 파일의
시작이 되는 것입니다.

다시 디버거로 돌아와 계속 진행하면 메모리를 확보하게 되는데 크기는 읽어올 파일명의 바로 앞에있는 1바이트 입니다.
여기서는 0x192758입니다. 그다음 ReadFile함수를 통해서 파일을 읽게됩니다.

전번과 마찬가지로 메모리 창을 열어 확인해보면 파일내용이 덤프됐음을 알 수 있습니다.




오늘은 여기까지 입니다. 다음에는 덤프된 파일의 암축을 풀고 복호화하는 과정을
설명드리겠습니다.
이올린에 북마크하기

Posted by Dual

2005/07/31 12:41 2005/07/31 12:41
Response
No Trackback , a comment
RSS :
http://dual5651.hacktizen.com/tc/rss/response/28

Trackback URL : http://dual5651.hacktizen.com/tc/trackback/28

Comments List

  1. 최동혁 2011/05/07 08:21 # M/D Reply Permalink

    저, 죄송한데, 이거 다음에 파일의 압축을 풀고 복호화하는 거는 아직 강좌를 하실 수 없는 건가요? 제가 프로그램 만드는 데 복호화시키는 과정이 정말로 필요해서 그런데요, 지금까지는 어떻게든 이해 가능했는데, 복호화 과정부터 턱 막히네요ㅠㅠㅠ

Leave a comment
« Previous : 1 : ... 221 : 222 : 223 : 224 : 225 : 226 : 227 : 228 : 229 : ... 251 : Next »

블로그 이미지

슬픔 메아리쳐, 난 너무도 약했어..

- Dual

Notices

Archives

Authors

  1. Dual

Calendar

«   2012/05   »
Sun Mon Tue Wed Thu Fri Sat
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Site Stats

Total hits:
98778
Today:
58
Yesterday:
165