프로그램을 하다보면 필요에 의해서 제작중인 프로그램 내에서 외부프로그램(타프로그램)을 종료시켜야할 경우가 있습니다.

이럴경우 C#에서는 어떻게 할까요?


여러 프로그램 언어을 접해보신 분들이 알고계신 알고리즘과 동일하게 C#에서도 프로세스를 찾아서 Kill하는 방식과 FindWindow를 찾아서 SendMessage를 사용하는 방식을 사용합니다.

그런데 C#에서 어떻게 사용을 해야하는지, 사용하는 방법을 모를 경우가 있습니다.

저도 도데체 어디에 있으며 어떻게 사용해야하는 지 난감하더군요. 여기저기 뒤지고 검색해서 간단하게 구현한 소스를 소개합니다.

서두에 언급한 것처럼 2가지 방법을 소개할 예정이며 코드를 보시면 쉽게 이해가 되리라 생각됩니다.

1. 프로그램의 타이틀로 찾아서 종료


1) FindWindow를 사용해서 해당 프로그램의 핸들을 찾습니다.
2) SendMessage를 사용해서 종료 메시지를 보냅니다.

C#,C Sharp, .Net, 외부프로그램 종료, 타 프로그램 종료, GetProcessesByName, FindWindow, SendMessage, Process, Kill

2. 프로세스의 이름으로 찾아서 종료


1) Process.GetProcessesByName을 사용해서 해당 프로그램의 정보를 가져옵니다.
2) Process.Kill을 사용해서 외부 프로그램을 종료합니다.

C#,C Sharp, .Net, 외부프로그램 종료, 타 프로그램 종료, GetProcessesByName, FindWindow, SendMessage, Process, Kill

3. 프로그램 소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Process를 사용하기 위해 아래 네임스페이스 추가
using System.Diagnostics;
// DllImport를 사용하기 위해 아래 네임스페이스 추가
using System.Runtime.InteropServices;
// API Import
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd,uint Msg,int wParam,int lParam);
private void ErrExit()
{
// 타이틀 바의 이름으로 찾아서 프로그램 종료
IntPtr hwd = FindWindow(null, "테스트.txt - 메모장");
if (hwd.ToString() != "0")
SendMessage(hwd, 0x0010, 0, 0);
// 프로세스 프로그램 이름으로 찾아서 프로그램 종료
Process[] p = Process.GetProcessesByName("notepad");
if (p.GetLength(0) > 0)
p[0].Kill();
}

 

Posted by wakira
,
MFC 안에서 외부 프로그램을 동작 시킬수 있다는 (획기적인) 방법이 있다는 것을 듣고 직접 실행 시켜 보았습니다. 프로그램안에서 외부 프로그램을 동작 시켜 볼 수 있다는 점에서 참 재미가 있었네요.

1) WinExec 함수

외부 프로그램을 동작 시킬 수 있는 함수들 중에서 제일 먼저 사용된 그래서 오래된 함수(win3.x 버전부터 사용된 함수입니다.)는 WinExec함수입니다.

이 함수의 프로토 타입은

UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);

으로 사용방법은 아래와 같습니다.

WinExec("C:/Program Files/Internet Explorer/IEXPLORE.EXE",SW_SHOW);
혹은 WinExec("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",SW_SHOW);

로 프로그램안에서 위 함수를 위와 같이 인자를 넣으면 인터넷 익스프롤러가 실행이되는 구문입니다.

이 함수의 장점은 인자가 2개뿐이어서 사용하기는 간편다는 것이지만,
단점으로는 실행을 시켜 놓으면 실행이 되는지 에러가 났는지, 종료 되었는지 전혀 알수가 없다는 것입니다.

2) CreateProcess 함수

다음은 CreateProcess()의 Prototype입니다.

