PE 재배치를 실습하기 위해서 ollydbg와 PEView를 이용했다.

그런데 PEView를 이용해서 계산을 해도 ollydbg로 보면 엉뚱한 값이 나와서 당황했다.



이렇게 notepad.exe를 실행시키고, ImageBase를 확인하기 위해서 스크롤을 맨위로 올렸는데 "E61000"이라는 주소가 있다. 이게 ImageBase 인줄 알고 계산을 했기때문에 정상적인 값이 나오지 않았다.


저 그림에 M이라는 버튼을 클릭하면 Memory Map이 나오는데 거기서 PE Header라고 쓰여있는 주소를 더블클릭하면 PE Header 구조가 나온다. 


여기서 ImageBase를 확인해본 결과



이렇게 code window에서 확인한 "E61000"이 아니라 "E60000"인것을 알 수 있었다.

구글링 해보니 .text 영역의 크기(1000)를 더한 값이라는 설명이 있었다.

'Reversing(리버싱 핵심 원리) > 개념' 카테고리의 다른 글

UPack PE 헤더 상세 분석  (0) 2019.03.25
실행 파일에서 섹션 추가하기  (0) 2019.03.23
C언어 #Pragma commnet, #Pragma data_seg 란  (0) 2018.09.04
EP(Entry Point)란  (0) 2018.09.04
64비트 리버싱  (0) 2018.08.29

프로세스를 실행시키는 방법은 아래와 같다

1. 바탕화면에 있는 아이콘을 실행

2. 프로그래밍을 통해 프로세스 실행(부모-자식 프로세스)


위의 2가지는 사실 똑같은 방법이다.

- 바탕화면도 프로세스이다.

- 더블클릭 이벤트가 발생하면 바탕화면(부모) 프로세스가 클릭된 프로세스(자식)을 실행시킨다.


프로세스 생성 함수

BOOL CreateProcess(

LPCTSTR lpApplicationName,

LPTSTR lpCommandLine,

LPSECURITY_ATTRIBUTES lpProcessAttributes,

LPSECURITY_ATTRIBUTES lpThreadAttributes,

BOOL bInheritHandles,

DWORD dwCreationFlags,

LPVOID lpEnviroment,

LPCTSTR lpCurrentDirectory,

LPSTARTUPINFO lpStartupInfo,

LPPROCESS_INFORMATION lpProcessInformation

);


첫 2가지와 마지막 2가지가 중요하다.

- LPCTSTR lpApplicationName : 실행 파일 이름


- LPTSTR lpCommandLine : 매개변수 (실행 파일 이름까지도 여기에 표현가능)


- LPSTARTUPINFO lpStartupInfo : 생성하려는 프로세스의 정보(전달 목적)


- LPPROCESS_INFORMATION lpProcessInformation : 생성된 프로세스의 정보(제공받기 위한 목적)



LPSTARTUPINFO 구조체


typedef struct _STARTUPINFO {

DWORD     cb;                 // 구조체 변수의 크기

LPTSTR       lpReserved;

LPTSTR       lpDesttop;

LPTSTR       lpTitle;            // 콘솔 윈도우의 타이틀 바 제목

DWORD     dwX;              // 프로세스 윈도우의 x 좌표

DWORD     dwY;              // 프로세스 윈도우의 y 좌표

DWORD     dwXSize;        // 프로세스 윈도우의 가로 길이

DWORD     dwYSize;        // 프로세스 윈도우의 세로 길이

DWORD     dwXCountChars;

DWORD     dwYCountChars;

DWORD     dwFillAttribute;

DWORD     dwFillAttribute;

DWORD     dwFlags;           // 설정된 멤버의 정보

WORD       wShowWindow;

WORD       cbReserved2;

LPBYTE       lpReserved2;

HANDLE     hStdInput;

HANDLE     hStdOutput;

HANDLE     hStdError;

} STARTUPINFO, *LPSTARTUPINFO; 


cb로 구조체의 크기를 전달하는 이유

- CreateProcess 함수의 9번째 전달인자가 다른것도 올 수 있게 하도록 라이브러리를 개편하는 경우 구별하기 위해서 전달한다.



