KOEI

징기스칸4 신국왕/신무장 임의이름 뜯어보기.

K66Google 2021. 5. 10. 13:04

댓글로 어떤 요청을 받아서, 다시 징기스칸4를 뜯어보기로 했다.

요청의 요지는, 가상인물(신국왕이나 신무장)의 이름을 생성할때 깨진 문자가 출력된다는 것이었다.

 

신국왕명 변경 창에서 '임의' 버튼을 클릭해보니, '귺긎' 같은 뷁어가 랜덤으로 출력되는 것을 확인할 수 있었다.

매번 그러는 건 아니고, 티베트나 아프리카 쪽을 스타트 지점으로 지정했을때 이런 현상이 발생했다.

 

정보에 따르면(링크), 랜덤 이름은 가타카나 2~3문자를 조합해서 나오는 것으로 보인다.

 

랜덤 이름 뒤에는 실행파일에 입력되어 있는 지정 이름이 출력되는 것 같고... 일단 Crystaltile2만 가지고는 해당 문제를 분석할 수 없을 것 같아서 Ollydbg로 여는 수밖에 없겠다.

 

Ollydbg로 실행파일을 연 뒤, Hex dump 쪽에서 지정 이름 아무거나 검색하고 Find references 해보았다. 그러니까 무슨 PUSH들이 여러 개 나열되어 있는 코드가 보였다.

 

이게 뭔가 싶어서 이번엔 다른 지정 이름을 가지고 레퍼런스를 조회해보았다. 여기에도 PUSH들이 나열되어 있는데 아까보다는 좀 적다. 위쪽 코드를 보니 혼자만 위로 올라가는 JMP 문구가 보였다.

 

JMP가 가리키는 주소로 가보니 그냥 이런데로 연결되었다. 별로 쓸데없는 내용인 것 같아보인다.

그런데...

 

조금 아래로 내려가보니 004BC0E1에 이런 어셈블리 코드가 있었다.

 

MOV BYTE PTR SS:[ESP+0x4],0x83

 

Shift-JIS의 83 xx대 영역. 전각 가타카나와 그리스 문자가 있다. (출처 : 문자 집합 위키)

0x83???

그러고 보니, Shift-JIS 코드의 83 xx대 영역은 전각 가타카나 영역이었다.

아무래도 수상하다.

 

그래서 0x83을 0xB0으로 바꾸어 보기로 했다. 과연 어떤 결과가 나올까?

저장하고 실행해보았더니...

 

랜덤 글자들이 B0 xx대 영역의 글자들로 바뀌어서 출력되고 있다.

아무래도 내가 수정한 구문이 랜덤 글자의 '앞 바이트'를 담당하고 있었던 모양이다.

 

그럼 '뒷 바이트'는 누가 담당하고 있는 것인가.

일단 그냥은 분석하기 힘들어서, F2로 브레이크 포인트를 걸고(004BC0E1에 걸었다.) Ollydbg 상에서 징기스칸4를 실행했다.

그렇게 하니 신국왕 이름 변경 창이 뜰때 게임이 멈춘다. 여기서 F8을 누르면서 한 단계 씩 진행해본다.

 

이렇게 삽질을 하다가 MOV BYTE PTR SS:[ESP+0x11],AL 구문을 넘어가면 ESP+10에 77 B0 같은 식으로 값이 들어오는 걸 확인할 수 있었다. 바이트 플립(앞-뒤 바이트 자리 바꾸기)을 하면 B0 77이다.

 

B0 77은 '컒' 인데, 과연 이대로 출력이 되었을까? Ollydbg에서 F9를 눌러 넘겨버리니까...

 

진짜로 '컒' 자가 출력된 것을 확인할 수 있었다. 아무래도 저 부분이 뒷 바이트를 담당하고 있는 모양이다.

 

약간 더 위에 있는 어셈블리 구문을 살펴보았다. 그 구문은...

 

MOV AL,BYTE PTR DS:[EBX+0x5E0688] 이었다.

 

과연 0x5E0688에 무슨 내용이 있을지 Hex dump 창에서 찾아가보았더니... 거기에는 어떠한 값들이 나열되어 있었다. 아마 '뒷 바이트'의 목록일 것이다.

 

이 게임에서 뒷 바이트를 가져오는 방법은 다음과 같을 것이라고 추정해본다.

(예시로 EBX값은 2D라고 가정함)

 

1. 0x5E0688에다 EBX값을 더한다. (0x5E0688 + 2D = 0x5E06B5)

2. 0x5E06B5 주소로 가서 바이트를 가져온다. (4B)

3. 앞 바이트(B0)과 조합해서 B0 4B를 이름 입력창에다 출력시킨다.

 

Hex dump창에 '후지와' '와다' 같은 문구도 보이니까, 이건 Crystaltile2 상에서도 수정할 수 있을 것 같다.

Crystaltile2로 실행파일을 열고 0x1DF088부터 0x1DF0CB 영역에 있는 값들을...

 

A1~F4로 변경한다. 이렇게 하면 B0 A1(가) 부터 B0 F4(곯) 까지 랜덤 이름으로 나오게 될 것이다.

(꼭 순서대로 나열할 필요는 없는데 편의상 이렇게 변경했다.)

 

저장하고 실행해보니 겆검갭 이렇게 나온다. 세 글자 모두 B0 [A1~F4] 영역에 들어가있는 글자들이다.

이름으로 쓰기엔 여전히 이상하지만, 이렇게 변경할 수 있다는 게 증명되었으니 응용해 볼 수도 있겠다.

예를 들어, B0 CA(걺)이나 B0 D0(겆)은 이름으로 쓰기에 부적절하니까 해당 자리만 A1(가) 으로 바꾸는 식으로 말이다.

 

'앞 바이트'의 제약때문에 랜덤으로 나오는 글자들의 한계가 존재하는게 아쉽지만 이쯤에서 분석을 마치도록 하겠다.

 

* 변경 사항 정리

Ollydbg에서

- 0x4BC0E1 : 0x83 → 0xB0 으로 변경.

 

Crystaltile2에서

- 0x1DF088부터 0x1DF0CB : 93 41 43 45...(중략)...87 42 44를  A1 A2 A3 A4...(중략)...F2 F3 F4로 변경.

 

그럼 이만...