본문 바로가기

쓰기

제가 시간만 된다면 약간의 데모스럽게 소스라도 올려드리는데..

 

좀 여의치 않군요.

 

일단 생각한 방안입니다.

 

 

 

예전부터 필요한 기능이라 생각했는데

이래저래 고민 끝에 해결방안이 나왔습니다.

 

현재 ATCode의 후킹 방식은

 

한 함수 내에 후킹 지점부터 리턴 포인트까지 복사하여 복귀 루틴만 살리는 형식으로 보이는데

단점이라면 그 리턴포인트까지 복사할때의 부분에 다시금 또다른 후킹을 걸면

무시가 된다는 점입니다.

 

따라서 이런 형식에서 제일 알맞은 후킹 지점은

 

함수의 첫 부분으로

자체디버깅에서도 확인하는 곳들로 보입니다.

 

뭐 이런저런 서론은 제끼고

 

 

본론입니다.

 

 

그런 함수의 첫지점내에는 반드시 리턴포인트가 [esp] 내에 있습니다.

 

말 그대로 그 지점을 참조하는 콜스택들이 여러개가 있다면

지정한 리턴포인트나 복귀할 리턴포인트 를 지정해두고 

 

지정한 리턴포인트 :   [esp]-0x5(콜의 크기, 포인터 콜일경우 크기가 -6)

복귀할 리턴포인트 :   [esp]

 

해당되는 곳에서 온 경우에만

참조하여 대사를 번역하는 형식입니다.

 

 

위 방식은 반드시 리턴포인트가 [esp] 에 있는

콜의 첫번째 위치로 가정하며

 

 

 

필요하게된 이유는

여러개의 콜스택이 쌓인 곳에 후킹이 불가피하고

특정 여러 지점에서 하려니 ATCode 상의 후킹 방식 때문에 한 콜내에 여러 후킹이 불가능

따라서

후킹한 콜내에서 분리하거나 판별하여 걸게되면

처음 제시한 단점이 보안되는 형태가 됩니다.

 

 

^-^

이해가 되셨으리라 생각하지만

부족한 설명이 있을 수 있으므로

물어봐주시기 바랍니다.

 

 

분류 :
Talk
조회 수 :
2518
등록일 :
2012.04.01
10:38:14
엮인글 :
https://arallab.hided.net/59785/7d5/trackback
게시글 주소 :
https://arallab.hided.net/board_devtalk/59785

EroGame

2012.04.01
10:39:15

시간만 난다면 제가 손보는데 ㅡㅡ;

whoami

2012.04.01
13:39:17

음 언제나 그렇듯이 피시님 (.. 에로게임님으로 불러드려야 하나요? 줄여서 에게님...(퍽))글은 난해한 면이 있군요..;;

 

일단 확실히 하고 넘어갈 것은 ATCode 에는 후킹방식이라는 것이 없습니다. ATCode 는 후킹이 필요할 때

ATCAPI (아랄트랜스 컨테이너 API...제가 만든 단어입니다만 ㅎ).. 그러니까 http://lab.aralgood.com/4350 에서 소개된

컨테이너 제공 함수를 불러주는 것이고 실제 후킹은 ATCTNR.DLL 에서 하게 되는 것이니까요.

 

어쨌든, 이 후킹 방식 (편의상 후킹모드1이라고 합니다)의 문제점에 대해서는 예전부터 많은 고려가 있어왔습니다.

그래서 후킹모드2 가 개발되었고 0.2용 테스트 버전이 한번 만들어졌으며.. 소스공개가 안되어 있습니다만

아마도 0.3은 후킹모드2로 만들어져 있었던 것으로 보입니다.

 

하지만 이 후킹모드2는 문제점이 있었는데, 특히 루프문에 잘못 사용하면 게임이 뻗는 경우가 생겼습니다.

그것이 아마도 0.2에서 작동하는 코드가 0.3에서 작동하지 않는 이유인 듯 합니다만 글쎄요.

 

참고로 후킹모드 0 이랄까.. 0xCC INT3 을 사용해서 디버그 모드로 붙어 사용하는 전통적인 방법이 하나 더 있습니다만

이것은 전통적인 방법이다보니 안티 디버거가 잡아낸다는 문제가.. oTL

 

서론은 여기까지 하고.. 본론이랄까 잘 이해가 안가는 부분에 대해서.

 

1. 일단은 피시님께서는 후킹모드1 을 유지한 상태에서 ATCode 만 고치는 해결책을 말씀하신 것인가요?

