엔진 포럼에 올라온것을 보고 파고있는것도 너무 안파이고 해서 한번 시도해봤는데 의외로 빨리 찾아지더군요.
우선 굴러님이 UTF-8 형식으로 스크립트가 저장되어있다고해서 대사서치는 미루고 ITH로 출력 문자 형식을 한번 확인해봤습니다.
ITH에서는 drawtext 함수에서 문자를 뽑아내더군요. 보시면 유니코드 형식으로 되어있습니다.
그래서 추론하기를 UTF-8 > 유니코드 변신시키겠구나 생각해서
멀티바이트 함수에다가 죄다 브포를 걸어봤습니다.
그러면 대사 넘기면 처음으로 걸리는곳에서는 UTF-8형식을 한글자씩 쭉 로드하고
위에 보이는 스샷에 두번째로 걸리게됩니다. 위에 함수에서는 변환된 문자를 저장하지 않는것같더군요.
그리고 음영처리간된 두번째 함수에서 저장을 하더군요.
스택세그먼트던가 저기가 여하튼 빨간 네모를 보시면
codepage = fde9
option = 0
stringtomap = UTF-8형식 문장
stringsize = ffffff 죄다 하라는 소리죠. 보통 2, 1 요런식으로 stringtomap 문자의 바이트크기가 들어있어요.
widecharbuf = 변환된 문장이 저장될 위치정도로 생각하시면 되요. < 우리가 작업걸 메모리 위치죠.
widebufsize = 49 < 요건 변환된 문장의 크기인데 계산기로(16진수) 곱하기 2를 하면 92가된다
F8로진행시켜서 변환된 메모리주소를 덤프로 보면 유니코드로 변신되어있고 크기도 역시 92라는걸 확인할수있다.
그리고 요놈에 수작을 걸면 한글이 튀어나온다.
그래서 아래에있는 콜문에 작업을했더니 잘되더라는...
머 요렇게 함수를 빠삭해서 찾은 것처럼 써놨지만 그냥 F8로 진행하다니 보니 아래쪽 42C4F0 반복문에서 유니코드발견해서
타고올라가다가 이해를 하고 장황히 써놨습니다. 대충 해석은 맞을겁니다.
___________________________________________________
HxD 를 활용한 옮겨심기
___________________________________________________
체험판에서 코드를 찾은후 본편에 적용할때 패킹및 디버깅 방지가 되어있을때 활용
제가 발견한 글중에 패킹된것은 실행시 언팩시켜서 실행시킨다. 머 당연한 말이겠지만...
HxD로 메모리 보기를 해봅시다.
게임을 구동시키고 HxD를 실행시킨다음 위의 핑크 네모 메모리 단축키를 눌러줍니다. 그리고 실행중인 게임을 선택합니다.
CRT+F 찾기 단축키를 쓰시거나 요렇게 메뉴바에서 선택해줍니다.
찾을 바이너리값을 입력하고 16진수형을 선택해줍니다.
// 한글판을 받아놨더니 언어로케일 변경상태라 문자가 죄다 깨져있군요. 냐하하
_____________________________________
바이너리 값
33 C9 51 53 66 89 0C 46
_____________________________________
요 바이너리값은 체험판 윗 스샷중에 유니코드상태 문자보여드리는 스샷을 보시면 (4.PNG)
0042C4D2 |. FF15 88B14B00 CALL DWORD PTR DS:[<&KERNEL32.MultiByteT>; \MultiByteToWideChar
0042C4D8 |. 33C9 XOR ECX,ECX
0042C4DA |. 51 PUSH ECX
0042C4DB |. 53 PUSH EBX
0042C4DC |. 66:890C46 MOV WORD PTR DS:[ESI+EAX*2],CX
0042C4E0 |. E8 5DA90400 CALL <JMP.&lua5.1.lua_settop>
요러한 코드값중 주황색 바이너리 값을 넣은겁니다.
우리가 작업할지역은 바이너리값으로 찾은 다음 명령어 지역이 되겠습니다.
콜문이나 점프문같은경우 변할수가있으니 요런식으로 콜문과 점프문을 피한 바이너리 탐색을 하는게 좋습니다.
바로 위에 스샷을 보시면 음영처리된 다음지역에 E8 이 보이죠 콜문입니다 저기 주소를 후킹주소로 쓰고 인자는
체험판에서 찾은 인자를 넣어주면됩니다.
주소계산은 앞에 주소+위에 offset 하시면됩니다. 42c540 +0 = 42c540
// 만약에 xor ecx,ecx 요기를 후킹지역으로 삼는다치면 42c530 + 08 = 42c538 머 요런식이 되겠죠.
참고로 메모리 바이너리값중에 E8 2DB60400 요 다음 바이너리값 8BC6 83C4 체험판 스샷을 확인해보면 콜문다음 명령어와
같죠. 같은위치라는 소리죠..
요런식으로 HxD를 활용해서 옮겨심기하실때 체험판에서 바이너리 서치했을때 한번만서치되는 바이너리 값을 구해서
옮겨심기를해야 정확합니다. 머 해보시면 아실테니....
머 그렇습니다. 아실분은 아시는내용일테고 짤막한 후기와 알고나면 편리한 HxD 활용이였습니다.
하지만 요 함수를 눈여겨 보시면 우리가 혼히 이거 자폰아니야 하는 것들중
아스키 > 유니코드 (예, BGI) 변환시키는데 아랄형이 요 함수를 못 덮쳐서 요상한 한문만 나올때가 있죠.
이럴때 요 함수 아래에서 유니코드로 변환된 문자를 아랄로 돌려보면 한글이 게임에 튀어나올때가 있습니다.
그러면 그놈은 아랄형이 저 함수를 못 덮쳐서 생기는 현상이니 아스키값 부터 온 갖 역경을 뚫고 나와서
저함수에서 코드페이지를 한글영역으로 넣어주면 한글이 나오더군요.
근데 한글 아스키값으로 저기까지 뚫고 나가는게 장난이 아니더군요. 저 함수에서 바로 아랄형 한글을 일본문자셋 변환
함수로 보낼수있다면 일은 매운 쉬워질것같은데... 방법을 모르겠다는....
저는 몰랐네요 ㅠㅠ..(저만 몰랐는 듯..)
저렇게 찾는 방법을 연습해 봐야 겠습니다 ㅎㅎ..
항상 찾으면 이렇게 포럼에 올려주시는데 ..
정말 두병더더님이 최고인듯.