BOOL CreateProcess(
LPCTSTR lpApplicationName, // 실행파일 모듈의 이름에 대한 포인터
LPTSTR lpCommandLine, // 커맨드 문자열에 대한 포인터
LPSECURITY_ATTRIBUTES lpPA, // 프로세스 보안 속성 포인터
LPSECURITY_ATTRIBUTES lpTA, // 스레드 보안속성 포인터
BOOL bInheritHandles, // 핸들 상속 여부 플래그
DWORD dwCreationFlags, // 생성 플래그
LPVOID lpEnvironment, // 환경 블록에 대한 포인터
LPCTSTR lpCurrentDirectory, // 현재 디렉토리
LPSTARTUPINFO lpStartupInfo, // STARTUPINFO 포인터
LPPROCESS_INFORMATION lpPI // PROCESS_INFORMATION 포인터
);

이 함수의 실행 방법은 아래와 같습니다.

STARTUPINFO StartupInfo = {0};
PROCESS_INFORMATION ProcessInfo;
StartupInfo.cb = sizeof( STARTUPINFO );
::CreateProcess("C:/Program Files/Internet Explorer/IEXPLORE.EXE",
NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo);

만약 위의 프로그램을 실행시키고 종료하기를 기다린다고 하면,

BOOL ret = CreateProcess(............);
if(!ret)
return FALSE;

WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
return TRUE;

이렇게 하면 됩니다.

3) ShellExecute 함수

이 함수의 원형은 아래와 같습니다.

HINSTANCE ShellExecute(
HWND hwnd, // 부모 윈도우 핸들
LPCTSTR lpVerb, // 동사 혹은 작업
LPCTSTR lpFile, // 실행 대상 문서
LPCTSTR lpParameters, // 컴맨드 인자
LPCTSTR lpDirectory, // 현재 디렉토리
INT nShowCmd // 보여주기 옵션
);

일단 위의 함수를 살펴보면 CreateProcess() 함수보다 기능이 많이 떨어지는 것 처럼 보이지만 이 함수의 진정한 의미는 동사 연결이라는 점입니다.
보통 우리가 말하는 [연결 프로그램]을 지칭합니다.

이 함수는 아래와 같이 사용할 수 있습니다.

ShellExecute(NULL,
"open",
//"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", // 경로가 이렇게도 사용가능
"C:/Program Files/Internet Explorer/IEXPLORE.EXE",
NULL,NULL,SW_SHOW);

이 함수는 3번째 인자에 다양한 타입을 열수 있도록 되어 있으므로 다양한 응용이 가능한 함수가 되겠습니다.

 

Posted by wakira
,

http://forensic-proof.com/archives/372



예약된 영역(Reserved Area)는 FAT 파일시스템에서 가장 앞 부분에 위치하는 구조로서 여러 개의 섹터로 구성된다. 예약된 영역의 크기는 기본적으로 FAT12/16 에서는 1 섹터, FAT32 에서는 32 섹터를 사용한다. 예약된 영역은 다시 부트 섹터(Boot Sector), FSINFO(File System INFOrmation) 섹터, 추가적인 섹터로 구분된다. 다음은 예약된 영역의 추상적인 구조이다.

 

1. 부트 섹터

부트 섹터의 크기는 1섹터로 FAT 파일시스템의 처음에 위치한다. 부트섹터(512 바이트)의 구조는 다음과 같다.

 FAT 형식 범위 설명
 10진수 16진수
 FAT12/16 0 – 2 0x0000 – 0x0002 Jump command to boot code
 FAT32
 FAT12/16 3 – 61 0x0003 – 0x003D BIOS Parameter Block (BPB)
 FAT32 3 – 89 0x000 – 0x0059
 FAT12/16 62 – 509 0x003E- 0x01FD Boot code and error message
 FAT32 90 – 509 0x005A – 0x01FD
 FAT12/16 510 – 511 0x01FE – 0x01FF Signature (0x55AA)
 FAT32

 

