[어셈블리어]
Push  : sp 레지스터를 조작하는 명령어중의 하나이다. 스택에 데이터를 저장하는데 쓰인다.

          ex:) Push eax : 스택에 Eax의 값을 스택에 저장한다.

          ex:) Push 20 : 즉석값인 20을 스택에 저장한다.

          ex:) Push 401F47 : 메모리 오프셋 401F47의 값을 스택에 저장한다.
 

Pop  : 이또한 sp 레지스터를 조작하는 명령어중 하나이다. 스택에서 데이터를 꺼내는데 쓰인다.

          ex:) Pop eax : 스택에 가장 상위에 있는 값을 꺼내애서 eax에 저장한다.

             * 주의점 : Push 의 역순으로 값은 스택에서 Pop 된다.


Mov  : 메모리나 레지스터의 값을 옮길 때[로 만들 때]쓰인다.

          ex:) Mov eax,ebx : ebx 레지스터의 값을 eax로 옮긴다[로 만든다].

          ex:) Mov eax,20 : 즉석값인 20을 eax레지스터 에 옮긴다[로 만든다].

          ex:) Mov eax,dword ptr[401F47] : 메모리 오프셋 401F47 의 값을 eax에 옮긴다[로 만든다]


Lea  : 오퍼렌드1의 값을 오퍼렌드2의 값으로 만들어준다.

          ex:) Lea eax,ebx : eax레지스터의 값을 ebx의 값으로 만든다.


Inc  : 레지스터의 값을 1증가 시킨다.

          ex:) Inc eax  : Eax 레지스터의 값을 1증가 시킨다.
 

Dec  : 레지스터의 값을 1 감소 시킨다.

          ex:) Dec eax : Eax 레지스터의 값을 1 감소 시킨다.


Add  : 레지스터나 메모리의 값을 덧셈할떄 쓰임.

          ex:) Add eax,ebx   :Eax 레지스터의 값에 ebx 값을 더한다.

          ex:) Add eax,50    :Eax 레지스터에 즉석값인 50을 더한다.

          ex:) Add eax,dword ptr[401F47]  : Eax 레지스터에 메모리 오프셋 401F47의 값을 더한다.
 

Sub  : 레지스터나 메모리의 값을 뻇셈할떄 쓰임.

         ex:) Sub eax,ebx   : Eax 레지스터에서 ebx 레지스터의 값을 뺸다.

         ex:) Sub eax,50
 

Eax  : 레지스터에서 즉석값 50을 뺸다.

        ex:) Sub eax,dword ptr[401F47] : Eax 레지스터에서 메모리 오프셋 401F47의 값을 뺸다.
 

Nop  : 아무동작도 하지 않는다. : 90
 

Call : 프로시저를 호출할떄 쓰인다.

        ex:) Call dword ptr[401F47]    : 메모리 오프셋 401F47을 콜한다.

DIV <Target> - Division. EAX를 <Target>으로 나누는 연산이다. 결과로 몫은EAX에 나머지는 ECX에 들어간다. 

                       ex :) MOV EAX, 64h

                               MOV ECX, 9h

DIV ECX       ; 64h(100) / 9h(9) = 몫 : 0Bh(11) , 나머지 1h이므로

                EAX = 0Bh, ECX = 1h가 저장된다.


IDIV <Target> - Integer Division. DIV와 똑같다. 하지만 다른점은 부호있는 정수를 다룬다는 점이다.


MUL <Target> - Multiplication. EAX와 <Target>을 곱하여 EAX에 저장한다.

                        ex:) : MOV EAX, 2h

MUL 4h       ; EAX에는 2h * 4h = 8h가 저장된다.


IMUL <Value> - Integer Multiplication. EAX와 <Value>를 곱하여 EAX에 저장한다.

IMUL <Destination>, <Value> - <Destination>과 <Value>를 곱하여 <Destination>에 저장한다.

IMUL <Destination>, <Value>, <Value> - 2개의 <Value>를 곱한 후에 <Destination>에 저장한다.

TEST <Target1>, <Target2> - 이 연산은 대부분이 <Target1>과 <Target2>가 같게 설정된다. 예를들면 TEST EAX, EAX. 이 연산은 논리회로의 AND연산을 수행하지만 결과값을 저장하지 않는다. 단지 EAX=0일경우 ZF=1이 되고 EAX!=0일경우 ZF=0이 된다. 그리고 OF, CF는 0이된다.

ex :) TEST EAX, EAX 

LODS, LODSB, LODSW, LODSD(Load String Byte, Word, DWord) - ESI가 가르키는 곳에서 지정한 크기(Byte, Word, DWord) 만큼 읽어와 EAX에 복사한다. ESI는 복사한만큼 이동한다.


