PEB (Process Environment Block)
-> 프로세스 정보를 담고 있는 구조체 (굉장히 크다.)
접근 방법
-> TEB.ProcessEnvironmentBlock 멤버가 PEB 구조체의 주소
-> TEB는 FS 세그먼트 셀렉터가 가리키는 세그먼트 메모리의 시작 주소에 위치한다.
-> ProcessEnvironmentBlock 멤버는 TEB 구조체 시작부터 30 옵셋만큼 떨어져있다.
PEB 주소 구하는 법(디버깅 모드시)
1. MOV EAX, DWORD PTR FS:[18]
MOV EAX, DWORD PTR DS:[EAX+30]
2. MOV EAX, DWORD PTR FS:[30]
-> 1번의 방법이 정석적인 방법 (TEB의 주소를 먼저 구하고 PEB주소를 구함.)
PEB 구조체 중요 멤버
-> BeingDebugged(+02) : kernel32!IsDebuggerPresent() 라는 API가 참조하는 정보가 PEB.BeingDebugged 멤버 (kernel32!IsDebuggerPresent() : 현재 프로세스가 디버깅 당하는 지를 판단해 결과 리턴 1: 디버깅 중, 0 : 디버깅 x)
-> PEB.ProcessHeap & PEB.NtGlobalFlag : 안티디버깅에 사용 프로세스가 디버깅 중이라면 특정한 값을 가진다.
-> ImageBaseAddress(+08) : 프로세스의 ImageBase를 표시(GetModuleHandle() API 는 ImageBase를 얻어낸다. 이 함수에 파라미터로 NULL을 주고 호출시 다음의 코드가 실행된다.)
MOV EAX, DWORD PTR FS:[18] // FS:[18] = TEB
MOV EAX, DWORD PTR DS:[EAX+30] // DS:[EAX+30] = PEB
MOV EAX, DWORD PTR DS:[EAX+8] // DS:[EAX+8] = PEB.ImageBaseAddress
-> Ldr(+00c) : _PEB_LDR_DATA 구조체 포인터, 프로세스에 로딩된 모듈(DLL)의 로딩 베이스 주소를 직접 구할 수 있는 방법을 제공한다.
_PEB_LDR_DATA 구조체
-> _LIST_ENTRY 타입의 멤버가 3개 있다.(InLoadOrderModuleList, InMemoryOrderModuleList, InInitializationOrderModuleList)
-> _LIST_ENTRY 구조체를 보면 양방향 연결 리스트 메커니즘을 제공하는 구조체라는 것을 알 수 있다.
-> typedef struct _LIST_ENTRY{
struct _LIST_ENTRY * Flink;
struct _LIST_ENTRY * Blink;
} LIST_ENTRY, *PLIST_ENTRY
연결 리스트에 저장되는 정보
-> _LDR_DATA_TABLE_ENTRY 구조체 정보
-> 프로세스에 로딩된 DLL 모듈마다 _LDR_DATA_TABLE_ENTRY 구조체를 하나씩 가진다. 이 구조체들은 _LIST_ENTRY 양방향 연결 리스트로 연결된다.(3가지 종류의 연결리스트 존재)
'Reversing(리버싱 핵심 원리) > 고급 리버싱' 카테고리의 다른 글
TEB(Thread Environment Block) (0) | 2018.09.05 |
---|---|
TLS 콜백 함수 (0) | 2018.09.04 |