Reverse Engineering/Reversing 이론 설명 23

[MASM] 문자열과 배열

1. 문자열 프리미티브 명령 ● 문자열 프리미티브(primitive) - 바이트, 워드, 더블워드의 배열 처리를 위한 Intel 명령 집합에는 5개의 그룹이 있으며, 이를 문자열 프리미티브라고 하지만, 문자 배열로만 국한되지 않는ㄴ다. - 문자열 명령어는 메모리를 참조하기 위해 ESI, EDI 레지스터를 참조한다. - ESI, EDI는 유일하게 단일 메모리 피연산자를 사용하여, 문자열과 배열의 처리에 특히 유용 - 보호모드에서는 ESI는 자동적으로 DS가 가리키는 세그먼트에서의 오프셋이 되고, EDI는 자동적으로 ES가 가리키는 세그먼트 내의 오프셋이 된다. - DS, ES는 항상 같은 값으로 설정되고, 이를 변경할 수 없다. ● 문자열 프리미티브(primitive) 명령 명령어 설명 MOVSB, MO..

[MASM] 고급프로시저 (지역변수 선언, 스택 매개변수, 디렉터리)

1. 지역변수 - 단일 프로시저 안에서 생성, 사용, 소멸되는 변수이다. - 지역 변수에 대한 제한된 엑세스는 디버깅할 때 도움을 준다. - 지역 벼수들은 메모리를 효과적으로 사용한다. - 같은 변수 이름은 이름 충돌을 일으키지 않는 한, 두 개 또는 그 이상의 프로시저들에서 나타낼 수 있다. - 지역 변수들은 실행 시 스택에서 생성한다. ● LOCAL 디렉티브 - LOCAL 디렉티브는 하나의 프로시저 내부에서 하나 또는 그 이상의 지역 변수들을 선언한다. - PROC 디렉티브 바로 다음 행에 위치해야 한다. - 지역 변수 사용시, 어셈블러에 의해 코드 생성 - LOCAL 디렉티브에 의한 지역변수 선언 BubbleSort PROC LOCAL temp : DWORD, SwapFlag : BYTE ret B..

[MASM] 어셈블리 언어(MASM)의 기초

이제 NASM에서 벗어나, MASM으로 들어간다. 문법적 차이는 존재하지만 그렇게 큰 차이는 존재하지 않는다. NASM의 경우 []를 제외한 특수기호가 안 쓰이지만, MASM은 그 규제가 유연하다. 또한 주소지정 방식에서 차이를 보인다. NASM MASM ● 데이터 저장 時 mov ax, [data] ● 주소 지정 時 mov ax, data ● 데이터 저장 時 mov ax, data ● 주소 지정 時 mov ax, offset data 이번 공부는 '09.07.15 당시 한국항공대학교 재학중이던 배건규 님의 자료를 참고한다. 쩝... 어셈블리 책 하나 사야겠다... 돈이 깨지는 소리가 들리는 군하;; 1. 어셈블리 언어의 기본적인 구성요소 ● 산술 연산 우선순위(Precedence) : 수식이 두 개 이..

[NASM] 구조체와 C++

1. 구조체 C에서 사용되는 구조체는 연관된 데이터를 하나의 변수에 보관하는 것이라 말할 수 있다. 이는 몇 가지 장점이 있다. ● 구조체에 정의된 데이터가 연관되어 있음을 보임으로써 코드를 명료하게 할 수 있다. ● 이를 통해 함수로의 데이터 전달을 단순하게 할 수 있다. 여러 개의 변수를 독립적으로 전달하는 대신에 이를 이용해 하나의 단위만 전달하면 된다. ● 이는 코드의 지역성(locality)을 향상시킨다. 어셈블리의 관점에서 볼 때 구조체는 원소들의 크기가 제각각인 배열로 볼 수 있다. 실제 배열의 원소들의 크기는 언제나 같은 형이자, 같은 크기여야 한다. 이를 통해 실제 배열에서는 배열의 시작 주소와 원소의 크기, 원소의 번째 수 만 알면 원소의 주소를 계산할 수 있게 된다. 그러나 구조체의 ..

[System] 기계어의 구성(명령어 형식 : Instruction Format)

이전에 마이크로프로세서가 읽어들이는 숫자화된 명령어의 집합을 기계어라 하였으며, 이 기계어는 실제 시스템 프로그래밍을 하면서 직접 다루어야할 경우가 많다. 대표적인 예는 디스어셈블러나 디버거를 작성하는 경우이지만, 이외에 프로그래밍 언어에 의하여 컴파일되어진 실행 이미지의 내용을 직접 조작해야할 때나 프로그램의 함수 호출을 중간에 가로채야 하는 API-Hooking과 같은 테크닉에서 사용될 수 있다. 그럼 이제부터 실제 기계어 코드가 어떻게 구성되어 있는지 본격저으로 알아보도록 할 것이며, 여기에서 다루는 기계어 코드는 인텔 마이크로프로세서 또는 그 호환 기종에 기반한 것이다. 인텔 마이크로프로세서는 아래와 같은 내용들이 묶여 하나의 명령어를 구성하게 되는데, 이들 요소는 그 명령어에 따라 존재하는 요소..