부트 섹터의 처음 3 바이트는 0x003E 또는 0x005A의 부트 코드로 점프하기 위한 점프 명령어가 위치한다. 이후 클러스터 크기, FAT 크기, 루트 디렉터리 위치, 총 섹터 수 등의 파일시스템 정보를 기록한 BPB 영역이 온다. 이후에는 해당 파일시스템을 부팅하기 위한 부트 코드가 위치한다. 부트 코드는 점프 명령에 의해 실행되는데 이때 BPB 정보를 참조하여 파일시스템을 부팅한다. (NTLDR : NT Loader 실행) 부트 코드 실행과정에서 정상적이지 않은 동작이 발생할 경우 저장된 에러 메시지를 출력하게 된다.

각 BPB 영역에 대해 자세히 살펴보면 다음과같다. 

[ FAT12/16/32 ] 공통된 데이터 구조

 범위 설명
 10진수 16진수
 0 – 2 0x0000 – 0x0002 Jump command to boot code (usually 0xEB5890)
 3 – 10 0x0003 – 0x000A OEM ID (Win95=MSWIN4.0, Win98=MSWIN4.1,
 Win2K/XP/Vista=MSDOS5.0, Linux=mkdosfs)
 11 – 12 0x000B – 0x000C Bytes per sector
 13 – 13 0x000D – 0x000D Sectors per cluster
 14 – 15 0x000E – 0x000F Reserved sector count (FAT12/16=1)
 16 – 16 0x0010 – 0x0010 Number of FAT tables
 17 – 18 0x0011 – 0x0012 Root directory entry count (FAT12/16=512, FAT32=0)
 19 – 20 0x0013 – 0x0014 Total sector 16 (FAT12/16=variable, FAT32=0)
 21 – 21 0x0015 – 0x0015 Media Type
 22 – 23 0x0016 – 0x0017 FAT size 16 (FAT12/16=variable, FAT32=0)
 24 – 25 0x0018 – 0x0019 Sector per track (typically 32 for hard drive)
 26 – 27 0x001A – 0x001B Number of heads (typically 255 for hard drive)
 28 – 31 0x001C – 0x001F Hidden sectors
 32 – 35 0x0020 – 0x0023 Total sector32

 

[ FAT12/16 ] 추가적인 데이터 구조

 범위 설명
 10진수 16진수
 36 – 36 0x0024 – 0x0024 INT 0x13 drive number (Floppy=0x00, Hard Drvie=0x80)
 37 – 37 0x0025 – 0x0025 Not used
 38 – 38 0x0026 – 0x0026 Boot signature
 39 – 42 0x0027 – 0x002A Volume serial number
 43 – 53 0x002B – 0x0035 Volume label (ASCII)
 54 – 61 0x0036 – 0x003D File system type
 62 – 509 0x003E – 0x01FD Boot code and error message
 510 – 511 0x01FE – 0x01FF Signature (0x55AA)

 

[ FAT32 ] 추가적인 데이터 구조

 범위 설명
 10진수 16진수
 36 – 39 0x0024 – 0x0027 FAT size 32
 40 – 41 0x0028 – 0x0029 Ext flags
 42 – 43 0x002A – 0x002B FAT32 volume version
 44 – 47 0x002C – 0x002F Root directory cluster offset
 48 – 49 0x0030 – 0x0031 FSINFO(File System INFOrmation) offset
 50 – 51 0x0032 – 0x0033 Backup boot sector offset
 52 – 63 0x0034 – 0x003F Reserved
 64 – 64 0x0040 – 0x0040 INT 0x13 drive number (Floppy=0x00, Hard Drive=0x80)
 65 – 65 0x0041 – 0x0041 Not used (typically 0)
 66 – 66 0x0042 – 0x0042 Boot signature
 67 – 70 0x0043 – 0x0046 Volume serial number
 71 – 81 0x0047 – 0x0051 Volume label (ASCII)
 82 – 89 0x0052 – 0x0059 File system type
 90 – 509 0x0060 – 0x01FD Boot code and error message
 510 – 511 0x01FE – 0x01FF Signature (0x55AA)

 

다음 그림은 실제 필자의 컴퓨터를 FAT32로 포맷한 후 덤프한 결과이다.