STOS, STOSB, STOSW, STOSD(Store String Byte, Word, DWord) - EAX에 들어이있는 데이터를 지정한 크기만큼 EDI가 가르키는 주소에 복사한다. EDI는 복사된 만큼 이동한다.


CLD(Clear Direction flag), STD(Set Direction flag) - Direction Flag를 Set하거나 Clear할때 사용한다.


CMC(Complement Carry flag), CLC(Clear Carry flag), STC(Set Carry flag) - Carry flag를 순서대로 반전, Clear, Set시킨다.
 

SHL <Destination>, <Value> - Shift Logical Left. <Destination>에 <Value>만큼 Shift연산을 왼쪽으로 수행한다. 만약 <Destination>보다 커질경우 CF=1이 된다.


SHR <Destination>, <Value> - Shift Logical Right. SHL과 기능은 동일하며 Shift연산이 오른쪽으로 진행된다.


ROL <Destination>, <Value> - Rotate Left. SHL과 기능은 동일하다. 단지 자리수가 늘어날경우 해당 비트가 오른쪽 끝으로 이동한다.


ROR <Destination>, <Value> - Rotate Reft. SHR과 기능은 동일하다. 단지 자리수가 없어질경우 해당 비트가 왼쪽 끝으로 이동한다.  

Ret : 콜한 지점으로 돌아간다.
 

Cmp : 레지스터와 레지스터혹은 레지스터 값을 비교하기위하여 쓰인다. 

        ex:) Cmp eax,ebx : Eax 레지스터와 Ebx 레지스터의 값을 비교한다.

        ex:) Cmp eax,50 : Eax 레지스터와 즉석값 50을 비교한다.

        ex:) Cmp eax,dword ptr[401F47] : Eax 레지스터와 메모리 오프셋 401F47의 값을 비교한다.
 

Jmp : 특정한 메모리 오프셋으로 이동할떄 쓰인다.

        ex:) Jmp dword ptr[401F47] : 메모리 오프셋 401F47 로 점프한다. 
 

조건부 점프: Cmp나 Test 같은 명령어의 결과에 따라점프한다.
Je : Cmp나 Test 의 결과가 같다면 점프 

Jne : Cmp나 Text 의 결과가 같지 않다면 점프

Jz : 왼쪽 인자의 값이 0 이라면 점프

Jnz : 왼쪽 인자의 값이 0 이 아니라면 점프 

Jl : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작으면 점프(부호있는)

Jnl : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작지 않으면(크거나 같으면) 점프 (부호있는)

Jb : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작으면 점프(부호없는)

Jnb : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작지 않으면(크거나 같으면) 점프 (부호없는)

Jg : 왼쪽 인자의 값이 오른쪽 인자의 값보다 크면 점프

Jng : 왼쪽 인자의 값이 오른쪽 인자의 값보다 크지 않으면 (작거나 같으면) 점프

Jle : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작거나 같으면점프 (부호있는)

Jge : 왼쪽 인자의 값이 오른쪽 인자의 값보다 크거나 같으면 점프
 

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

약 이정도의 명령어들이 가장 많이 나오는 것들임으로

최소한 위에 나온것들은 외워 두도록 하자.


이글에서는 5가지 논리연산에 대해서 쓸것이다.

논리연산자는 두 오퍼렌드의 값의 비트들을 대응시켜 명령에 따른 적절한 값을 구하여 첫번쨰 오퍼렌드의 값을 바꾸어 주는것이다.

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 

AND 연산 : 대응되는 비트가 둘다 1이면 결과는 1이고 그외의 결과들은 모두 0 이 된다.

 - AND EAX,10 : 이를 계산하기 위해 우선 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000 이 되고 10은 1010 이 되고 AND 연산은 둘다 1이여야 1이 됨으로 결과는 1000 이 됩니다.


OR 연산 : 대응되는 비트중 하나가 1 또는 둘다 1이면 결과는 1이고 그외는 모두 0이 된다.

 - OR EAX,10 : 이를 계산하기 위해 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000이 되고 10은 1010이 되고 OR 연산은 한쪽 또는 양쪽둘다 1이면 1이고그외는 모두 0 임으로 결과는 1010이 된다.

 

XOR 연산 : 대응되는 비트 중에서 한비트가 1이고 다른 비트가 0이면 1이 되고 두개의 비트가 1이면 0 이 되고 두개다 0 이어도 0이 된다.

XOR EAX,10 : 이를 계산하기 위해 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000이 되고 10은 1010이 되고 XOR 연산은 한쪽만 1이어야 1임으로 결과는 10이 된다.


NOT 연산 : NOT 연산은 오퍼렌드의 값을 반대로 하여 준다.