아니면 다른 후킹모드를 고안해 내신 건가요?

 

2. 말씀하신 방법은 반드시 후킹위치가 함수 첫지점 (그러니까.. 55 8B EC 로 보통 시작되는) 에서만 가능한 것이죠?

 

3. 지정한 리턴포인트와 복귀할 리턴포인트에 대해 이해가 잘 안가는데요..

예를 들어...

 

1000 ...

...

1005 call 2000 // 함수 호출 포인트 1

100A ... // 함수 호출 포인트 1의 리턴지점

...

1100 ...

...

1105 call 2000 // 함수 호출 포인트 2

110A ... // 함수 호출 포인트 2의 리턴지점

[.......................]

2000 jmp 3000 // 후킹된 함수 첫 위치. 원래는 55 8B EC 등으로 시작했겠지만 후킹되어 3000 으로 점프한다.

...

2100 ret

[.......................]

3000 ... // ATCTNR 의 후킹 캐치부분. 여기서 각 레지스터를 백업한다.

...

3050 call ATCode.PointCallback // ATCode 로 제어를 넘긴다. ATCode 부분은 생략.

...

3100 jmp 4000 // ATCTNR 후킹 끝. 백업된 레지스터를 복원 후 원래 함수 복사본으로 점프.

[.......................]

4000 ... // 원래 함수 (2000) 의 복사본.. 55 8B EC ;;

...

4100 ret // 1005 에서 call 했는가 1105 에서 call 했는가에 따라 100A 나 110A 로 돌아감.

 

이런 코드가 있다고 하겠습니다.

 

여기서 3000에 넘어온 상태에서 -라기 보다는 ATCode로 넘어온 상태에서 (결국 3000 에서의 상태를 백업받는

것이므로 3000부터 ATCode가 시작된다고 봐도 됨) [esp] 에는 복귀할 리턴포인트 (100A 혹은 110A) 가 있는 것이 맞습니다.

 

그럼.. 지정한 리턴포인트라는 개념은 무엇이죠? 함수 호출 포인트 (1005 혹은 1105) 를 말씀하시는 건가요?

이 지정한 리턴포인트의 사용처는 무엇인가요?

 

4. 위의 예에서, 현재 말씀하시는 것이 ATCode 내에서 복귀할 리턴포인트에 따라 다른 처리를 하고 싶으시다는 뜻인가요?

쉽게 말해...

if ([esp] == 0x100A) { 처리 1;}

else if ([esp] == 0x110A) { 처리 2;}

이런 식으로 하고 싶으시다는 건가요?

 

좀 더 자세하게.. 그러니까 토끼가 이해할 수 있을 정도로 ^^ 설명해 주시면 감사하겠습니다.

EroGame

2012.04.01
15:42:19

말 실수 했군요.

ATCTNR 에서 넘어갔을때를 말한건데;;

1. 후킹모드 2 는 제대로 디버거로 본적이 없어서 얼마나 다른지는 모르겠군요.

다만 후킹모드 1은 진작에 다 까봤기 때문에 심각하게 문제가 많은걸 알고 있었습니다.

제가 위에 말한 문제점이 후킹모드 2에서 해결 되었는지는 제가 알 길이 없지만..말이지요.

아마 해결 안되었다고 가정하고 얘기했습니다.

그리고 지금 해결 방법은 후킹모드 1의 후킹에 있어서 제일 큰 문제점의 보안이 되겠구요.

 

2. 함수 첫위치가 보통? 으로 지정되있던건 본적이 없군요.

일단 생각하는 의미는 맞습니다.

위 설명대로하면 2000 위치에서 후킹했다는 걸로 되겠지요.

 

3.위 내용을 근거로 설명하면

call 2000 을 가리키는 위치가 여럿있습니다.

1005, 1105, ex) 1205, 1305, 1405 ......

따라서 2000 에 후킹을 걸면

저 많은 위치에서 들어오게 됩니다.

그러면 해당 후킹위치에서는

2000 에서 [esp] 가 가리키는 것은

위 수많은 지점중에 들어왔던곳을 복귀하기 위한 리턴포인트(100A, 110A, 120A....)가 있겠지요.

 

일단 여기까지 설명하고 이해를 위해서 4번 가겠습니다.

 

4. if ( [esp] == {0x100A, 0x130A,...} ) { 번역 }

 else 무시

 

말 그대로 여러 call 2000 중에서 특정 장소에서 들어온 값들만 번역하게 넘기는 겁니다.

포함하지 않는 녀석들은 그냥 다시 원래대로 실행하면 됩니다.

 

