IT 그리고 정보보안/Knowledge base 227

세그먼테이션(Segmentation) 과 페이징(Paging)

가상메모리를 관리하는 기법인 세그먼테이션(Segmentation) 과 페이징(Paging)에 대해 알아보자. 먼저 가상메모리는 메모리에 로드된 즉, 실행중인 프로세스가 가상의 공간을 참조하여 마치 커다란 물리메모리를 갖고 있는 것처럼 사용할 수 있도록 하는 것이다. 간단하게 말해 실제 메모리 주소가 아닌 가상의 메모리 주소를 주는 방식을 말한다. 예를 들어, 내가 실행하고자 하는 프로그램의 용량이 5GB인데, 메모리(RAM)는 4GB이다.. 그럼 어떻게 실행하지? 4GB에 10GB를 올리는 것도 문제인데, 억지로 올린다고 쳐도.. 해당 프로그램이 실행될 때는 다른 작업은 아무것도 못하게 되지 않는가. 이런 경우 사용되는 기술이 바로 가상메모리다. 가상메모리는 각 프로세스 당 메인메모리와 동일한 크기로 하..

바이트 오더링 (Byte Ordering)

메모리를 저장하는 방식인 바이트 오더링에 대해 알아보자. 리틀 엔디언과 빅 엔디언 방식을 얘기하는 것이다. Big Endian (빅엔디언) 시작주소에 상위 바이트부터 기록하는 것. 사람이 보는 방식과 동일한 순서로 저장된다. 12 34 56 78 이렇게 들어온다면 12 34 56 78 이대로 저장하는 방식. 대형 유닉스 서버에 사용되는 RISC 계열 CPU와 IBM370 컴퓨터, 네트워크 프로토콜에 사용된다. (참고로 응용프로그램에서 리틀엔디언을 써도 네트워크 통신 시에 엔디언 방식을 바꿔야 함.) Little Endian (리틀엔디언) 시작주소에 하위 바이트부터 기록하는 것. 인텔 x86 CPU에서 사용된다. 유닉스나 윈도우 시스템... 12 34 56 78 이렇게 들어오면다면 78 56 34 12 이..

함수 호출 규약 (Function Calling Convention)

함수 호출 규약, Function Calling Convention 에는 여러가지 종류가 있다. 각 호출 규약들은 파라미터 받는 순서, 인자 정리 하는 방법 등 여러가지 차이점들이 존재한다. 한번 알아보도록 하겠음. 1. __cdecl C, C++ 에서 default 값으로 사용되는 호출 규약이다. 기본 호출 규약. 함수 호출자(caller)가 인자를 정리한다. 인자 호출은 오른쪽에서 왼쪽 즉, 뒤에서 부터 앞으로 __cdecl 은 함수 인자의 갯수를 미리 알고 호출하기 때문에 가변 인자를 호출할 수 있다. 함수 정의 방식은 "_함수명" 인자 정리를 add를 이용하여 한다. 2. __stdcall Win32 API 함수들이 사용하는 호출 규약이다. __cdecl과 다르게 함수 피호출자(callee)가 인..

메모리 스택(Stack)영역

스택에 대해 알아보자. 알고 있을진 모르겠지만 스택의 역할은 뭐.. 로컬 변수 임시 저장, 함수 호출 시 파라미터 전달, 리턴 어드레스 저장 등이 있다. 구조는 후입선출이다. Last In First Out 가장 마지막에 넣은 녀석부터 다시 튀어나온다는 것. (POP연산을 한다고해서 튀어나온다고 표현을 했는데 실제로는 그 값은 살아 있지만 후에 나올 esp가 pop연산을 만나면 자동으로 4바이트 아래로 내리기 때문에 튀어나오는 것 처럼 보이는거.) 스택은 메모리에 높은 주소 쌓이는 이유는 힙과 마주보며 쌓이면서 메모리를 좀더 효율적으로 사용할 수 있도록 하기 위해서 이렇게 설계되었다고 하는데 구체적인 이유가 2가지 정도 있다. 1. 높은 주소부터 거꾸로 스택을 채워나가면 스택영역이 커널영역에 침범할 일이..

x86 메모리 구조