NOT EAX : 이를 계산하기 위해 오퍼렌드의 값을 2진수로 바꾸어 주면 10은 1010이 되고 NOT 연산은 1 과 0을 반대로 하여 줌으로 결과는 0101 이 된다.

 * 참고 : Test 연산은 오퍼렌드에 영향을 주지 않으며 플래그만 세트 시키어 준다


[레지스터]

1. 범용 레지스터

 - EAX 레지스터 : 누산기인 EAX 레지스터는 입출력과 거의 모든 산술연산에 사용된다. 곱셋과 나눗셈, 변환 명령어등은 반드시 EAX 레지스터를 필요하게 된다.

EAX 레지스터는 32bit의 레지스터이고 16bit 의 레지스터로 AX가 있다. (AX는 왼쪽의 AH와 오른쪽의 AL로 이루어져 있다)

 

 - EBX 레지스터 : EBX는 주소지정을 확대하기 위한 인덱스로서 사용될수 있는 유일한 범용 레지스터 이며, 다른 일반적인 계산 용도로도 쓰인다.

EBX는 32bit 레지스터이고 16bit로 EB가 있다. (EB는 왼쪽의 BH와 오른쪽의 BL로 이루어져 있다)

 
 - ECX 레지스터 : ECX는 루프의 반복 횟수나 좌우방향의 시프트 비트 수를 기억한다. 그외의 계산에도 사용된다.

ECX는 32bit 레지스터이고 16bit로 CX가 있다. (CX는 왼쪽의 CH와 오른쪽의 CL로 이루어져 있다.)
 

 - EDX 레지스터 : EDX는 몇몇 입출력 동작에서 사용 된다.
 

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 

2. 플래그 레지스터

 - OF [Over Flow] : 산술연산후 상위 비트의 오버플로를 나타냄

 - DF [Direction] : 스트링 데이터를 이동하거나 비교할떄 왼쪽 또는 오른쪽으로의 방향을 결정한다.

 - SF [Sign] : 산술결과의 부호를 나타낸다[0=양수,1=음수]

 - ZF [zero] : 산술연산 또는 비교동작의 결과를 나타낸다[0=결과가 0이 아님,1=결과가 0임]

 - CF [Carry] : 산술연산후 상위 비트로부터의 캐리 그리고 시프트 또는 회전동작의 결과 마지막 비트 내용을 저장한다.

 - TF [trap] : 프로세서가 단일 스텝 모드(single-step mode)를 동작할수 있도록 해준다.


[참고]

1. 나눗셈 연산의 피젯수는(32bit의 나눗셈을 가정) 항상 edx:eax 이다.

2. cdq 는 나눗셈을 위해 피젯수의 사이즈를 확장하는 것이다.


나눗셈연산(div, idiv)은 eax와 edx에 의해서만 이루어집니다

- 피젯수(나눔을 당하는 수) 는 eax, edx에만 들어갈 수 있다는 얘기에요

16 / 5 연산을 한다고 가정해 봅시다.


16과 5 둘다 32bit data라고 가정하구요


그럼 일단 eax에 16을 넣습니다. 그 다음 ebx(다른레지스터나 메모리도 상관없음)에


5를 넣습니다. 그 다음 div 연산을 하면.........될것 같지만 안됩니다..


일반적으로 제수(여기서는 5)가 32bit이면 피젯수(여기서는 16) 는 64bit가 되어야


32bit 값을 가지는 몫을 얻을 수 있습니다.


그래서 피젯수의 bit를 확장 시켜주는것이 바로 cdq 연산입니다


32bit 크기의 eax의 값을 64bit의 값인 edx:eax로 만들어줍니다.


여기서 edx는 상위자리가되고 eax는 하위 자리가 되죠


자..그럼 cdq 연산까지 끝났으면 edx:eax에 16이 들어가있고 ebx에 5가 들어있겠네요


그럼 idiv연산을 해봅시다(div는 부호가없는 나눗셈 idiv 부호가 있는 나눗셈)


그럼 몫과 나머지가 나와야 하겠죠? 그 결과는 다시 eax와 edx로 들어가는데


eax에는 몫이, edx에는 나머지 부분이 들어갑니다~


 



LoadLibrary GetProcAddress (로드 라이브러리 겟프락어드레스) 후에 변하지 않는 레지스터는

EBX EBP ESI EDI 이다. EAX, ECX, EDX 가 변한다 


출처 : http://zerohz.tistory.com/61

'[+] Information > [-] RCE' 카테고리의 다른 글

Lena's Tutorial 4 상세분석  (0) 2011.10.08
Lena's Tutorial 3 상세분석  (0) 2011.10.08
어셈블리어 정리.  (2) 2011.10.06
Lena's Tutorial 1 상세분석  (0) 2011.10.06
Lena's Tutorial 분석 글을 쓸 예정  (0) 2011.10.06
  1. Favicon of https://rootfriend.tistory.com BlogIcon RootFriend 2018.04.04 09:44 신고

    보기좋게 잘 정리해놓으셔서, 종종방문해서 참고합니다~
    출처남기고 퍼갈께요~!

