메모장 입니다2
Windows] Self Creation 본문
0.정의
-자기 자신을 자식프로세스로 생성하여, 하나의 실행파일을 두 개의 실행흐름으로 나누어 동작.
-실행 흐름이 나뉘기 때문에 디버깅을 어렵게 함.
1.실행 구조
-동작 구성도
1) 부모 프로세스 실행
2) 부모 프로세스가 "parent process"를 출력.
3) 부모 프로세스가 자기 자신(SelfCreation.exe)을 *SUSPEND 모드의 자식프로세스로 생성.
4) 부모 프로세스가 자식프로세스의 EIP를 변경(자식 프로세스가 실행할 코드로 EIP 변경)
5) 자식프로세스 Resume.
6) 자식 프로세스가 "child process"를 출력.
*SUSPEND: import DLL은 로딩되고 Main 쓰레드는 정지된 상태.
2.소스코드
-SelfCreation.exe
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
void ChildProc() //자식프로세스의 실행코드.
{
MessageBox(NULL, L"This is a child process!", L"DebugMe2", MB_OK);
ExitProcess(0);
}
void _tmain(int argc, TCHAR *argv[])
{
TCHAR szPath[MAX_PATH] = {0,};
STARTUPINFO si = {sizeof(STARTUPINFO),};
PROCESS_INFORMATION pi = {0,};
CONTEXT ctx = {0,};
_tprintf(L"This is a parent process!\n");
if( !GetModuleFileName(NULL, szPath, sizeof(TCHAR) * MAX_PATH) )
{
printf("GetModuleFileName() failed! [%d]\n", GetLastError());
return;
}
// Create Child Process
if( !CreateProcess( //자식프로세스 생성.
szPath,
NULL,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED, //SUSPEND MODE
NULL,
NULL,
&si,
&pi) )
{
printf("CreateProcess() failed! [%d]\n", GetLastError());
return;
}
// Change EIP
ctx.ContextFlags = CONTEXT_FULL;
if( !GetThreadContext(pi.hThread, &ctx) ) //자식 프로세스의 CONTEXT 정보를 얻어옴.
{
printf("GetThreadContext() failed! [%d]\n", GetLastError());
return;
}
ctx.Eip = (DWORD)ChildProc; //자식 프로세스의 EIP 변경.
if( !SetThreadContext(pi.hThread, &ctx) ) //변경된 CONTEXT를 적용
{
printf("SetThreadContext() failed! [%d]\n", GetLastError());
return;
}
// Resume Main Thread
if( -1 == ResumeThread(pi.hThread) ) //자식 프로세스 실행.
{
printf("ResumeThread() failed! [%d]\n", GetLastError());
return;
}
WaitForSingleObject(pi.hProcess, INFINITE); //자식프로세스가 종료될 때까지 기다림.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
3.디버깅
-자식프로세스의 시작주소부터 디버깅하기 위해선, 별도의 방법이 필요.
>JIT(Just-In-Time) 디버깅
->실행 중인 프로세스에 예외가 발생하였을 때, OS가 설정된 디버거를 해당 프로세스에 Attach 시켜주는 기능.
->예외가 발생한 부분부터 디버깅 가능하다.
-따라서, 올리디버거를 JIT로 설정한 뒤 자식프로세스 시작주소에 BP를 하드코딩하고 실행하면
BP예외가 발생하여 해당 지점(자식프로세스 시작주소)부터 올리디버거가 Attach되어 디버깅이 가능해진다.
-실습
1)JIT 설정
>레지스트리 값 변경
`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Current Version\AeDebug\Debugger`
->OLLYDBG 경로로 변경한다.
->확인
2)BP 설정
>자식 프로세스의 EP 주소 확인 //BP를 설정하기 위해.
->부모프로세스가 EIP 변경하는 부분을 디버깅하여 확인.
:자식 프로세스 시작주소 = 401000
>BP 설정
->401000 = RVA: 1000 = RWA: 400
3)프로그램 실행
->예외 발생
->디버깅
'Study > 리버싱' 카테고리의 다른 글
Windows] TLS 콜백함수 (0) | 2017.08.08 |
---|---|
Windows] 32bit / 64bit 차이점 - 2 (0) | 2017.08.08 |
Windows] 32bit / 64bit 차이점 (0) | 2017.08.08 |
32bit/64bit 역사 (0) | 2017.08.08 |
어셈블리] TEST, JNZ (0) | 2017.08.08 |