위 기능이 필요하게 된 이유는

현 후킹모드 1 에서 아래와 같은 경우 후킹이 씹히게 됩니다.

 

1000 ...

...

1005 call 2000 // 함수 호출 포인트 1

100A ... // 함수 호출 포인트 1의 리턴지점

...

1015 call 2000 // 함수 호출 포인트 2

101A ... // 함수 호출 포인트 2의 리턴지점

1020 ret

 

위 내용을 하나의 함수로 판단했을때

후킹모드 1 이 싹 가져갑니다.

 

이때 후킹할 지점은 2지점.

1005, 1015 이고 그 둘의 사이는 코드로 보아도 그리 멀지 않습니다.

중간 내용도 기껏해야 점프나 간단한 분기문만 있다고 했을때입니다.

 

이렇게 후킹하게 될 경우

 

1005 는 제대로 후킹되어 번역이 되는데 반면에

복귀는 100A 지점이 아닌

복사된 4005 쯤으로 날라가겠지요.

 

그러면 자연히 1015 의 위치는 씹히게 됩니다.

만약 이런 상태에서 저부분을 무리하게 후킹하려면

4015 라는 가상 위치에 후킹하게 되고 2중으로 돌아가게 됩니다.

 

이건 생각만해도 말도 안되는 개념이고,

실제 해봤는데 안전성이 매우 취약합니다. 따라서 무시하겠습니다.

 

 

 

그래서 위와 같은 같은 함수내에서

특정 함수를 중복 참조 했을때의 문제점을 해결하기 위해서는

 

2000 위치를 후킹해야 하는데.

만약 이 위치를 가리키는게 약 30개 정도 된다고 하고

거기서는 참조하면 무조건 에러가 나오는 위치도 존재할 때도 있습니다.

 

이럴 경우 2000 의 후킹하고 필터로 걸러내기에는 많은 무리가 되거나

번역하지 않아야 하는 문장이 왔을때도

따로 걸러내기가 힘듭니다.

 

그래서 3번에서 말한 방법으로

2000 위치에서 리턴 위치를 기준으로 번역하냐 마냐를

AT코드의 추가적인 값으로 판단하자 이겁니다.

 

여기까지는 이해되셨으리라 생각됩니다.

 

그리고 부가적인 문제는 그 기준을 정해야 하는 리턴 값을.

정말 리턴값으로 할것이냐(100A, 101A ...)

 

혹은 그 위치로 들어가는 (1005,1015) 값으로 할것이냐는

whoami 씨의 몫으로 던지고자 합니다.

 

아, 그리고 저는 피시로 불러주셔도 상관없어요. ^-^

whoami

2012.04.02
21:02:28

1. 후킹모드2 는 아랄님이 처음 SVN에 커밋한 소스를 보면 알 수 있습니다만...

동작방식은 간단히 요약하면 이렇습니다.

- 후킹장소에 점프명령(5바이트) 으로 지워지는 명령을 별도 메모리에 백업

- 후킹 처리 후 백업된 명령으로 점프

- 백업된 명령 실행 후 원본의 다음 명령으로 점프

그래서 후킹된 곳이 같은 루틴 내에 있더라도 정상적으로 작동합니다...만,

루프시에 jmp 로 돌아가는 부분에다 후킹을 해버리면 문제가 발생합니다.

예)

1000 - 1003 (명령1)

1004 - 1006 (명령2)

1007 jmp 1004

 

이런 코드를 후킹하면

1000 - 1004 jmp ATCTNR.후킹처리루틴

1005 - 1006 (명령2의 조각)

1007 jmp 1004 (어디로 점프해야 하나?)

 

2. 함수 첫위치는..

55 push esp

8B EC mov ebp, esp

보통 이렇게 시작한다는 것이었습니다; 아닌 것들도 꽤 많지만요.

 

4. 일단 이해는 했습니다만 좀 고민해봐야 할 문제로군요.. 또 옵션을 추가해 넣어야 하나.

어차피 손대려 해도 다른 일이 앞에 쌓여있어서 바로 시작할 수가 없군요.

KiriKiri 도 봐야 하고 커스텀딕 요청도 있었고.... 그 후에나 손을 봐야 할 것 같습니다.

아랄

2012.04.03
19:19:36

네, 당시 저도 그 문제로 고민했었는데..

문제의 점프코드를 죄다 코드조각으로 점프시키도록 하는 방법도 있지만