LPPROCESS_INFORMATION 구조체는 지금 알필요 없다.


typedef struct _PROCESS_INFORMATION

{

HANDLE    hProcess;            //프로세스의 핸들

HANDLE    hThread;            // 쓰레드 핸들

DWORD    dwProcessId;        //프로세스 ID

DWORD    dwThreadId;        //쓰레드 ID

}PROCESS_INFOMATION




표준 검색경로

- 파일을 오픈할때 경로를 명시해주지 않으면 다음과 같은 순서로 실행파일을 찾는다.


1. 실행중인 프로세스의 실행파일이 존재하는 디렉터리

2. 실행중인 프로세스의 현재 디렉터리(Current Directory)

3. Windows의 시스템 디렉터리(System Directoy)

4. Windows의 디렉터리(Windows Directory)

5. 환경변수 PATH에 의해 지정되어 있는 디렉터리



프로세스

- 메인 메모리로 이동하여 실행중인 프로그램 (일반적인 정의)


프로세스 범위

- 메모리 구조 + 레지스터 Set

- 프로세스 별 독립적인 대상(레지스터 Set)은 프로세스의 범주에 포함시킬 수 있다.



Context Switching

- A라는 프로세스가 연산을 하고 B라는 프로세스로 전환되는 것


- 1초에 수십번씩 진행된다. 그래서 사용자에게는 여러 프로세스가 동시에 실행되는 것 처럼 보여진다.


- Context Switching이 일어날 때, 레지스터 Set을 비워줘야지 다음 프로세스의 데이터를 저장할 수 있다.

그런데 1초에 수십번씩 진행되는 Context Switching 특성상 이러한 방법은 굉장히 비효율적이다.


- 그래서 각 프로세스 별로 레지스터 Set을 독립적으로 할당해주는 기법이 있다.

 


프로세스 스케줄러 

- 윈도우에서 SoftWare적으로 구현되어있는 장치(Block)


- 둘 이상의 프로세스가 적절히 실행되도록 컨트롤 한다.


- CPU입장에서는 스케줄러도 하나의 프로세스이다.



프로세스의 상태

- Ready : 스케줄러가 선택해주길 기다리는 상태(프로세스는 실행을 위한 모든 준비가 다 됨.)


- Running : 현재 cpu에 의해 실행중인 상태 

(CPU의 코어가 1개이면 Running 상태에 있는 프로세스의 개수는 1개이다.) 

(일반적인 실행은 CPU에 의존적인 연산이고, I/O연산은 CPU에 의존적이지 않은 연산이다.)


- Blocked : CPU에 의존적이지 않는 연산을 하고 있는 상태


ex)

1. A,B 프로세스가 Ready 상태이다.

2. A 프로세스가 스케줄러에 의해 Running 상태가 됬다.

3. 연산을 하다가 I/O 연산을 수행한다.

4. A 프로세스는 I/O 연산이 끝날 때 까지 Blocked 상태가 되고, B 프로세스가 Running 상태가 된다.

5. A 프로세스가 I/O 연산이 끝나고 CPU에 의한 연산이 남아있다면, 다시 Ready 상태가 된다.


★주의★

꼭 I/O 연산을 한다고 Running 상태가 해제 되는것이 아니라, 우선순위에 의해서 다른 프로세스들도 실행을 시켜야 하기 때문에 Running 에서 Ready 상태가 되기도 한다.



Context Switching 추가 설명

- Running 상태의 프로세스(A)의 데이터가 레지스터 Set에 저장되어있다.


- Ready 상태의 프로세스(B)가 Running 상태가 되기 위해선 레지스터에 Set에 B에 관한 데이터가 저장되야 한다.


- A의 데이터가 있는 레지스터 Set은 메모리에 저장되고, 메모리에 저장 되어있던 B의 데이터는 레지스터 Set에 복원된다.


- 이러한 과정이 끝난 후 B는 Running 상태가 된다.


- 프로세스의 범위에 '메모리 구조 + 레지스터 Set'이 포함되는 이유가 위의 과정 때문이다.






+ Recent posts