본문 바로가기

쓰기



-아직 작성중이랄까[.......................]
-뭐 일단 올리고 수정하죠 ㅡㅡㅋ
-본 게시물은 어셈블리 기초 부분입니다.
-디버거로 게임을 열었을 시 게임 프로그램 코드는 주로 어셈블리로 보일텐데 그 어셈블리를 알아야 
-대사의 흐름을 쫒는데 용이하겠죠. 


;이 부분은 프로그램 소스를 짜기 전 미리 선언하는 부분이다.
;따라서 이 강좌에서는 신경을 쓸 필요는 없다.


.586
.model flat, stdcall
option casemap:none



;메모리 영역에 이 프로그램이 사용할 영역을 생성하겠다고
;선언하고 있다. 두개의 메모리 공간을 만드는데 
;각 공간의 크기는 20바이트이다.
;마찬가지로이 강좌에서 이 부분에 대해 큰 신경을 쓸 필요는 없다.


.data
work    byte 20 DUP(0)
work_2  byte 20 DUP(0)




;여기서부터가 프로그램이 구동하기 위한 실행코드가 적혀있는
;부분이다. 살펴볼 곳은 여기서부터이다.


.code




;C언어에 대한 기초지식이 있다면 알고있겠지만 프로그램에는 무조건
;하나 이상의 함수가 존재해야만 한다. 일반적으로 프로그램에 반드시
;존재해야하는 함수를 main함수라고 한다.
;어셈블리어에서도 이것은 공통적으로 적용되어진다.


main proc



;이 루틴은 어셈블리어에서 말하는 함수 프롤로그라고 하는 루틴이다.
;이 루틴이 존재한다고 하는 것은 다시말해 그 지점부터 함수가 시작된다고
;하는 것과 마찬가지 이다. 그 동작원리는 굳이 알 필요는 없겠지만
;함수가 어디서부터 시작하는 가를 보려면 우선 이와 동일한 루틴을 찾는 것이
;좋은 방법이다. 그렇다고 해서 무조건 함수가 이런 루틴으로 시작하는 것은 
;결코 아니다.
push  ebp
mov   ebp,esp 



;이 루틴은 mov명령어에 대해 간단히 설명하고자 짜넣은 루틴이다.
;이 루틴을 통해 데이터가 이동하는 가장 기본적인 방식에 대해 알 수 있게 된다.
mov   al,10h ;EAX의 1바이트 공간 AL에 16진수 10을 넣고있다.
;디버거를 포함한 모든 프로그램에서는 숫자, 혹은 문자는
;그 모두가 16진수값으로서 인식되어진다. 명심하고 또 명심하자.
;(10h의 h는 16진수를 의미하는 HEXA의 약어이다.) 
mov   ah,11h ;EAX의 1바이트 공간 AH에 16진수 11을 넣고있다.
;EAX는 4바이트 공간이다. 이것이 분할되어 사용될 수 있는데 
;그 분할되는 구동원리는 아래와 같다.
;00000000 EAX(4바이트)
;    0000 AX(2바이트)
;    00 AH(1바이트)
;      00 AL(1바이트)
;따라서 지금 EAX에는 최초 AL에 10이 들어갔고 
;AH에 11이 들어가있으니
;EAX=00001110이 되는 것이다. 다시말해
;0000 11 10 식으로 분할된다.
mov   ax,1000h ;AX에 1000이 들어가고 있다.
;현재 EAX에는 0001110이 들어가 있지만 여기에 AX가 1000으로
;들어가면 현재 AX의 값 1110위로 1000이 덮어씌어지는 것을 확인할 수 있다.
mov   eax,10000000h ;EAX에 다시 10000000을 넣고 있다. 이번에도 마찬가지로 기존에 존재하던 데이터
;00001000위로 10000000이 덮어씌어지는 것을 확인 할 수 있다.
mov   eax,20000000h ;재차 복습이다. 마찬가지로 10000000위로 20000000이 덮어씌어지는 것을 확인 할 수
;있다.
mov   ecx,01111111h ;ECX에 01111111이 들어간다.
add   eax,ecx ;add명령이다. 이것은 두 값의 합을 목적지 오퍼렌드로 저장하게 된다.
;즉 EAX와 ECX의 합을 EAX로 저장한다는 거다.
;따라서 현재 EAX의 값 20000000은 ECX와 더해져 211111111이 된다.
;반대개념으로 sub라는 명령어가 존재한다. 이것은 add랑 다르게 뺄셈을 수행하지만 그 외의
;구동 방법은 add와 동일하다.





