320x100

Computer Science

컴퓨터 관련된 알고리즘, 계산, 컴퓨터 구조, 하드웨어/소프트웨어 등 컴퓨터의 전반에 대한 학문

  • 어셈블리
  • 레지스터
  • 메모리 맵
  • 인스트럭션
  • 함수 호출 규약

어셈블리란 ? Assembly 

  • 기계어와 일대일로 대응이 되는 컴퓨터 언어 (고급언어와 저급언어 사이에 있는 언어)
  • 컴파일된 기계어를 어셈블리, 해석하는 것을 Disassemble 이라고 함

 

 

프로세스 메모리 맵 Process Memory Map

  • OS가 실행파일을 실행할 때 메모리에 각각의 데이터 영역을 분리하여 할당된 Layout을 말한다.
  • 전역변수, 지역변수, 동적변수, 상수 등이 위치해있다.
  • 각 Layout마다 역할이 나뉜다.

메모리는 크게 2가지로 나뉜다.

  • 동적 메모리: 실행 중에 필요에 따라 메모리를 할당하고 해제할 수 있어 유연성이 높지만, 관리에 주의가 필요합니다.
  • 정적 메모리: 변수를 사전에 정의하여 고정된 메모리 공간을 사용하므로, 크기 변경이 불가능하지만 관리가 간편합니다.

 

레지스터란?

CPU내에 존재하는 기억장치로 메모리 외 빠른 데이터 자장 및 읽기가 가능한 장치

 

범용레지스터: 연산 결과 저장, 산술 논리 연산, 주소 저장 등 다목적으로 사용되는 레지스터 // eax, ebx, ecx, edx

인덱스레지스터: 메모리 내 데이터 접근 시 주소를 가리킬 때 사용하는 레지스터 // esi, edi

그밖에 포인터레지스터, 세그먼트레지스터, 플래그레지스터가 있다.

 

Byte Ordering

→주소를 표기하는 방식으로 크게 두가지 방식이 존재한다.

 

  • Big-endian (사람눈에 읽기 쉬움 / 디버깅 시 유리 / 네트워크 바이트 오더에서 사용)

0x12345678 → 0x12345678

  • Little-endian (대부분 사용 // 연산, 타입변환시 유리하다)

0x12345678 → 78 56 34 12 순으로 한 바이트씩 끊어서 배열된다.

 

 

ISA(Instruction Set Architecture)란?

-> 프로세서가 이해하고 실행할 수 있는 형태의 기계어 명령어

 

ex)

mov eax, 10H  - 0x10을 EAX에 넣는다.

mov | 레지스터 | 10 HEX

 

*operand : 인자

 


리눅스 중요한 명령어

 

PUSH/POP

  • PUSH: 스택에 데이터를 추가하는 연산.
  • POP: 스택에서 데이터를 제거하고 반환하는 연산.

esp(스택의 최상위) / ebp(스택의 최하위)

 

ESP: 스택의 최상위(top)를 가리키며, 함수 호출 및 리턴, 변수 저장 및 로드 시에 사용됩니다.
EBP: 스택의 최하위(bottom) 또는 함수의 스택 프레임의 기준 지점을 가리키며, 함수의 로컬 변수나 인수에 접근할 때 기준이 됩니다.

MOV

데이터나 값을 한 위치에서 다른 위치로 이동시키는 역할

 

ex)

mov eax, ebx

ebx에 있는 값을 eax에 넣는다.

eax = ebx

 

LEA

메모리 주소를 계산하여 레지스터에 로드하는 데 사용되는 어셈블리 언어의 중요한 명령어입니다. 이를 통해 복잡한 주소 계산을 간편하게 수행할 수 있으며, 포인터 연산이나 배열 처리에 유용합니다. (두줄로 적어야 할 코드를 LEA 를 사용하면 한줄에 요약해서 적을 수 있다.)

 

lea eax, dword ptr ds: [esp+8]

esp+8 한 값을 eax에 넣는다.

 

 

mov eax, dword ptr ds : [esp+8] → eax == ???

→ 0x1234aaaa

lea eax, dword ptr ds : [esp+8] → eax == ???

→ 0x40008

 

 

 

 

 

 

mov eax, dword ptr ds: [esp+8]는 esp+8이 가리키는 메모리 주소에 저장된 값을 eax에 복사합니다. 즉, 메모리에서 데이터를 가져오는 동작입니다. eax는 메모리에서 읽은 값, 즉 0x1234aaaa가 됩니다.
lea eax, dword ptr ds: [esp+8]는 esp+8의 주소값을 계산하고, 그 계산된 주소를 eax에 저장합니다. 즉, eax는 esp+8의 값인 주소 0x40008이 됩니다.

 

 