[System] 바이트 순서 (Little Endian과 Big Endian)

다중 바이트로 이루어진 수를 단일 주소를 가진 하나의 데이터로 다루어야 할 필요가 있을 때 어떠한 바이트 순서로 그 데이터를 배열할 것인지 결정하는 것은 엔디언(Endian)이라 하며, 이때 낮은 주소에 최하위 바이트를 저장하는 방식을 리틀 엔디언(Little Endian)이라고 부르며, 이와는 반대로 낮은 주소에 최상위 바이트를 저장하는 방식을 빅 엔디언(Big Endian)이라고 부른다. 0x12345678 ※ 최상위 비트 : 12 ※ 최하위 비트 : 78 Little Endian과 Big Endian의 어원은 동화 [걸리버 여행기]에서 출발한다. 걸리버가 여행하던 소인국은 크게 2개의 파벌로 나뉘고 있었다. 그 기준은 달걀을 처음 깨는 방법, 달걀의 뾰족한 부분을 먼저 깨야한다는 파와 그 반대인 넓..

[CPU] 80286과 80386 마이크로프로세서

1. 80286 80286은 외부적으로 8086에 비해 더 빠른 속도와 더 많은 어드레스(24비트의 주소선)를 다룰 수 있게 된 것 외에 내부적으로 보호모드(Protected Mode)라는 새로운 소프트웨어 아키텍처를 출현시켰다. 80286은 전원을 넣으면 이전의 8086과 같은 실제모드로 출발하여 하위 20비트의 주소선만을 사용하여 최대 1MByte까지의 메모리를 다룰 수 있었고, 이와 같이 실제모드에서 동작하는 80286은 단지 클록속도가 빨라진 8086과 같았으며, 과거 8086 소프트웨어가 아무런 수정 없이 돌아갈 수 있었다. 하지만 프로그램에서 보호모드의 전환을 수행하게 되면80286은 멀티태스킹 환경을 지원하게 된다. 이는 각 프로그램에 독립적인 일정한 양의 메모리를 할당할 수 있게 해주며 프..

[CPU] 세그먼트 레지스터의 이용

프로그램이 수행되기 위해서는 여러 가지 메모리 주소가 필요하다. 우선 현재 수행되고 있는 명령어의 위치를 나타내는 값, 프로그램이 사용하는 데이터가 있는 메모리 값, 그리고 함수 호출 등을 위한 스택의 위치를 나타내는 값 등이다. 8086은 어드레스 버스가 20비트로 구성되어 있어서 1MByte까지 메모리 번지를 나타낼 수 있으나 8086에 있는 레지스터는 16비트밖에 되지 않아서 어떤 명령이 수행되어 메모리를 참조할 때에는 항상 다음의 표와 같이 암시적 또는 명시적으로 세그먼트 레지스터가 개입되게 된다. 세그먼트 오프셋 목적 코드 세그먼트(CS) IP 수행되어질 명령어의 위치 스택 세그먼트(SS) SP, BP 스택 주소 참조 데이터 세그먼트(DS) 범용 레지스터, DI, SI 데이터 주소 참조 보조 세..

[CPU] 8086의 레지스터들

8086 내부에는 데이터의 일시 저장, 여러 가지의 연산 처리와 번지 지정 등을 쉽고 빠르게 하기위해 많은 레지스터가 준비되어 있다. 이들 레지스터는 몇 개의 그룹으로 나뉘어 프로그램의 실행을 위한 역할을 담당한다. 즉, 각 레지스터들은 각자의 역할이 정해져 있다. 8086에서 이들 레지스터는 기본적으로 16비트로 구성되어 있고, 이들 레지스터 중 데이터 레지스터는 분할해서 8비트씩의 레지스터로 취급할 수도 있다. 1. 범용 레지스터(General Register) : 범용 레지스터는 연산 결과를 받을 수도 있으며, 연산에 사용되어질 수도 있는 레지스터이다. 과거 8비트 컴퓨터에서는 연산 결과를 저장하기 위하여 특정 레지스터를 사용할 수 밖에 없었으나 8086에서는 범용 레지스터를 사용하여 모든 연산을 ..

[CPU] 8086 세그먼트와 오프셋의 개념

8086은 1978년 인텔에서 제작된 CPU로서 처음으로 x86 아키텍처를 적용한 제품입니다. (모든 80x86 CPU는 8086을 기초로 하여 만들어졌으므로 8086에서 사용되는 명령어는 다른 80x86 제품에서도 사용할 수 있습니다.) 클럭은 제품에 따라 4.77MHz에서 10MHz까지 다양하며 16 bit 레지스터를 사용하였습니다. 내부적으로는 16 bit 레지스터를 사용했지만, 어드레스 버스가 20 bit 였으므로 1024 * 1024 = 1048576 (byte) = 1MB 만큼의 메모리를 사용할 수 있었습니다. 어드레스 버스가 20 bit 였기때문에 최대 1MB(2^20)의 메모리까지 사용할 수 있었지만, 바이오스에서 사용하는 영역인 384KB를 제외하면 640KB만을 실제로 사용할 수 있었습..