push  00401000h ;PUSH 명령은 스택에 피연산자의 데이터를 집어넣는 연산이다.
;스택 역시 일종의 메모리 공간인데 이 스택이라는 메모리 영역을 통해 많은 데이터의 
;백업, 혹은 연산값이 들어가게 된다.
;스택은 기본적으로 FILO(First In Last Out)구조를 가지고 있다.
;사진을 보면 ESP는 현재 0012FFC0을 가리키고 있다. 거기서 우리는 00401000 이라는
;4바이트의 값을 PUSH해 넣었고 그 결과 ESP는 0012FFBC로 올라가게 된다.
;즉 0012FFC0-4가 되는 것이다. 이것은 스택의 구조가 4바이트씩 분단되어지기 때문이다.
;만약 4바이트값이 아닌 push 1을 때려넣는다 해도 같은 4바이트가 소모되어진다.
;여튼 결론적으로 PUSH 00401000을 실행한 결과는
;sub ESP,4
;mov [ESP],00401000
;이 된다.
;그런데 여기서 어째서 빼는데 올라가냐는 질문이 분명 생길 것이다.
;그것은 스택메모리의 시작이 가장 높은 메모리에서 낮은 방향으로 내려가기 때문이다.
;디버거는 이것을 거꾸로 뒤집어 우리가 보기 좋게 표시할 뿐이다.
;본래대로라면 ∪의 형태가 아닌 ∩의 형태가 올바르다.(설마 집합기호 생각하는 사람 없겠지)

;스택은 높은 주소에서 낮은 주소로 흐른다. 절대 착각하지 말자.



;이 루틴은 mov와 lea라고 하는 명령어에 대한 차이를 설명하고 있다.
;mov라는 값이 일반적으로 값을 가져온다면 lea는 주소를 가져오게된다.
;ESP라고 하는 레지스터는 메모리의 주소를 가리키는 레지스터다.
;따라서 사용시에는 무조건 [ ] 를 사용해 주어야 한다. [ ]라고 하는 것은 C에서 말하는 포인터, 즉 주소 연산을 의미한다.
;ESP의 값이 00400000라는 메모리 주소를 가리키고 00400000의 메모리 주소에는 01020304라는 값이 있다고 하자. 
;ESP는 00400000이라고 하는 값이 들어가 있다. 그런데 이 ESP라는 녀석은 무조건 [ ]가 사용되어야 한다고 했다.
;그럼 [ESP]가 되는데 이것이 의미하는 것은 바로 00400000에 존재하는 01020304를 가리키고 있는 것이다.
;종합해 설명하면 ESP=00400000이지만 [ESP]=[00400000]=01020304가 된다고 하는 것이다.
;그렇다면 ESP가 가리키는 주소의 값이 아닌 ESP자체의 주소 값을 가져오려면 어떻게 해야할까?
;바로 LEA 명령을 통해 해당 피연산자의 주소를 직접 가져오는 것이다.
;아래의 예제를 진행하며 살펴보도록 하자.
;혹여 언급하지만 [ESP]가 아닌 단순히 ESP만을 사용해 연산된다면 그것은 즉 프로그램 에러와 동일하다.

mov   ebx,[esp] ;현재 ESP값은 0012FFBC이다. 그리고 그 곳에는 지금 방금전 PUSH해 넣은 
;00401000이 존재한다.
;ESP라고 하는 레지스터는 재차 말하지만 메모리의 주소를 가리키는 레지스터이다.
;ESP와 EBP가 스택에 관여하는 레지스터인건 지난 강좌에서 언급했었다.
;역시 재차 설명하지만 ESP는 스택의 최상의 주소를 가리키고 있다. 
;즉 실제 사용중인 스택 영역의 가장 최상위의 끝단을 의미 하는데 거기에 우리는 아까 
;PUSH명령을 통해 00401000을 넣었고
;그 결과 자동으로 [ESP]는 한층 더 올라가 00401000을 가리키고 있는 것이다.
;따라서 EBX에는 00401000이 들어가게 된다.
lea   edx,[esp] ;LEA명령은 MOV와 다른 동작을 보여주게 된다.
;분명 [ESP]에는 00401000이 존재하게 되지만 LEA를 사용할 경우 [ESP]를 가져오는 게 아닌
;ESP를 가져오게 된다. 다시말해 현재 ESP는 0012FFBC가 들어가있다. 거기엔 아까 
;PUSH해 놓은 00401000이 존재하지만 이번엔 0012FFBC를 가져와 EDX로 넣는다고 하는 것이다.
;그런이유로 EDX에는 0012FFBC가 들어가게 된다.
;이것은 ESP나 ESI, EBP의 포인터 레지스터 외에도 각종 주소 연산에서도 사용되는 명령어이다.

lea   ebx,[402000] ;이것도 같은 맥락에서 보자 단지 ESP나 EBP가 아닌 402000을 말하고 있을 뿐이다.
;메모리를 확인해보면 메모리 영역 [402000]에는 0으로 채워져있을 뿐이지만 LEA명령어에 의해
;EBX에는 00402000을 가져오게 되는 것이다.
mov   eax,11111111h ;EAX에 11111111을 채워넣는다.