위의 부트 섹터는 볼륨의 0번째 섹터이다. FAT32의 경우에는 부트 섹터가 손상될 것을 대비하여 6번째 섹터에 내용을 백업해 둔다. 따라서, 파티션 복구 도구들의 경우에 부트 섹터가 정상적이지 않을 경우 백업되어 있는 부트 섹터를 복사하여 사용하여 복구하곤 한다.

 

2. FSINFO(File System INFOrmation)

FSINFO는 일반적으로 1번째 섹터(부트 섹터 다음)에 저장되는 구조로 7번째 섹터에 내용을 백업해 둔다. 이것의 위치는 BPB에 정의되어 있기 때문에 임의로 지정이 가능하다. FSINFO 구조의 용도는 운영체제에게 첫 비할당 클러스터의 위치와 전체 비할당 클러스터의 수를 알려준다.

이것이 무슨 의미가 있을까? 우선 첫번재 비할당 클러스터의 위치를 알려줌으로써 해당 볼륨에 저장하고자 하는 파일을 빠르게 할당할 수 있도록 도와준다. 그리고 전체 비할당 클러스터의 수를 통해 해당 파일이 볼륨에 할당 가능한지 여부도 알 수 있다. 특정 볼륨에 파일을 복사할 경우 여유 공간이 있는지 없는지를 파악하기 위해서는 기존에는 FAT 영역 전체를 검색해봐야 했다. 하지만 FSINFO 구조때문에 볼륨의 여유 공간을 빠르게 파악할 수 있다. 다음은 FSINFO 섹터의 데이터 구조이다. 

 범위 설명
 10진수 16진수
 0 – 3 0x0000 – 0x0003 Signature (0x41615252)
 4 – 483 0x0004 – 0x01E3 Not used
 484 – 487 0x01E4 – 0x01E7 Signature (0x61417272)
 488 – 491 0x01E8 – 0x01EB Number of free clusters
 492 – 495 0x01EC – 0x01EF Next free cluster
 496 – 509 0x01F0 – 0x01FD Not used
 510 – 511 0x01FE – 0x01FF Signature (0x55AA)

다음은 필자의 볼륨에서 FSINFO 섹터를 확인한 것이다. 내용에서 알 수 있듯이 여유 클러스터의 수는 0x032D70(208240) 이고, 첫 여유 클러스터의 주소는 0x48E1(18657) 이다.

 

3. 추가적인 예약된 영역

앞서 부트 섹터는 0, 6번 섹터를 사용하고, FSINFO는 1, 7번 섹터를 사용한다고 했다. 이외에도 2번 섹터는 부트 섹터의 부트 코드 영역이 부족할 경우 추가적으로 사용할 수 있는 섹터이다. 그리고 이 내용은 8번에 백업해 둔다. 이렇게 기본적으로 FAT32는 0, 1, 2, 6, 7, 8번의 섹터를 사용한다.

결과적으로 총 32섹터 중 6개 섹터만 사용하고 나머지 섹터는 만약을 대비해 예약되어 있다. 따라서 이러한 섹터는 일반적으로 어플리케이션에서 접근하지 않기 때문에 간혹 예약된 나머지 영역에 데이터를 숨겨두는 경우도 있다.

 

그렇다면 항상 FAT32에서 예약된 영역을 32섹터를 가질까? 다음은 필자의 USB를 FAT32로 포맷한 후 EnCase를 통해 해당 볼륨을 살펴본 것이다. 보는 바와 같이 예약된 영역이 38섹터의 크기를 가지고 있다. 결국, 예약된 영역은 장치 타입이나 포맷 소프트웨어에 따라 변할 수 있기 때문에 반드시 부트 섹터의 오프셋 14-15의 예약된 영역 섹터 수를 확인한 후 접근해야 한다.


'usb' 카테고리의 다른 글

부팅 USB만들기!  (0) 2014.05.14
usbboot 파일 및 만들기  (0) 2014.01.05
Posted by wakira
,