우리는 인텔 32비트 시스템 즉, 8086 시스템에 대해 알아본다. x86 메모리 구조 (8086 Memory Architecture) 는 아래와 같이 생겼다. 위에서 부터 설명하겠음. * 커널 영역 : OS의 시스템 코드가 로드되는 부분이다. 우리가 직접 건드릴 수 없는 영역이다. * Off-Limit 영역 : 사용자가 커널 영역에 접근하지 못하도록 할당 해둔 공간이다. * 유저 영역 : 유저가 실제 사용하는 영역이다. 스텍, 힙, 코드 영역이 여기에 포함된다. * Null Pointer 할당 영역 : 모두 0이고 변경 불가능한 영역, 시스템 보호 차원에서 만들어둔 영역 위 메모리 구조는 윈도우 기준이고, 리눅스는 커널영역이 1GB 이다. 32비트 기준으로.. 시스템에 실행되는 모든 프로세스들은 4GB..

리버싱(Reversing) 그리고 올리디버거(Ollydbg)

Reverse Engineering (역공학) 말그대로 프로그램을 뒤집어 까는 것이다. 리버싱 하는 방법에는 2가지가 있다. 먼저 정적 분석 파일을 실행하지 않고 있는 그대로의 모습으로 분석하는 것이다. 파일 종류, 크기, 헤더, API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털 인증서 등의 다양한 내용을 확인하는 것이다. 디스어셈블러를 이용해 내부 코드와 구조를 확인하는 것도 여기에 속한다. 다음 동적 분석 파일을 직접 실행 시켜서 분석하는 것이다. 디버깅을 통하여 흐름과 메모리 상태 등을 살펴보는 방법. 파일, 레지스트리, 네트워크 등을 관찰하고 디버거를 이용하여 프로그램 내부 구조를 분석하는 것이다. 이 두가지 방법을 적절히 혼용하여 사용하면 된다. 이 외에 기초적인 단어들..

어셈블리 - REP 명령어

REP 명령어는 REP뒤에 오는 스트링 명령을 CX 레지스터가 0이 될때까지 반복하는 명령이다. 한번 명령이 실행되면 CX 레지스터의 값은 1 감소한다. 예를 들어, REP MOVS byte ptr [edi], byte ptr [esi] 이런식으로 쓸 수 있다 중간에 STOS, MOVS, SCAS 가 올 수 있는데 각각 의미는 STOS : 크기에 따라 (AL/AH/AX/EAX)를 EDI가 가르키는 주소에 저장한다 MOVS : ESI, EDI 증가 SCAS : AX와 비교하여 같으면 아래로, 같지 않으면 계속 명령 실행

어셈블리어 - CALL / JMP / RET

ADD, SUB, INC 등의 보면 딱 알 수 있는 명령어에 대한 포스팅은 안하겠음. CALL, JMP, RET 는 중요하니까 해야지. CALL : 프로시저를 호출하는 명령이다. 프로시저? 바로 함수를 이야기하는 것임. CALL과 JMP의 차이는 RET다. 너무 두루뭉술한 말이구나 내가 적어놓고도. CALL은 호출되고 난 후에 이전에 실행중이던 프로시져로 복귀를 해야하고 JMP는 그럴 필요가 없다. 즉, RET명령이 필요없다는 것 CALL을 이용하여 호출하면 "프롤로그" 과정부터 수행해야한다. 지금껏 분석하면서 프롤로그는 많이 보았을 터임. ESP레지스터를 EBP에 저장하여 복귀지점을 기록하는 것이다. 그리고 처음에 스택 공간을 할당한 것은.. 그 함수가 사용하는 매개변수가 잇을 때. 호출 한 후 복귀할..

어셈블리어 - CMP

비교하는 명령이다. CMP 명령은 첫번째 값에서 두번째 값을 뺐을 때 마이너스(-)가 되는 경우 CF=1 0일 경우 ZF=1 플레그가 설정된다. 플래그는 CPU의 FLAG 레지스터에 저장되는 처리 데이터 이다. FLAG의 한 비트가 한 플래그가 됨. 그 플래그가 어떻게 설정되냐에 따라 분기문 조건이 달라진다. CMP명령으로 플래그가 어떻게 설정하느냐에 따라 조건 분기 명령이 다 다르다. 표에 정리를 궁금증이 하나 생기게 된다. 그럼 플래그를 어디서 확인해?? Ollydbg에 레지스터 창에서 확인이 가능하다. C P A Z S T D O 이친구들이 모두 앞서 설명한 플래그 레지스터 들이다. 모든 산술 연산, 논리 연산이 끝나고난 결과값에 대해 상태 플레그값을 설정한다. C: Carry flag : 연산결과..

반응형