mov   dword ptr ds:[ebx],eax ;이것이 주소를 이용하는 본격적인 연산의 시작이다.
;DWORD PTR DS:[EBX]라고 하는 기다란 피연산자를 처음으로 보게 될 것이다.
;이것을 설명하려면 우선 아래의 주석을 보도록 하자
;BYTE : 1바이트(00)
;WORD : 2바이트(0000)
;DWORD : 4바이트(00000000)
;QWORD : 8바이트(0000000000000000)
;상기의 주석들이 어셈블리어에서 사용되는 데이터의 단위라고 할 수 있다.
;일단 PTR은 포인터연산을 생각하면 되지만 깊이 생각할 필요는 없다.
;그리고 DS는 데이터 세그먼트(Data Segment)의 약자이다. 이전의 강좌에도 말했지만 프로그램이 사용할
;메모리 영역을 말하고 있는 것이다.
;즉 DWORD PTR DS:[EBX]라고 하는 것은 메모리 영역의 EBX 주소로 시작하는 4바이트 공간이라고 해석할 수 있다.
;요컨데 현재 EBX에는 00402000이 들어가있다. 
;00402000으로 시작하는 메모리 주소에 4바이트 길이 만큼, EAX의 값을 넣는다고 하는 것이다.
;실행해본다면 메모리 공간 00402000에 현재 EAX에 들어가있는 값 11111111이 들어가는 것을 확인할 수 있다.
;어지간하면 게임내에서 대사가 이런식으로 들어가진 않는다. 하지만 그렇다고 해서 절대로 그런건 아니다.
;잘 봐두도록 하자.

push 6c6b6a69h ;이번엔 스택에 모종의 값을 넣고있다.
push 68676665h ;아까 언급했지만 재차 언급하자면 프로그램, 즉 기계어란 녀석은 문장이나 숫자를
;결코 우리가 이해하는대로 보고있지 않다. 모든것을 16진수 HEXA값으로 보고있는데
;문자 역시 마찬가지다.
push 64636261h ;HEXA값 61은 소문자 알파뱃 a를 의미한다. 이것을 61 62 63 64...식으로 12개까지 쭈욱 쓰면
;abcdefghijkl이 된다.(영문의 경우는 1바이트가 문자 하나지만 한글이나 일본어의 경우는
;기본적으로 문자의 크기는 2바이트다. 즉 00 00의 형태라고 하는 것이다)
;한가지 봐둘 것이 있다.
;사람의 시점으로는 61626364가 정방향일 것이다. 즉 abcd라는 올바른 문자가 나온다고 하는 것이다.
;하지만 컴퓨터의 시점으로는 64636261이 정방향이다. 이렇게 거꾸로 나열해 줘야 문자가 abcd라고 온전히 나온단 거다.
;만약 61626364를 그대로 읽어들이게 된다면 컴퓨터는 dcba라고 출력하게된다. 기억하자 ㅡㅡㅋ

mov   ecx,3 ;ecx에 3을 넣고 있다. 이것이 어째서 연산되었냐 하면 아무 의미없이 
;숫자가 들어간 것은 아니다. 밑의 REP연산에서 다시금 참조하도록 하자.

lea   esi,[ESP] ;[ESP]의 주소값을 ESI로 넣는데 현재 ESP는 64636261이 들어간 주소
;0012FFB0이 들어가 있다.

lea   edi,[402000] ;그리고 EDI에는 아까처럼 00402000이 들어가게 된다.