ADD/SUB

ADD와 SUB는 어셈블리 언어에서 사용되는 기본적인 산술 명령어로, 각각 덧셈과 뺄셈을 수행합니다.

 

 

INT/SYSCALL

 

int 0x80

x86에서 eax에 들어있는 값에 따라 시스템콜을 호출한다.

 

syscall

x64에서 rax에 들어있는 값에 따라 시스템콜을 호출한다.

 

* EAX는 x86 아키텍처에서 사용되며, RAX는 x86-64 아키텍처에서 사용됩니다.

* EAX는 32비트 레지스터이며, RAX는 64비트 레지스터입니다.

 

 

CMP, JMP (compare, jump)

 

cmp : if구문과 동일하다.

 

JMP 0x40001

특정 주소나 레이블로 무조건 점프하여 실행 흐름을 변경합니다. 이를 통해 루프나 조건문, 서브루틴 등을 구현할 수 있습니다

 

0x40001로 실행 흐름(eip/rip)을 변경하는 명령어

위 cmp 조건에 따라 분기하는 명령어도 존재한다.

 

 

CALL 0x400000

함수 호출

 

leave

함수의 실행이 끝나면 해당 스택 프레임이 "leave"되어 스택에서 제거됩니다. 이 과정을 통해 함수의 지역 변수와 상태가 관리됩니다

leave 명령어는 현재 스택 프레임을 정리하고 이전 스택 프레임으로 복귀하는 데 사용됩니다.

 

 

ret (return)

함수 또는 서브루틴의 실행을 마치고, 스택에 저장된 복귀 주소를 참조하여 원래의 호출 위치로 돌아가는 데 사용됩니다. 이는 프로그램의 흐름을 제어하는 데 중요한 역할을 하며, 스택을 통해 복귀 주소를 관리합니다.


 

함수 프롤로그/에필로그

메인 루틴에서 특정 함수 실행 흐름이 옮겨졌을 때 사용할 Stack과 Register를 정리하는 과정

 

프롤로그 (시작점) / 에필로그 (끝점)


SFP는 "Stack Frame Pointer"의 약자로, 스택 프레임의 시작 주소를 가리키는 레지스터입니다

RSP(=ESP)는 "Stack Pointer"의 약자로, 현재 스택의 최상위 주소를 가리킵니다. 스택의 가장 최근에 푸시된 데이터의 주소를 나타냅니다.

RBP(=EBP)는 "Base Pointer"의 약자로, 현재 스택 프레임의 시작 주소를 가리킵니다. 함수가 호출될 때 RBP는 함수의 스택 프레임을 설정하는 데 사용됩니다.

 

 

push rbp ----- [1] 

 

mov rbp, rsp -----[2]

RSP 값이 RBP에 복사되어 새로운 스택 프레임이 설정 됩니다.  (-> rbp=rsp 이므로, rbp 값이 rsp 값으로 올라온다고 볼 수 있음)

 

sub rsp, 0x10 -----[3]

0x10(HEX) = 16(DEC) 바이트

 

  • sub rsp, 0x10 명령어는 스택 포인터(RSP)를 16바이트 감소시켜 3개의 새로운 공간을 확보합니다.
  • 이 새로운 공간은 나중에 로컬 변수나 임시 데이터를 저장하는 데 사용될 수 있습니다.
  • 스택의 내용은 변하지 않지만, RSP가 새로운 스택 최상단을 가리키게 됩니다.

공간이 생기는 이유

메모리 공간 확보: sub rsp, 0x10 명령어는 RSP의 값을 16바이트 감소시킵니다. 이로 인해 스택의 최상단이 16바이트 아래로 이동하게 됩니다. 스택에서 데이터가 추가되면, 새로운 공간이 생긴다고 할 수 있습니다.

 

 

 

leave -----[4]

RSP가 RBP의 값으로 설정되며, 이전 스택 프레임의 RBP가 스택에서 꺼내져 RBP에 저장됩니다.

 

 

 

ret -----[5]

RIP는 "Instruction Pointer"의 약자로, 현재 실행 중인 명령어의 주소를 가리키는 레지스터입니다. x86-64 아키텍처에서 사용하는 64비트 레지스터로, 프로그램의 흐름 제어에 중요한 역할을 합니다.

 


함수 호출 규약

메인루틴에서 서브루틴으로 실행 흐름을 옮길 때, 어떻게 인자를 전달하고 메모리를 할당하며 결과를 반환할 지에 대한 규약

 

intel x86_64는 크게 cdecl, stdcall, fastcall, thiscall 등이 존재한다.

*fastcall : 레지스터에 사용할 인자를 적어서 사용한다.

 

아래의 어셈블리 언어를 -> C언어로 트랜스퍼 하였다.

 

