본문 바로가기

개인 공부/리버싱

Reverse Engineering-001(Assembly)

어셈블리어(Assembly Language) 

  • 컴퓨터 언어들 중에 낮은 레벨의 언어 (컴퓨터에 가까운 언어!!)
  • 기계어와 1:1 대응이 되는 프로그래밍언어
  • CPU마다 고유한 어셈블리 언어를 갖는다

어셈블리어의 명령 포맷(X86 CPU : IA-32 기준)

  • Opcode(명령어) + Operand(인자)
Opcode Operand(목적지) Operand(출발지)
MOV EAX EBX

레지스터(Register) : 데이터의 저장 공간 용도이다(컴퓨터 언어의 변수 느낌?!)

  • EAX(Accmaulator Regist) : 산술 연산, 리턴 값 전달, 가장 많이 사용되는 레지스터! 
  • EBX(Base Regist) : 포인터에 많이 사용되는 레지스터
  • ECX(Count Regist) : 반복 카운팅에 사용되는 레지스터(for 문에 i,j.. 느낌!!)
  • EDX(Data Regist) : EAX와 역할은 같지만 리턴 값은 전달하지 않는다, OEP값이 입력되는 레지스터
  • ESI(Source Index) : 데이터 출발지 주소에 대한 값, 문자열이나 각종 반복되는 데이터를 처리 또는 메모리를 옮기는데 사용하는 레지스터
  • EDI(Destination Index) : 데이터 목적지 주소에 대한 값을 저장하는 레지스터
  • EBP(Base Point) :스택의 시작 주소를 저장하는 레지스터
  • ESP(Stack Point) : 스택의 끝 주소를 저장하는 레지스터
  • EIP(Instruction Point) : 다음 명령어가 실행될 메모리 주소를  저장하는 레지스터

※ PE 추가내용

  • ImageBase : PE 파일 저장되는 시작 주소(exe파일은 주로 0x00400000)
  • address of entry point : 메모리의 실제 시작 주소
  • OEP(Original Entry Point) :  메모리의 실제 시작 주소(ImageBase + address of entry point)

EAX등의 레지스터(EBX, ECX, ...)는 4Byte(32bit) 크기이다

AX는 2Byte(16bit) = AL 1Byte(8bit) + AH 1Byte(8bit)

레지스터 크기


엔디언(Endian) : 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 것을 의미한다

  • 빅 엔디언(Big Ednian) : 데이터가 상위 바이트로부터 메모리에 적재되는 것 (왼쪽 -> 오른쪽)
    • ex) DATA : 0x12345678 -> [12] [34] [56] [78]
  • 리틀 엔디언(Little Endain) : 데이터가 하위 바이트로부터 메모리에 적재되는 것 (오른쪽 -> 왼쪽)
    • ex) DATA : 0x12345678 -> [78] [56] [34] [12]
Little Endian Big Endian
낮은 비트 열에 먼저 들어와서
들어오는 족족이 연산을 바로 할 수 있다 
높은 비트 열에 먼저 들어와서
데이터를 다 받아와야 연산을 할 수 있다  
산술 연산 속도가 빠르다 산술 연산 속도가 느리다
비교 연산시에는 불리하다 비교 연산시에는 높은 비트열 먼저
비교해서 유리하다

 


Opcode(명령어)

  • PUSH [operand] : 스택 영역에 공간을 할당하고 [operand]에 값을 저장한다
  • POP [operand] : ESP가 가르키는 곳의 값을 [operand]에 저장하고  ESP가 가르키는 공간 정리
  • MOV [operand1] [operand2] : [operand2] 값을 [operand1]으로 넣는다([operand]가 1개일 경우 [operand1]은 EAX!!)
  • LEA [operand1] [operand2] : [operand2] 값의 주소를 [operand1]으로 넣는다 ([operand]가 1개일 경우 [operand1]은 EAX!!)  
  • CMP [operand1] [operand2]:  비교 연산할 때 사용
  • JMP [operand] : 주소로 이동 (점프)
    • JE [operand] :  CMP연산 후 값이 같을 경우 점프
    • JNE [operand] : CMP 연산 후 값이  다를 경우 점프
    • JZ : CMP 연산 후 값이 0 이면 점프
    • JNZ : CMP 연산 후 값이 0이 아니면 점프
  •  산술 연산
    • ADD [operand1] [operand2] : 더하기 연산 명령어 (ADD EBX일 경우 스택을 정리)
    • SUB [operand1] [operand2] : 빼기 연산 명령어 (SUB EBX일 경우 스택을 확보)
    • MUL [operand1] [operand2] : (부호가 없는)곱하기 연산 명령어( [operand]가 1개일 경우  [operand1]은 EAX!!)
    • IMUL [operand1] [operand2] : (부호가 있는)곱하기 연산 명령어( [operand]가 1개일 경우  [operand1]은 EAX!!) 
      • EAX * ECX 연산 할 경우 EDX : EAX에 저장된다(상위 비트 = edx, 하위 비트 = EAX) 
      • AX  * CX 연산 할 경우 DX : AX에 저장된다 (상위 비트 = DX, 하위 비트 = AX)
      • AL * CL 연산 할 경우 AX에 저장된다
    • DIV [operand1] [operand2] : (부호가 없는) 나눗셈 연산 명령어
    • IDIV [operand1] [operand2] : (부호가 있는) 나눗셈 연산 명령어
      • EAX / ECX 연산 할 경우 EAX : EDX에 저장된다 (몫 = EAX, 나머지 = ECX)
      • AX / CX 연산 할 경우 AX : DX에 저장된다 (몫 = AX, 나머지 = DX)
      • AL / CL 연산 할 경우 AL : AH에 저장된다 (몫 = AL, 나머지 = AH) 
  • 논리 비트 연산
    • AND [operand1] [operand2] : [operand]를 비교해서 모두 참이라면 참 그외 거짓! 
    • OR [operand1] [operand2] :  [operand]를 비교해서 하나가 참이라면 참 그외 거짓!
    • XOR [operand1] [operand2] :  [operand]서로 다르면 참!!, 주로 레지스터를 초기화 할때 사용(XOR EAX EAX )
    • TEST [operand1] [operand1] :  [operand]끼리 AND연산,  [operand]에 값이 있는지 없는지 확인하는 명령
  • NOP : 아무것도 하지 않고 무조건 통과(리버싱할 때 치트키 같은 친구!)
  • INC [operand]  / DEC [operand] : 1씩 증가, 1씩 감소 (1++, 1--)
  • INT [상수만] : 인터럽트를 일으키는 명령어
  • CALL [operand] : 함수 호출 명령어
  • RET : 함수의 종료 시 사용되는 명령어, 함수가 종료되어 스택에 저장된 복귀주소로 돌아간다!! (POP EIP + ADD ESP와 비슷, return!!)

 


 

'개인 공부 > 리버싱' 카테고리의 다른 글

Reverse Engineering-006 PE-01  (0) 2023.04.17
Reverse Engineering-005  (0) 2023.04.13
Reverse Engineering-004(C++)  (0) 2023.04.12
Reverse Engineering-003(구조체 & API)  (0) 2023.04.12
Reverse Engineering-002(문법)  (0) 2023.04.10