rep movs dword ptr es:[edi],dword ptr ds:[esi]
;다시 처음 보는 명령어가 존재한다. REP라는 녀석은 반복을 의미한다.
;해당 명령을 정해진 수 만큼 반복하라는 의미인데 기억하는가?
;전 강좌에서 레지스터중 반복횟수에 사용되는 레지스터가 있다고 했다.
;바로 ECX라고 하는 녀석이다. 전 강좌에서 잊어버렸더라도 재차 확인하도록 하자.
;ECX라는 녀석은 REP 외에도 각종 반복횟수에 관여하는데 반복이라 하면 ECX가 빠질 수 없다. 명심하도록 하자.
;이 ECX에서는 위에서 보듯 MOV ECX,3이라는 명령에 의해 3이 들어가 있다.
;그리고 이어지는 MOVS. 이녀석은 MOV String의 약자로서 문자열을 복사한다고 하는 것이다.
;그 유형은 위에 명령어에 나온 그대로 인데 보다 자세히 보면
;  MOVS               DWORD PTR ES : [EDI],  DWORD PTR DS :   [ESI]
;    문자열 이동명령     (이동할 크기)옮길 목적지,(이동할 크기)옮겨갈 문장의 원본이 존재하는 영역
;이런식으로 된다. 이미 위의 과정을 어느정도 이해했다면 이 말이 무슨 의미인지 알 수 있을 것이다.
;자 그럼 이제 종합해 명령어를 분석해보자.
;ECX에는 3이 들어와있다. 따라서 REP에 의해 해당 명령어는 3회 실행되게 된다.
;MOVS에 의해 [ESI]로부터 [EDI]로 문장이 이동하게 된다. 물론 [ESI]에는 어떠한 값들이 존재하고 있다.
;재차 나오는 DWORD PTR이다. 위에서 설명했던 어셈블리어의 데이터 단위를 생각해보자. 이것은 4바이트크기를 의미한다고 했다.
;그렇다면 슬슬 감이 오지 않는가? [ESI]부터 4바이트씩 복사해 [EDI]로 갖다 놓는데 그것을 3회 반복한다 라는 것이다.
;4곱하기 3은 12이다. 이쯤되면 결론이 보일것이다. [ESI]의 주소부터 시작해 12바이트 크기를 [EDI]로 갖다 놓는 다는 것이다.
;그런데 여기서 질문이 생길 것이다.
;[ESI]부터 [EDI]로 4바이트를 움직이는 명령이 3회 반복되는데 그럼 같은 명령을 3번 반복하는게 아닌가 하는 의문이다.
;결론부터 말하자면 그럴일은 없다.
;해당 명령이 수행되면 ESI와 EDI는 자동으로 명령문이 지정한 문장의 크기(DWORD)만큼 더해지게된다.
;즉 명령이 한번 실행될때마다 자동적으로 ESI와 EDI는 다음에 복사할 지점과 다음 복사될 지점을 자동으로 계산한다고 하는 점이다.
;걱정하지 말고 알고는 있자.
;그렇다면 저 명령은 지금 현상에서는 어떻게 구동될까?
;ESI에는 현재 ESP의 주소가 들어가 있다. 거기엔 ESP부터 ESP+8까지 쭈욱 총 12바이트를 차지하면서 
;abcdefghijkl(6162636465666768696a6b6c)가 들어있다.
;EDI에는 현재 00402000이 들어있다. 이것을 [EDI]라고 하면 메모리 주소 00402000이 된다.
;ECX에는 3이 들어있다. 그렇다면 4바이트씩 3회에 걸쳐서 [ESI]의 abcd...문자열을 [EDI]로 최종적으로는 12바이트를 움직이게 되는 것이다.
;따라서 [ESP]~[ESP+8]까지의 12바이트 크기 메모리에 들어있는 a~l까지의 12문자는 [EDI]의 메모리 주소 00402000으로 복사하게 된다.
;그 과정을 보도록 하자.
;이것을 이해한다면 스택이란 것도 결국 크게 다를바 없는 메모리의 영역이란 것을 알 수 있게된다.
;뿐만 아니라 REP MOVS는 게임에서 대화를 이동할때 주로 사용하는 명령이기도 하다.
;유심히 보도록 하자.


pop   eax ;POP명령이다. 이것은 PUSH명령과는 완전히 반대라고 생각하면 된다.
pop   ebx ;PUSH가 스택에 데이터를 넣었다면 POP은 스택에서 데이터를 뺀다.
pop   ecx ;정확히 말하면 POP명령의 레지스터 혹은 메모리 주소로 현재 ESP가 가지고 있는 데이터를
pop   edx ;옮긴 뒤 ESP주소를 4바이트 만큼 증감시킨다. 즉 ESP=ESP+4가 된다.
;따라서 POP EAX는 현재 [ESP]에 들어가있는 데이터를 EAX로 넣고 ESP가 한층 내려가는 것을 확인 할 수 있다.
;이렇게 4개의 레지스터에 POP하게 되면 최종적으로 ESP는 4층이 내려오게 되니 ESP=ESP+16이 된다.

jmp   test0 ;드디어 나오는 점프 명령이다.
;JMP는 피연산자 주소를 향해 문자 그대로 무조건 점프하게 된다
;따라서 test0으로 프로시저가 이동하게 된다. TEST0으로 쫒아가보자.




test6: ;문장 복사 루틴이 끝나고 나온 JMP TEST6에 의해 이곳으로 오게 됐을 것이다.
call  g2m ;다시 처음 보는 명령어의 등장이다. 이것은 CALL명령이라 하는 것이다.
;오퍼랜드에 존재하는 주소를 호출하게 되는데 이것은 현재 위치한 함수에서 새로운 함수를 호출해 오는 것이다. 
;이것이 실행될 경우 프로시저는 해당 주소로 이동하게 되는데 그러면 JMP명령과 다를 바 없을 것이다.
;CALL은 JMP와는 조금 다른 구동방식을 보인다.
;레지스터중 EIP라는 녀석이 존재하는 것은 지난 강좌에서 보았을 것이다. 이녀석은 언제나 다음에 실행해야할 명령어 주소를 가리키고 있다.
;이 CALL이란 녀석은 JMP랑 다르게 EIP를 이용해 되돌아올 주소를 저장한다. 즉 갔다가 다시 되돌아 온다고 하는 것이다.
;CALL이 동작하는 자세한 구동방식은 아래와 같다.
;
; PUSH EIP
; JMP G2m
;
;CALL명령을 맞닥트리게 되면 CALL다음에 수행할 명령의 주소를 스택에 넣게 된다.
;그리고 CALL이 호출하고 있는 주소로 점프한다. 이것이 CALL이 갔다가 되돌아 올수 있는 이유다.
;돌아올 주소는 무조건 CALL다음에 실행되는 주소이다. CALL이 위치하는 주소로 되돌아오면 도로 CALL이 실행되어버리기 때문이다.
;따라서 CALL다음에 존재하는 주소가 CALL이 실행되고 돌아와 곧바로 실행되는 것이다.
;이것이 어떻게 돌아오는 지는 이제 G2m의 주소를 향해 쫒아가보도록 하자. 저 맨 아래에 위치해 있다.