Reverse Engineering

일반적인 의미로 물건, 장치, 시스템 등의 기능 및 구조를 분석한 뒤 그 원리를 이해하는 방식

→ 해킹관점에선 프로그램의 원리를 분석하는 것을 말함

프로그램의 구조를 분석하기 위해 다양한 역공학 작업을 수행함

  • 리버스 엔지니어링의 중요성

소프트웨어 취약점

악성코드 분석

비즈니스 재산 보호

저작권 침해 보호

리버스 엔지니어링은 위법인가?

→ 악의적으로 사용하지 않는이상 바이너리를 확인해서 분석하는 것은 위법이 아님.

하지만 바이너리를 패치해서 불법적인 게임 핵을 만들거나 하면 당연히 위법이 된다.

 

Static vs Dynamic

Static analysis

  • 바이너리를 실행하지 않고 디스어셈블러, 디컴파일러를 이용해 코드를 분석하는 방식
  • 프로그램이 실행중이 아니기 떄문에 분석환경의 제약이 존재하지 않는다.
  • 프로그램의 전반적인 구조를 파악하기에는 편하다.
  • 난독화가 걸려잇을 경우 분석시 어려움이 있다.

Dynamic analysis

  • 디버거 등을 이용해 메모리, 레지스터, 코드 흐름등을 프로그램을 실행하는 중에 실시간 분석하는 방식
  • Data, Code flow를 읽기 쉬움
  • 분석 환경 구축이 필요함
  • 코드가 클 경우 분석 시 많은 시간이 소요될 수 있음

리버싱엔지니어링 이론 (분석순서)

  • 파일구조확인, 파일정보확인

윈도우에서 돌아가는지, 리눅스에서 돌아가는지 .. 어떤 인스트럭션 셋을 가지고 코드가 구현이되어 있으며 파일의 크기는 어느정도인지

  • 정적분석

코드에 대한 전반적 구조를 파악하고 취약할 것 같은 것을 리스트업함

  • 동적분석

프로그램의 취약해보이는 부분을 가지고 내가 A라는 값을 넣었을때 특정 영역에 프로그램을 잠깐 멈추는 걸 넣어서 분석, 확인하는 방법

  • 취약점 테스트

나는 이걸로 어떻게 취약점을 식별할 수 있는데를 확인해야함 예를들어, 페이로드(공격시 사용)을 해봤을떄 상대 컴퓨터에서 뭐가 날라오는지 테스트

  • 취약점 식별

 

Disassemble 디스어셈블

컴파일된 바이너리 코드를 어셈블리어로 변환하는 과정

 

Decompile 디컴파일

어셈블리어라는 로우 레벨의 언어를 고수준의 언어로 변환하는 작업


Usage of Reversing Tools

정적분석도구 Static analysis

  • IDA Decompiler

아키텍쳐, ISA 별로 디컴파일러를 만들어서 각 ISA별로 매우 잘 분석을 해준다. 단, 과금하는 방식이 아키텍쳐 하나에 얼마씩으로 나와서 가격이 비쌈

  • Ghidra (기드라를 사용해서 실습할 예정)

NSA(National Security Agency)에서 개발한 오픈 소스 리버스 엔지니어링 도구, 디스어셈블/디컴파일 지원

  • Binary Ninja

동적분석도구 Dynamic analysis

  • x64dbg, WinDbg : window 에서 사용가능
  • gdb : 리눅스에서 사용 가능

Ghidra 기드라 실습

symbol tree 왼쪽 중간

프로그램이 바이너리 형태로 되면 심볼같은게 없다.

여러가지 펑션을 자기 마음대로 명령한 것이 보인다.

실제 펑션에 대해 내용을 확인하고 싶으면 각 띄워서 분석하면되고

Assembly - 가운데 화면

어셈블리가 위치해 있는 화면, 펑선에 대한 프롤로그가 보이고, 메모리 세팅하는 것이 보임

Pseudo-Code 오른쪽 화면

 

분석을 쉽게 하기 위한 단축키

  • ctrl + L 을 눌러서 내가 분석하기 쉽게 변수를 rename 을 할 수있다
  • ; 를 누르면 코멘트를 달 수 있다.

아래와 같이 원하는 String을 Search 할 수 있다.

 

HANDSON 5

 

 


시험문제

용어관련

 

레지스터, 어셈블리 쪽에서 제출

 

아래와 같은 내용으로 시험 출제 1문제 예정

  • push instruction의 역할이 무엇인가요?
  • push instsruction을 수행하면 메모리주소가 어떻게 바뀔가요?
  • push instsruction을 수행하면 esp 가 어떻게 바뀔가요?
300x250

+ Recent posts