저는 처음에 어셈이 뭔지도 몰랐어요.

이강석님이 쓰신 리버스 엔지니어링 책을 보고 어셈의 존재를 알게됬죠 ㅎㄷㄷ

근데 아무것도 모르는 상태에서 책을 보니 아무것도 모르고 지겹기만 하더라구요.

그래서 제가 찾은 방법이 비쥬얼 스튜디오를 이용하는 것 이었습니다.

비쥬얼 스튜디오에 디버깅 모드로 원본 소스와 어셈을 비교해가면서 공부했어요.


빨간색 동그라미는 브레이크 포인트 걸어둔거에요 ㅎ

위에 처럼 원본 소스하고 어셈하고 비교 하면서 볼 수 있어요 ㅎㅎ

이렇게 비교해서 보고 또 똑같은 프로그램을 올리디버거, gdb등으로 보면 대충 눈에 익죠.. ㅋㅋ

각 언어의 문법들을 소스로 짜신후에 디버깅해보시는게 제일 좋은 공부 방법인것 같아요 ㅎㅎ

전 이렇게 해서 어셈하고 조금 친해졌답니다 ㅋ

비쥬얼 스튜디오 디버깅 사용법 txt파일 올려둘께요 ㅋ

간단한 사용법은 브포(F9)를 걸고 싶은 곳에 거신후에 실행(F5)을 합니다.

그 다음에 Ctrl + F11 버튼을 누르시면 디버깅 모드로 됩니다.

그 다음 부터는 txt파일 안에 있는 명령어들 보고 하시면 됩니다 ㅎ

'[+] My Think and LIfe > [-] ETC' 카테고리의 다른 글

훈훈한 메리크리스마스  (0) 2009.12.25
저 군대 가요 1월 4일  (10) 2009.12.19
어셈 공부하는 법??  (8) 2009.12.12
새로운 바탕화면  (10) 2009.12.10
우와 난 아이피가 두개야.  (17) 2009.12.09
  1. Favicon of https://strangeronpaleblue.com BlogIcon 이방인펠블닷 2009.12.14 00:20 신고

    ㅋㅋㅋㅋ어셈 공부하던 저번학기 도무지 짜증나서 아...그냥 VS 디버깅모드 돌려서
    어셈으로 바꾼다음에 내버릴까 하는 생각 했었는데...
    조교형이 딱 보더니 너 누가 VS돌려서 하래......ㅎㄷㄷ
    딱 보고 알더라구요...VS는 가끔가다가 희한하게 어셈하는 부분이 있어서 티가난다면서...

    그렇다면...그형님도....경험자???ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

    • Favicon of https://maj3sty.tistory.com BlogIcon MaJ3stY 2009.12.14 00:33 신고

      음... 너무 완벽해서 그런거 아닐까요 ㅋ

      그리고 디버깅 모드하면 쓰레기 부분들이 있으니.. ㅋㅋ

      좀 잘하시는분인듯? ㅎ

      아니면 말씀대로 유경험자 ㅋ

  2. Favicon of https://sun2day.tistory.com BlogIcon Sun2Day 2009.12.14 09:22 신고

    헤더나 스타트업펑션을 보면 컴파일러마다 특징이 있다고 합니다 ㅇ_ㅇ

    VS같은 경우 헤더의 특정부분에 컴파일러버전이 들어간다고 알고있습니다 (+__)ㅋ

    • Favicon of https://maj3sty.tistory.com BlogIcon MaJ3stY 2009.12.14 16:49 신고

      오호~ 컴파일러마다 그런 부분이!!!

      그렇게 해서 어떤걸로 컴파일 됬는지 확인하는건가요 ? ㅋ

    • Favicon of https://sun2day.tistory.com BlogIcon Sun2Day 2009.12.14 16:53 신고

      글쎄요 ㅇ_ㅇ;;

      제가 직접 확인해보진 못해서..

      수학쟁이님께서 쓰신글에 그런 내용이 있었어요 ㅇ_ㅇ;;

      PEiD같은 툴에선 그런 방식이 아니라 다른 방식일꺼같다.. 란식으로 글을 써놓으셨던걸로 기억합니다. ㅇ_ㅇ;;;

      수학쟁이님은 찾아서 물어보세용 +_+ㅋ

    • Favicon of https://maj3sty.tistory.com BlogIcon MaJ3stY 2009.12.14 23:47 신고

      음... 수학쟁이님이라.. 들어봤는데 어디서;;;

  3. Favicon of http://zzibong.ffhosting.net BlogIcon zzibong 2009.12.17 21:42

    잘가요 ㅠㅠ

+ Recent posts