jmp   testexit ;CALL이 끝나 RETN하게 되면 이곳으로 오게 된다. 그리고 이곳을 실행하면 
;TESTEXIT로 가게 된다. 다시 밑으로 쭈욱 내려가도록 하자.

test0: ;최초의 JMP TEST0을 통해 이곳으로 왔다.
;이 루틴부터는 이제 핵심중 하나인 조건 분기에 대해 알아보도록 하자.
;조건 분기라 하는 것은 조건에 따라 수행하느냐 안하느냐의 이야기다.
;인공지능이나 필터라 하는 것은 바로 이런 조건분기를 통해 수행되어지는 것이다.
mov   eax,10h ;eax에 10을 넣고있다.
mov   ebx,20h ;ebx에 20을 넣고있다.
mov   ecx,10h ;ecx에 10을 넣고있다.

cmp   eax,ebx ;이것이 바로 비교 명령이다. eax와 ebx를 비교해 어느쪽이 크거나 작은지 혹은 같은지를
;판별하게 되는데 그 결과를 바로 상태 플래그란 곳에 저장한다.
;이것은 지금 자세하게 알 필요는 없다. 기본적으로 어떻게 돌아가는 지를 집중적으로
;보기로 하자
jl    test2 ;JL은 목적지 오퍼랜드가 소스 오퍼랜드보다 작을 경우 발동된다.
;현재 EAX에는 10이 들어가있고 EBX에는 20이 들어가있다.
;따라서 조건이 맞아 떨어지므로 TEST2로 점프하게 된다.
;만일 조건이 맞지 않는다면 이 명령은 완전히 무시되고 바로 다음 명령어가 실행되게 된다.

test1: ;JG TEST1을 통해 이곳으로 왔을 것이다.
cmp   eax,ecx ;이번에는 EAX와 ECX를 비교하는데 둘다 같은 10이 들어있다.
je    test3 ;짐작했겠지만 두 값이 같을 경우 발동하는 명령어이다.
;TEST3으로 쫒아가도록 하자.

test2: ;JL TEST2를 통해 이곳으로 왔을 것이다.
cmp   ebx,eax ;이곳에서는 EBX와 EAX를 비교하고 있다. EBX에는 20이 EAX에는 10이 들어가있다.
jg    test1 ;JG라는 명령어는 목적지 오퍼랜드가 소스 오퍼랜드보다 클 경우 발동된다.
;EBX가 EAX보다 크기때문에 해당 명령역시 실행되어져 TEST1로 점프하게 된다.

;조건분기를 끝마쳐 도달하는 곳은 이곳이다. 분명 JE TEST3을 통해 이곳으로 도달했을 것이다.
;이 루틴에서는 지금까지 보았던 각종 명령어가 구체적으로 어떤식으로 조합되어 사용되는지 알아보도록 하자.

test3: ;JE TEST3을 통해 왔을 것이다.
lea   eax,[402014] ;EAX로 [402014]의 주소가 들어가게 되므로 EAX에는 402014가 세팅되어진다.
lea   ebx,[402000] ;EBX로 [402000]의 주소가 들어가게 되므로 EBX에는 402000이 세팅되어진다.
test4:
mov   cl,byte ptr ds:[ebx] ;CL(ECX의 1바이트 공간)에 EBX가 가리키는 주소의 1바이트 값을 옮긴다.
;EBX가 가리키는 402000에는 아까 우리가 옮겼던 a~l이 존재한다.
;그중 한 바이트라면 61 즉 a를 cl로 옮긴다고 하는 것이다.

cmp   cl,0 ;복사해온 CL을 0과 비교하고 있다. 처음은 물론 같지 않다

je    test5 ;그 둘이 같으면 TEST5로 점프하라고 하고있다.

mov   byte ptr ds:[eax],cl ;CL을 EAX가 가리키는 주소 402014로 한바이트를 이동하라고 하고있다.
;즉 CL에 들어있는 값 61(알파뱃 a)를 402014로 옮기라고 하는 것이다.

inc   eax ;처음 보는 명령어다. 이것은 increase의 약어인데 실행시 해당 오퍼랜드의
;값을 1 상승 시킨다. 따라서 EAX의 402014는 1이 더해져 402015가 된다.

inc   ebx ;마찬가지로 EBX의 값이 1상승되어 EBX는 402001이 되어진다.
;그러면 EBX는 현재 a다음의 값 b를 가리키고 있다.
;여담이지만 반대되는 명령어로 dec(decrease)라는 명령어도 존재한다.
;짐작 하듯이 그것은 1이 감소하는 효과를 낸다.