그렇게 코드를 역어셈블하고 점프코드를 탐색하는 기능을 만드는 비용이  발생빈도에 비해서 과연 합리적인가 하는 딜레마에 빠졌었드랩니다.

마찬가지로 커널 드라이버를 만들어 올릴까 하는 생각도 했지만

그것도 노력대비 성과는 아주 형편없고 루트킷에 대한 제약도 점점 강화되고 있는 추세라...

(드라이버에 왠 인증서를 ;;)

 

이래저래 고민하다가 결국 0.3을 방치하기에 이르렀다는 슬픈 전설이 ㅎㅎ

 

그나저나 히데님이 얼릉 홈피복구 도와주러 오셨음 좋겠네요 으으.. ㅜㅜ

저는 사고만 치고 다니네요 흑흑

 

List of Articles
번호 제목 글쓴이 조회 수sort 추천 수 날짜 최근 수정일
공지 Talk [필독] 테스트필터 사용시 주의사항 라파에 155441   2008-08-03 2008-12-16 00:03
204 Talk 웹 계정 아이디/비밀번호 secret Hide_D 1   2011-01-02 2011-01-02 16:21
비밀글입니다.  
203 Talk CustomDic의 동작 방식에 대해서 secret Hide_D 4   2012-02-14 2012-02-14 13:36
비밀글입니다.  
202 Talk 코드정리 목록 + 코드 secret sizukana 6   2009-01-17 2009-01-17 11:41
비밀글입니다.  
201 Talk ATCTNR에다가 Python만 갖다 붙여도...? [1] Hide_D 280   2016-01-11 2016-01-12 01:30
ATCTNR에 몇가지 버그는 좀 있지만 이거 좀 보완하고, 인젝터 세팅가능하게 한다음에 ATCTNR + ProtocolBuffer(+gRPC) + Python 3 정도로 해서 묶으면, 꽤 재미있는 물건이 나오지 않을까 생각해봅니다 ㅇㅇ 이쪽은 Standalone으로 해볼만할 것 같기도 하고...  
200 Talk VB.NET에서 ezTransXP.dll사용하는 방법은 없나요? [1] R2D2 360   2016-06-14 2018-06-20 14:44
vb.net에서 MFC dll을 써서 이지트랜스로 번역해서 결과물을 가져오고 싶습니다. 그런데 아무리찾아봐도 방법을 모르겠습니다. Imports System.Runtime.InteropServices  Private Declare Fu*nction Translate Lib "ezTransXP.dll" (ByRef cszJapanese As Stri...  
199 Talk atcode.dll이 출력 못하는 글자를 수집해 봅니다. [2] file Wales 490   2014-02-05 2014-02-07 20:13
 
198 Talk 엔드 아랄호환 문제를 모두 수정했습니다 [2] kiereh 494   2014-04-28 2014-04-30 01:25
http://www.eroha.net/%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8/%ec%97%94%eb%93%9c/ 오늘자 버전 (140428)으로 엔드와 아랄트랜스간의 호환 문제가 수정되었습니다. 멀티쓰레드로 번역문을 막 쏘면 문자열 포인터가 튀면서 잘못된 참조를 하던 문제, %가 들어갈...  
197 Talk aralgood.com 도메인 부활... [7] whoami 567   2014-03-02 2014-03-17 22:48
혹시나 하고 매일 한번씩 체크하곤 하는데.. 오늘 보니 도메인이 부활했군요! 아랄님이 체크하시고 부활시키셨나? 어쨌든 그에 따라 자동업데이트도 부활하고 좋군요. 혹시 아랄님이나 Hide_D군님 보시면.. 제로보드 업데이트 하실 생각 없으신가요? 꽤 오래된...  
196 Talk UTF-8이나 유니코드 원활한 필터처리를 위해 생각해봤는데 [5] Wales 621   2014-06-16 2014-07-29 16:39
Translate함수에 포함된 필터 전후처리를 따로 빼서 원문 전환전과 번역후에 필터 처리를 하도록 하는건데 문제는 필터들 전부 멀티바이트 중점으로 만들어지다 보니 필터 전부를 손봐야 하는 상황이 오는군요. 그래서 일단 보류중...  
195 Talk 스마트 방식과 윈7의 호환에 관한 잘못된 견해 [4] TwoComet 666   2013-07-06 2013-07-07 03:37
코드 게시글에 '스마트 방식이라 윈7에서 튕길지도 모른다'는 잘못된 인식을 불어넣는 것을 발견했기에 미리 사전에 이야기합니다. 해당사항의 정확한 원인은 아직까지 발견된 사례의 하나인 기가사나 타 브랜드에서 사용하는 넥서스 엔진에서만 해당하는 사항...  
194 Talk 정말 오래간만입니다. [5] Hide_D 694   2013-05-08 2013-07-04 04:45
중간에 폴라리스 폭파되었다는 소식 듣고 한번 들렀던 걸 제외하면 거의 1년 넘게 접속을 안하고 있었던 셈이네요 -0-;; 랩에 진행중인 과제도 있고해서 아직도 좀 바쁘긴 한데, 시간 나는데로 플러그인 관련으로 쌓인 일 좀 처리해 볼까 합니다. PS. 아직 관...  
193 Talk 변경된 소스 좀 올려주세요. [1] whoami 715   2013-03-06 2013-03-06 19:09
안녕하세요. 오랫만입니다. 간만에 들러보니 폴라리스쪽에 큰 일이 있었더군요. 뭐 자세한 사항은 잘 모르겠지만.. 어쨌든.. 오랫만에 다시 한번 볼까 하고 SVN 업데이트를 했더니 1/31 이 마지막인데 이후로도 업데이트가 많이 되었더군요. SVN 업데이트를 가...  
192 Talk 아랄 트랜스 github/svn [6] ka7713 736   2018-12-26 2018-12-30 17:26
안녕하세요. 아랄트랜스 0.2/0.3 업데이트가 되지 않는 것이 안타까운데, github나 다른 곳으로 올려주실 생각은 없으신지요. 큰 도움은 안되더라도 조금이나마 기여하고 싶네요.  
191 Talk 어플로케일이 후킹하는 함수리스트... [2] TwoComet 868   2013-03-22 2013-03-27 10:26
NTDLL.DLL RtlMultiByteToUnicodeN RtlAnsiStringToUnicodeString RtlUnicodeToMultiByteN RtlUnicodeStringToAnsiString RtlOemToUnicodeN RtlOemStringToUnicodeString RtlUnicodeToOemN RtlUnicodeStringToOemString RtlUpcaseUnicodeToMultiByteN RtlUpcas...  
190 Talk 요 며칠간 아랄트랜스 사이트가 인기군요. [2] file whoami 925   2014-04-18 2014-04-28 16:06
 
189 Talk ATCTNR.dll 120809 업데이트..완료 EroGame 1174   2012-08-09 2012-08-09 14:31
원본 방식으로 후킹시 뒤에 밀린 명령어가 0x90 (nop) 로 밀어버려서 언훅시에 그 복사한 값에서 5길이 밖에 복구하지 않더군요. 버그 잡고.. 언훅 잘되는거 확인완료. 주의? 할점은 원본 후킹방식일때는 되도록이면 후킹 장소 지점에 명령어로부터 5 이상의 ...  
188 Talk ATCode 120817 [1] EroGame 1283   2012-08-17 2012-08-26 23:12
좀 큰 버그가 있어서 잡고나서 업데이트.  
187 Talk 아랄트랜스 번역플러그인에 이 프로그램들을 추가해주시면 안될까요? [5] 암흑마제 1536   2013-03-14 2013-03-14 22:16
1.TransCAT KJ/JK - 한일,일한 양방향 실시간 번역 프로그램 창신소프트의 이지트랜스와 마찬가지로 한일,일한 번역 프로그램입니다. 이지트랜스와 마찬가지로 사용자사전 기능을 제공하여 사용자사전을 잘만 이용하면 번역은 더 좋아집니다. 공통적인 성격을...  
186 Talk LEN 기능에서 체크기능 제거 및 투가기능. EroGame 1766   2012-05-10 2012-05-10 10:37
현재 LEN 기능으로 길이 연산 체크를 할때 -1이나 0의 범위까지 0x00인 NULL 문자로 길이 체크를 하잖아요? 그렇지 않은 경우도 있네요. 길이는 있으나 해당 번역문+길이 위치에 NULL문자가 없는 형태의 길이 교체형태도 추가주세요. (그때는 길이값만 변하도...  
185 Talk ATCode에 추가했던 ASLR 있잖아요. [2] EroGame 1767   2012-06-18 2012-08-03 08:38
http://lab.aralgood.com/index.php?document_srl=49989 이때 추가한건데 이거 따로 분리해서 사용 유무 지정하는게 좋을것 같네요. (xp에서는 무반응으로 처리하고) 특정 게임에서 연산중 뻗는 경우 발견되었습니다. 더미다 같은경우는 굳이 연산안들어가고 ...