'컴'에 해당되는 글 307건
- 2013.02.21 금일 세미나
- 2012.11.29 typedef struct
- 2012.10.12 DLL을 DLL에서 불러오기.
- 2012.10.12 C# 외부 프로그램 종료하기 / C# Process.GetProcessesByName
- 2012.10.12 [MFC] 프로그램 안에서 외부 파일을 실행시키기(WinExec, ShellExecute, CreateProcess)
- 2012.07.30 usb 예약된영역 Reserved Area
- 2012.07.02 첫사용이네
typedef 는 기존에 존재하는 자료형의 이름에 새 이름(별명)을 부여하는 것을 목적으로 한다.
예를 들어 앞서 선언한 포인터를 이런식으로 선언한다면,
typedef struct point
{
int xPos;
int yPos;
} Point; /* 구조체 선언과 동시에 struct point에 Point 라는 새 이름(별명)을 부여하게 된다. */
int main(void)
{
Point P; /* struct라는 키워드를 생략하고 구조체 변수를 생성할 수 있다.
Point = struct point 처럼 되었다고 생각하면 된다.
P.xPos = 3;
P.yPos = 5;
}
보통 데이터를 묶어 사용할 때 struct를 많이 사용하는데 struct와 typedef struct의 차이점을 모르고 사용하는 경우가 있습니다. 이에 그 차이점을 정리해 보고자 합니다.
struct의 사용법으로 3가지 정도가 있습니다
아래와 같습니다.
1>
typedef struct
{
int data;
int text;
} S1;
// S1이라고 타입정의합니다. C와 C++에서 문제없이 동작합니다.
2>
struct S2
{
int data;
int text;
};
//S2라고 타입정의합니다. 이 형태는 C++에서만 가능합니다. C에서는 Error를 냅니다.
3>
struct
{
int data;
int text;
}S3;
// 이 문장은 C와 C++에서 문제없이 동작합니다.
// 하지만 주의할 점은, S3를 타입정의가 아닌 직접 변수로 선언하게 됩니다. S3자체가 변수입니다.
// 컴파일러는 S3변수를 위한 메모리를 할당하게 됩니다. S1,S2는 타입정의만 하기 때문에 메모리 할당이 당연히 없습니다.
// 사용 예
void main()
{
S1 mine1; // 문제없이 동작합니다. 이때 S1은 typedef입니다.
S2 mine2; // 역시 문제없이 동작합니다. 이때 S2도 역시 typedef입니다.
S3 mine3; // 문제가 발생합니다! S3는 typedef가 아니라 변수입니다. 따라서 S3 mine3;는 옳지 않습니다.
S1.data = 5; // 에러가 발생합니다. S1은 변수가 아닌 typedef입니다.
S2.data = 5; // 역시 에러가 발생합니다. S2는 변수가 아닌 typedef입니다.
S3.data = 5; // 잘 동작합니다. S3자체가 변수이기 때문에 문제가 없습니다.
}
다음으로 linked lists를 사용할 때 차이점을 알아보겠습니다.
1>
struct S6
{
S6* ptr;
};
// 위 문장은 C++에서만 가능합니다. C++ only
// C++에서는 위와같이 linked lists구조로 갈 수 있겠죠.
2>
typedef struct
{
S7* ptr;
}S7;
// 위 문장은 언뜻보면 문제가 없을 것으로 보이지만, 일단 C나 C++에서 에러를 낸다고 합니다.
// 하지만 무조건 에러를 내는것은 아닙니다. 컴파일러가 single-pass 이냐 multi-pass이냐에 따라서 가불이 결정됩니다.
gcc컴파일러 같은 single-pass의 경우 방금 말한 것처럼 저런 구문은 안됩니다. 이유는, S7* ptr; 구문에서 S7의 형태를 미처 파악 못하였기 때문에 에러를 내고 사용할 수 없다고 합니다. 하지만 multi-pass컴파일러의 경우는, 일단 저 문제시되는 부분에서는 에러 대신 unresolved symbol로 해놓고 지나갑니다. 그 후 다시 그 부분을 재처리해서 문제없이 동작하게끔 합니다. 컴파일러의 차이에 의해서 저 구문이 가능할 수도 있고 불가능할 수도 있다는 게 요지입니다.
대안책으론, S7* ptr; 대신 void* ptr;로 대체하고 타입캐스팅을 이용하면 문제없이 저 형태를 쓸 수 있을 것입니다. 그리고 struct대신에 class를 사용해도 문제 해결이 될 것입니다.
이상 간략하게 struct{}와 typedef struct{}에 대하여 알아봤습니다.
일단 새 프로젝트 - MFC - MFC 라이브러리 인가? 그거쓰고 옵션은 MFC 확장 DLL로 줌.
생성하면 거의 새하얀 백지의 코드가 보임.
extern "C" __declspec(dllexport) 뒤에 함수형태.
그리고 기술함.
클래스 형식의 DLL을 델파이에 이식시키기위해서 2주일 동안 쇼를 해봤지만 되지않음.
그래도 방법은 있었다.
DLL의 함수들을 가짜 생성자? 에 쑤셔넣어서 메모리에 등록시키는 법이었다.
extern "C" __declspec(dllexport) int ConstFunction(void)
{
hIns = LoadLibrary("xxxxxx.dll");
a = GetProcAddress(hIns, "DLL내부 함수명");
b = GetProcAddress(hIns, "DLL내부 함수명");
c = GetProcAddress(hIns, "DLL내부 함수명");
}
머 이런식으로 전역변수로 a b c 를 선언하고 메모리할당용 함수를 하나 만들어주면 완료된다.
typedef int ( *a )( int , int ); // a라는 함수포인터를 코드 맨윗줄쯤 추가해줘야 동작하겠지.
소멸자는 FreeLibrary() 로 인스턴스핸들을 인자로 넣어주면 메모리에서 삭제된다.
시박. 이거때문에 내가 2주동안 말도안되는 상상을 해가면서 부풀린 코드만 몇백줄이다.
다른분들은 부디 이런짓 안하길바라면서...
참고로 C++로 만들어진 출처없는 DLL을 다시 DLL로 다듬어서 델파이에 이식시키기 위해서 이짓을하였다.
그리고 알아낸것은 C# 또는 C++로 만들어진 클래스DLL 파일은 델파이에 이식이 불가능(?) 하다고 한다.
확실하진않음.
델파이의 .NET이 지원되는 버전부터 이식이 가능. 그 하위버전에서는 클래스는 무리인듯. 함수로 하길..
'Windows 개발' 카테고리의 다른 글
Win7 64bit Eprocess 구조체 (0) | 2013.08.23 |
---|---|
Write a very small KMDF driver (0) | 2013.08.23 |
Keyboard Filter Driver 제작. ( Key Logger ) (0) | 2013.08.22 |
C# 외부 프로그램 종료하기 / C# Process.GetProcessesByName (0) | 2012.10.12 |
[MFC] 프로그램 안에서 외부 파일을 실행시키기(WinExec, ShellExecute, CreateProcess) (0) | 2012.10.12 |
프로그램을 하다보면 필요에 의해서 제작중인 프로그램 내에서 외부프로그램(타프로그램)을 종료시켜야할 경우가 있습니다.
이럴경우 C#에서는 어떻게 할까요?
그런데 C#에서 어떻게 사용을 해야하는지, 사용하는 방법을 모를 경우가 있습니다.
저도 도데체 어디에 있으며 어떻게 사용해야하는 지 난감하더군요. 여기저기 뒤지고 검색해서 간단하게 구현한 소스를 소개합니다.
서두에 언급한 것처럼 2가지 방법을 소개할 예정이며 코드를 보시면 쉽게 이해가 되리라 생각됩니다.
1. 프로그램의 타이틀로 찾아서 종료
1) FindWindow를 사용해서 해당 프로그램의 핸들을 찾습니다.
2) SendMessage를 사용해서 종료 메시지를 보냅니다.
2. 프로세스의 이름으로 찾아서 종료
1) Process.GetProcessesByName을 사용해서 해당 프로그램의 정보를 가져옵니다.
2) 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();
} |
'Windows 개발' 카테고리의 다른 글
Win7 64bit Eprocess 구조체 (0) | 2013.08.23 |
---|---|
Write a very small KMDF driver (0) | 2013.08.23 |
Keyboard Filter Driver 제작. ( Key Logger ) (0) | 2013.08.22 |
DLL을 DLL에서 불러오기. (0) | 2012.10.12 |
[MFC] 프로그램 안에서 외부 파일을 실행시키기(WinExec, ShellExecute, CreateProcess) (0) | 2012.10.12 |
UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);
혹은 WinExec("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",SW_SHOW);
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 포인터
);
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;
HINSTANCE ShellExecute(
HWND hwnd, // 부모 윈도우 핸들
LPCTSTR lpVerb, // 동사 혹은 작업
LPCTSTR lpFile, // 실행 대상 문서
LPCTSTR lpParameters, // 컴맨드 인자
LPCTSTR lpDirectory, // 현재 디렉토리
INT nShowCmd // 보여주기 옵션
);
보통 우리가 말하는 [연결 프로그램]을 지칭합니다.
ShellExecute(NULL,
"open",
//"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", // 경로가 이렇게도 사용가능
"C:/Program Files/Internet Explorer/IEXPLORE.EXE",
NULL,NULL,SW_SHOW);
'Windows 개발' 카테고리의 다른 글
Win7 64bit Eprocess 구조체 (0) | 2013.08.23 |
---|---|
Write a very small KMDF driver (0) | 2013.08.23 |
Keyboard Filter Driver 제작. ( Key Logger ) (0) | 2013.08.22 |
DLL을 DLL에서 불러오기. (0) | 2012.10.12 |
C# 외부 프로그램 종료하기 / C# Process.GetProcessesByName (0) | 2012.10.12 |
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 |