jmp   test4 ;그리고 TEST4로 무조건 점프 하게된다.

;여기까지 차례대로 와 다시 TEST4를 살펴보기 전에 잠시 이 주석을보도록 하자.
;이것은 반복하고있다 연산을 다 처리해 끝으로 가면 도로 JMP TEST4로 되돌아 가도록 하고있다.
;그럼 이것을 빠져나가는 연산은 어디있는걸까?
;이미 눈치채고있겠지만 CMP CL,0에서 이어지는 JE TEST5가 바로 이 무한 반복을 빠져나가는 열쇠일 것이다.
;생각해보자 이 연산은 MOV CL,BYTE PTR DS:[EBX]와 MOV BYTE PTR DS:[EAX],CL을 통해 한문자씩 계속해 옮겨질 것이고
;INC EAX와 INC EBX에 의해 계속해 다음 복사할 문자와 다음 복사할 위치를 가리키게 될 것이다.
;그런데 옮기려는 CL에 들어가는 값이 00이면 거기서 문장을 종료하고 빠져나가라고 하고있다.
;올리디버거를 이용해 메모리창을 봐 현재 원본 문자열이 존재하는 00402000을 보도록 하자.
;문자가 쭈욱 이어지다가 마지막의 l다음을 보면 바로 00으로 펼쳐져 있을 것이다.
;결국 문자를 전부 복사하면 이 반복문을 빠져나가라고 하는 것이다.
;다시말해 이 루틴은 모든 문자열을 메모리 주소 00402014로 한 문자씩 쭈욱 복사한 다음에 그것을 전부 복사하면 
;빠져나간다는 것과 마찬가지 의미다.
;CL이 0을 가지게 되면 JMP에 의해 TEST5로 점프하게 될테니 모든 루프를 다 돌았다면 TEST5로 가보도록 하자. 

test5: ;문자를 옮기는 루틴을 지나면 이곳으로 오게 될 것이다.
jmp   test6 ;이번 루틴은 간단히 TEST6으로 이동하라고 말하고 있다.
;TEST6은 이 점프문을 배우기 이전에 존재한다. 위로 쭈욱 올라가보자.
      
testexit: ;CALL과 RETN을 끝내고 나면 이곳으로 도달하게 될 것이다.
;이곳은 제일 처음 시작했던 함수 프롤로그를 정리하는 구간이다.
;이 루틴을 거치게 되면 사실상 구동중인 프로그램은 종료된다.
;여기까지 잘 찾아왓다. 그동안 위아래로 왔다갔다 하느라 고생했겠지만
;어느정도 이해할때까지 강좌2와 강좌3을 계속해 반복해 줬으면 한다.
mov esp, ebp
pop ebp
retn

main endp ;종료 끝.



;G2m함수를 실행한다고 선언하는 부분이다.
g2m proc
nop ;어셈블리 명령을 보면 저 NOP란 명령을 자주 보게 될것이다.
nop ;그것이 내포하는 의미는 아무것도 없다. 그냥 무시하고 쭉 내려가면 된다.

retn ;그리고 새로나오는 명령인 RETN이다.
;이것은 Return의 약어이다. 돌아간다는 의미에서 아까 CALL이 백업한 돌아갈 주소가 연상되지 않는가?

;이녀석은 CALL에 의해 백업된 주소로 되돌아간다. 현재 ESP에는 아까 CALL이 백업한 CALL다음에 실행될 명령어의 주소가 백업되어져있다.
;이녀석이 구동하는 원리는 아래와 같다.
;
; pop eip
;
;EIP는 다음 실행해야할 주소가 들어가는 레지스터란 것을 이미 앞전에 배웠을 것이다.
;즉 스택에 백업해둔 돌아갈 주소를 EIP로 넣게되면. 
;다음 실행해야할 명령주소가 CALL 지점의 다음 명령문이 되는 것이다.
;다시 위로 올라가도록 하자.

;여기는 코드 종결을 이야기 하는 부분이다. 
g2m endp

end main

------------------------
이걸 써놓고 느낀건데 이보다 더 기초 내용이 선행되어야 하는게 아니었나 하는 생각이 듭니다[...............]
그래서 그동안 ㅈㅈ치고있었죠.

사실 이정도만 알아도. 코드파인드에 필요한 지식은 전부 클리어 된것과 마찬가지긴 합니다.

추가로 첨부합니다.
이게 아직도 남아있었군요 -_-;;
위의 코드를 실제 실행파일로 만들어 올리 디버거로 확인할 시 어떤 흐름으로 프로그램 코드가 진행되는지를 gif로
만들어 보았습니다.
이걸 프레임 단위로 볼 수 있으면 좋겠는데 말이죠. 하여간 위의 게시글과 병행해 보시는 것을 추천합니다. ㅡㅡㅋ

test.gif

->추가로 첨언하면 MOV CL,BYTE PTR DS:[EBX]로 시작하는 반복문이 한번 반복한 후 진행하다 갑자기 워프해버리는
부분이 보일텐데. 귀찮아서 루프 탈출해 버렸어요[....]
->어케 탈출하는지는 본문을 봐주세요 ㅡㅡㅋ

tene

2011.07.28
23:03:49

오오 ~ 정말 감사드립니다.

 

코드 추출할려고 정말 막무가네로 뒤적뒤적 거렸던 기억이.. ㅠ_ㅠ

 

많은 도움이 될꺼 같습니다.

프시쵸

2011.09.05
17:36:04
조흔 글이군염. 앞으로 코드파인더가 늘어나기를~

먹구르름

2011.11.08
00:57:49
코드파인더분들은 프로그래밍에 어느정도 지식은 있어야 수월하시겠네요
컴공분들은 좀 쉬울듯 ㅎㅎ;;
저도 컴공이긴한데 음... 그래도 어느정도 아는 부분이 있으니까 쉽겠네요
그런데 노가다 작업이 좀 많이 차지 하는것 같네요..

냥호가

2011.12.07
16:13:32
우와 바라보는데 뭔지모르겠다 ㅋㅋㅋ;;;
List of Articles
번호 제목 글쓴이 조회 수 추천 수sort 날짜 최근 수정일
공지 아랄트랜스로 게임하기 앞서 기본 셋팅 확인하기! [4] file TwoComet 40491   2012-08-30 2014-02-26 20:12
공지 아랄트랜스 - 초보자 가이드 [94] file Hide_D 319319   2008-07-16 2015-02-27 18:02
공지 모든 플러그인, 필터 안내 ('09.03.13) [20] Hide_D 191373   2008-10-31 2009-03-13 23:48
공지 아랄트랜스 0.2 - 초보자 가이드 [109] file 아랄 505841   2008-07-16 2013-12-31 09:32
197 [VNR홈페이지]게임이름으로 게임정보 찾기 미래도 3682   2015-09-13 2015-09-13 03:43
게임 정보를 빠르게 찾는 법에 대해 소개합니다. 개인적으로 엔진정리와 작업을 하고 있으나.. 금칙어 크리때문에.. VNR 홈페이지에서 일종의 데이터베이스를 제공합니다. 물론 정보를 수집해서 올려놓은 것이기에 플레이하지 않은 것은 지원하지 않습니다. 주...  
196 사진이 깨진 글에서 사진순서 맞추기 file 미래도 430   2015-09-13 2015-09-13 03:08
 
195 PhantOm:디버깅이 제한된 프로세스 디버깅하기 [1] 미래도 1436   2015-08-23 2015-08-25 19:46
사실 VNR 스크립트 주석에서 퍼옴 椎名里緒, 시나리오 엔진의 경우 Themida로 디버깅을 막았습니다.(다른 디버깅방지 엔진도 비슷할꺼라 생각함) - OllyDbg로 열 때, 게임이 실행되지 않는다. - 게임 모듈 메모리 공간이 수정하는 것을 막는다. 대체로 이런 특...  
194 에우슈리 & 아나스타샤 게임에서 오류가 뜨시는분 Peith 528   2013-08-07 2013-08-07 00:49
이런 에러가 뜨시는분 전에 질문을 올렷는데 더미컷 버전이라 그렇다고 하시더군요 근데 제가알기론 타유우타랑 명색의 예희는 더미컷 버전이 아닌데 말이죠 환린이랑 전여신은 잘 모르겟지만 그것들도 더미컷이 아닐겁니다 설치하는데 필요한 용량과 게임 파...  
193 미연시 플레이시 특히 오프닝 엔딩영상에서 강제종료 되는문제. 소라노카제 3280   2013-04-13 2013-04-13 11:40
많은 미연시 플레이어들이 겪으시는 문제인데.... 해결책을 아는 분이 적네요..... 저만 모르던가요. 어째든 최근들어 알게 된겁니다만............. "그리자이아의 과실" 과 "지금 당장 오빠에게 여동생이라고 말하고 싶어" 밑 여러 작품에서 이유없는 강제 ...  
192 [팁]단순후커사전SDK 두통 1450   2013-07-06 2013-07-08 20:42
[후커사전] 단순후커사전 SDK Ver1.00 자료실에 올릴까 하다가 그냥 방문해서 이것저것 봐보는게 좋을듯싶어서 링크 다른건 모르겠는데 ezTransMini 요놈 쓸만하네요.  
191 NTLEA GUI 0.92 이상을 쓰시는 분은 필히 보시기 바랍니다. [5] TwoComet 2877   2013-02-01 2013-07-29 03:13
현재 NTLEA 0.87 beta 를 쓰고 있었다가 저걸로 한번 사용하게 되었었습니다. 근데 큰 문제가 생깁니다. 어플로케일의 AlLayer.dll 가 인젝션 되지 않는 사태가 벌어지는군요. 솔직히 기능면에서는 0.87 beta 나 0.92 GUI 나 같습니다. 만약 0.92을 인스톨하여...  
190 기리기리 데이터 추출 [1] file 두병더더 7745   2012-12-06 2012-12-13 11:50
 
189 CS2엔진 야매+ file 두병더더 2313   2012-09-16 2012-09-24 12:09
 
188 올리 디버거 기능중 스탭인투와 스탭오버 file Wales 2044   2012-09-12 2012-09-20 15:27
 
187 아랄로 만든 바로가기 파일이 깨질때. TwoComet 2927   2012-08-30 2012-08-30 15:55
일부 게임이 아랄트랜스로 바로가기를 만들었을때 해당 바로가기가 제대로 동작하지 않는 게임들이 있습니다. 그런 경우는 대부분 3가지로 나눠서 생각할 수 있습니다. 첫째, 게임 엔진 중에 최초 실행시 아랄과 같은 후킹 프로그램이 동작하는지 검사하는 경...  
186 피시의 ATCode 기능 및 이론 설명 01 [11] file TwoComet 4378   2012-07-19 2012-07-26 21:46
 
185 기리기리엔진에 대해 여러가지 [3] 고토회복 8357   2012-06-25 2015-12-06 04:09
1. 무료엔진이라는 겁니다 이걸 왜 이야기 하냐 하면 그러므로 버전별로 안전판 원본이 있어요 도대체 무슨 이야기야? 하는 분들 많을듯... 어느 회사가 기리기리로 게임을 제작합니다.. 버전별로 전부 툴이 있지요 ^^ 그개 다 공개고 자 여기에서 어느 회사가...  
184 카미 육성 팁 입니다 [2] 력현 4004   2011-06-19 2012-01-14 13:44
캐릭을 그나마 효율 적으로 성장 시킬려면 마르웰을 초기 부터 장비 합니다 경험치 보석 4개다 장착하고 사냥 보다는 투기장에서 몹을 잡는 쪽으로 하지요 초기칭호는 15L때 히로인들은 획득이 가능 합니다 중요한것은 15L 의 초기 칭호를 얻기 전에 성장석을 ...  
183 아랄2 후킹후 무응답/작동중지로 강제종료/튕김 현상 해결 정리. [3] file uwle 22627   2011-03-16 2014-03-22 23:11
 
182 간단하게 적어두는 아랄트랜스 사용 방법! [1] Hide_D 8382   2011-02-19 2011-03-08 19:27
이미지로 된 것에 비해서 불친절하지만 약간 다른 내용도 있고 해서 쓸만할겁니다 ㅇㅇ 0-1. AppLocale 설치 0-2. ezTransXP 설치 0-3. 이지트랜스 딱 한번만 실행하고 '웹 프록시 기능'을 끄고 종료 1. 게임을 실행(주로 AppLocale로 실행함) 2. 아랄트랜스 ...  
181 아랄 트랜스 후킹만 하면 튕겨버리는 현상 TIP 입니다!!! [5] gosmy 6333   2011-02-05 2012-05-05 22:25
이번에 제가 아자나엘 설치 시도하면서 알게된 팁 하나 드리려고 이렇게 글을 씁니다. 아랄 트랜스 후킹만 하면 튕겨버리는 현상이 있으신 분들! 무슨 게임이든 후킹만 하면 아무 메세지도 없이 그냥 종료되시는 분들!!! 지금 즉시 windows작업 관리자 - 프로...  
180 후크하면 아랄트랜스가 소리소문없이 사라지는 분은 [1] 키리아스 5241   2011-01-17 2015-02-11 23:17
혹시 아랄트랜스가 바탕화면에 있지 않나요? 아랄트랜스를 내 문서라든가 어디든지 집어넣으세요. 세 줄 관리해야 하는데... 정말 이것 뿐입니다 =_= 경로가 길어져서 그런 건지, 한글이 들어가서 그런 건진 모르겠어요.  
» 코드파인드를 위한 기초 지식(3) [4] file G2m2000 9378   2011-07-13 2011-12-07 16:13
-아직 작성중이랄까[.......................] -뭐 일단 올리고 수정하죠 ㅡㅡㅋ -본 게시물은 어셈블리 기초 부분입니다. -디버거로 게임을 열었을 시 게임 프로그램 코드는 주로 어셈블리로 보일텐데 그 어셈블리를 알아야 -대사의 흐름을 쫒는데 용이하겠...  
178 에우슈리사 게임들에대한 간단한 팁(팁이라기도뭐한거지만...) [1] Ronya 6391   2010-10-21 2011-11-24 13:42
1. 유니코드 변경 후 플레이하세요... 에유슈리사 게임들은 어플과 그다지 안친합니다. 제 경험상 에우슈리 게임들은 어플돌리면 어느순간부터 에러메시지 계속뜹니다... (왼쪽이 무시고 오른쪽버튼이 종료하는거였나? 반대엿나?..;) 어플돌려도 괸찬은분도 계...