글 목록 보기

?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

관리자 권한을 가진 상태에서 MsiExec.exe /I{A0F05048-7653-4FCD-9F3A-C740E4052ACE}


를 실행하면 Rsfx Driver 언인스톨러를 띄울 수 있습니다. 이걸 먼저 언인스톨 한 후,  2012 Uninstall 을 하면 삭제 가능합니다.

TAG •
?

Lyn
조회 수 15391 추천 수 0 댓글 3
Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

이 코드는 Visual C++ 2013 RC에서 테스트 되었습니다.


C#을 자주 쓰시는 분들이라면 아시겠지만... C# 에는 @ 로 시작하는 문자열 리터럴이 있습니다.
저 안에서는 줄바꿈도 자유롭게 허용되고 Escape Sequence 할 필요도 없이 다양한 문자열을 쓸 수 있지요.
저같은 경우는 특히 쿼리를 날릴때 매우 유용하게 쓰고 있습니다.


csharpa.png


이런식으로요.


이게 C++ 할때도 참 부러웠는데... VC++ 2013 에서 드디어 사용 가능하게 되었습니다.
바로 R 접두사를 이용해서요..... 정확히는 괄호도 필요하지만


간단한 예제 만들어 보겠습니다.

#include <iostream>
#include <string>

using namespace std;

void wmain()
{
	string s = R"(Hello World
동해물과 백두산이 마르고 닳도록
\r\n\t
\가 안먹어!!
"따옴표도 그냥 써져!")";

	cout << s << endl;
}


의 실행 결과는 다음과 같습니다.


11.png


오! 멋지게 출력 되네요. (" 와 ") 가 문자열의 범위를 지정하는 태그로 쓰이는겁니다
하지만 여기 함정이 있습니다...

바로 )" 를 출력할 수 없단겁니다 (.....)

왜냐면 종료 태그로 쓰기 때문이죠.


즉 

#include <iostream>
#include <string>

using namespace std;

void wmain()
{
	string s = R"("(Test)")";

	cout << s << endl;
}


이런 코드는 오류라는 겁니다....

하지만 근성의 C++ 위원회 (...) 이번에도 그냥 넘어가지 않습니다. 
C++ 에서는 이것을 "시작 토큰 커스터마이징" 기능을 넣음으로서 해결했습니다...

이게 뭐냐면,  Raw String Literal 의 첫 ( 를 만날때 까지의 문자열을 "태그" 취급 합니다.

즉 아래와 같은 코드가 가능해집니다.


#include <iostream>
#include <string>

using namespace std;

void wmain()
{
	string s = R"Lyn("(Test)")Lyn";

	cout << s << endl;
}


RSL 의 첫 (를 만날때 까지 Lyn 이라는 문자열을 추가로 만났습니다.
그럼 위 리터럴의 시작을 나타내는 문자는 Lyn(, 종료를 나타내는 문자는 )Lyn 이 되는겁니다.
실행해보면 아래와 같습니다.


22.png


이로서 알아보긴 더럽게 힘들지만 (...) 맘껏 문자열을 만들수 있게 되었습니다.
아직 실제로 활용해보진 못햇지만, R"SQL(INSERT INTO TABLE VALUES(1, 2, 3))SQL" 처럼 이 문자열은 SQL 이다! 라는 것 처럼 표시하는식으로 사용해 볼 수 있을 것 같네요.


마지막으로 한가지... 유니코드 리터럴은 어떻게 하냐면... LR로 시작하면 끝입니다 (...) 간단하죠

TAG •
?
  • profile
    Lyn 2013.10.07 09:01
    아직 거의 쓰이지 않는 문법이라 그런지 syntax highlighter 가 제대로 컬러링을 못해주네요 =_= 젠장
  • ?
    사무엘 2013.10.07 18:57
    아아 이건 좀 내가 아는 C++과는 다른 사기적인 기능 같습니다... ㅎㅎ
    인텔리센스용 컴파일러, 코드 생성용 컴파일러, 신택스 하이라이팅용 파서 만드는 사람들.. 다 바빠지겠네요.
  • profile
    Lyn 2013.10.12 09:10
    간단하게 쓸수있는 문법이니 쓸모가 많을거 같습니다 ㅎㅎ.

Lyn
조회 수 14774 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

MS빠 인증 (...) 이라고 생각해도 될까요.

역시 개발툴은 MS가 최고죠..

1.png

?

Lyn
조회 수 21738 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

속도가 아주 쬐~금 올라간 거 같긴 하네요.


역시 변경 이후는 PC를 쓸땐 상관 없는데 터미널 쓸때는 구석에 딱 맞춰서 마우스 이동하는게 쉽지 않기 때문이었습니다 =_=;

습관적으로 마우스 죽~ 끌면 터미널 창 밖으로 나가버리니...


이전시간은 OS 설치 30분, 데이터 백업 30분, 세팅맞추는데 15분 정도 해서 1시간 좀 넘게 걸렸네요. 데이터가 그리 많지 않다는 점이 컷지요.

?
  • profile
    Lyn 2013.09.28 22:07
    몇가지 테스트 해보니 생각보다 많이빠른데? ㅡ.ㅡ;;;

2013.09.27 20:20

VS2013 RC 설치해봄

Lyn
조회 수 13822 추천 수 0 댓글 0
Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

VS2013 RC를 설치 해 봤습니다.

왠지 설치 할 때 로그인을 하려면 하라는군요.


디바이스 간에 설정 같은거 연동해 준답니다... 여러군데 왔다갔다하면서 개발하는경우엔 편리하겠네요.


vs start.png


전 일단 연동하지 않았고 다음으로 진행 하니 옵션창이 뜹니다.
옵션이 좀 다양해졋네요.


start2.png


기념할만한 첫 실행 스샷입니다.
프로젝트 템플릿에 크게변화된건 없지만 왠지 파이썬과 타입스크립트가 기본으로 들어가 있습니다.

타입스크립트는 MS에서 만들었으니 그렇다 쳐도 파이썬은 좀 의외네요. 단 파이썬의 경우는 목록에는 있지만 툴이 기본설치되진 않아 따로 받아야 합니다.

proj.png

?

2013.09.23 07:50

현재 MSDN Download Page

Lyn
조회 수 19153 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

page.png


얼마전이랑 비교했을때 큰 변화는 없는데 Windows 8.1 Enterprise 가 올라왔네요.
그외엔 바뀐게 없어보입니다.

TAG •
?

Lyn
조회 수 21815 추천 수 0 댓글 0
Atachment
첨부 '5'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

이 코드는 Visual Studio 2012 Update3에서 테스트 되었습니다.


boost 1.46 부터 추가된 icl 컨테이너들은 범위를 가지는 데이터들을 넣을 수 있게 되어 있는 컨테이너다


이것들은 주로 일정 등의 데이터를 관리하기에 아주 좋게 되어 있고(boost 예제도 대부분 그런쪽입니다) 매우 확장성이 좋게 설계 되어 있어 다양한 용도로 활용 가능하지만 개인적으론 map의 기본형인 boost::icl::intervap_map<T1, T2> 의 형태가 매우 비상식적이라고 생각한다.


그래서 interval_map 을 원하는 형태로 만들어서 쓰고 싶었고 그 과정에서 알게된 것을 정리 해 본다.

내가 최종적으로 원하는 형태는 프로그램이 처음 시작할때 로딩되는 범위를 가지는 데이터를 관리 하고, 중복되는 경우가 있을경우 데이터 오류로 취급하여 예외를 발생 하는 형태입니다.


하나씩 알아보자면 interval_map 의 기본 개념은 기존의 std::map 과 같지만, 몇가지 추가적인 개념이 존재한다.

1. 구간.

구간이란 0~1, 2~3, 12:00~13:00 처럼 범위를 가지는 데이터. 수학시간에 배웠던것처럼 개구간, 폐구간, 반폐구간(좌/우) 가 존재합니다.
뭐 이건 문제될 것 없는 당연한 경우라고 보입니다.


2. Combine

입력한 구간이 서로 겹칠 경우 그 구간에 대해 Combine 동작을 시행합니다.
이것에 대해선 아래에서 마저 합니다.


3. 기본값

웃기게도 왠지 모르겠지만 (...) 기본값에 대한 처리를 변경할 수 있습니다.

여기에서 기본값이란 static T; 로 선언 했을때의 초기값입니다. int라면 0, float 라면 0.0f, std::string 이라면 길이0인 문자열인 식입니다.


1번 구간에 대해서는 별로 문제가 될 경우가 없을겁니다. 상식적으로 사용 할 수 있지요.
계속 울궈먹을 기본 코드 하나 넣겠습니다


#include <boost/icl/interval_map.hpp>
#include <string>
#include <utility>
#include <cstdio>

void wmain()
{
	using namespace std;
	using namespace boost;
	using namespace boost::icl;

	interval_map<int, wstring> ivm;

	ivm.add(make_pair(interval<int>::right_open(0, 2000), L"Right"));
	ivm.add(make_pair(interval<int>::left_open(2000, 3000), L"Left"));
	ivm.add(make_pair(interval<int>::closed(3000, 4000), L"closed"));
	ivm.add(make_pair(interval<int>::open(4000, 5000), L"Open"));

	auto it = ivm.find(1000);
	if(it != ivm.end())
	{
		wprintf(L"Find %s\n", it->second.c_str());
	}
	else
	{
		wprintf(L"Not Found");
	}
}


기본적인 사용 방법은 위와 같습니다. 구간을 지정해서 데이터를 넣고 find로 찾아오는형식으로 map과 완전히 동일합니다.

결과도 별다를게 없구요


1.png


위 코드를 자세히 보시면 3000 이라는 값은 left, closed 두개의 데이터가 겹치는 구간이라는 것을 알 수 있습니다.
이때 3000을 찾아서 출력해 보면 어떤 결과가 일어 나냐면....


2.png


이런 상황이 벌어집니다 (...) 
왜냐면 interval_map은 구간이 겹칠 경우 Combine 작업을 진행 하는데 이 단순히 interval_map<T1,T2> 로 선언한 Combine의  동작이 + 연산입니다.

즉 겹치는 구간의 데이터를 몽땅 더해서 출력해 버립니다. 숫자라면 값이 더해질것이고 문자열이라면 위처럼 문자열일 경우 두 문자열이 붙어서 나타납니다.

이 Combine 연산을 미리 몇가지 제공 하고 있는데, 이렇게 더한다던지, stl 컨테이너에 insert 를 한다던지 최대값/최소값으로 교체한던지 하는 기본적으로 많이 쓸만한 연산을 제공 하고 있습니다....만 내가 필요한 문제있을시 예외던지는 Combine은 제공 하지 않습니다.


두번째로 기본값 문제입니다. 위 코드를 수정해서 아래처럼 바꾼 후 실행해보겠습니다.


3.png



[0~2000) 구간에 빈 문자열을 넣었지만 찾을수 없다고 하고 있습니다.

왜냐면 그 Type의 기본값이 들어갈 경우 데이터를 넣지 않는것이 interval_map 기본형의 동작입니다


하지만 이 상황에서 내가 원한건 데이터 없음과, 빈 문자열을 데이터로 가지는것을 확실하게 구별 해야 하는겁니다.

값이 빈값인건 빈값이고,  없는건 없다고 할수 있어야되는 상황이더 많다고 생각되는데.... 왜 이런지는 모르겠습니다.


이 동작을 바꾸는 기능을 icl 은 제공 하고 있는데 두가지 옵션을 하나의 구조체로 만들어 총 4종류의 형태를 제공합니다.
partial_absorber, partial_enricher, total_absorber, total_enricher 의 4가지입니다.

여기서 뒤에 붙은 absorber, enricher 이 기본값을 어떻게 처리할지 결정합니다.
absorber는 날려버리고(초기형태) enricher 는 보존합니다. partial_enricher 로 바꾼 뒤 다시 한번 실행해 보겠습니다.


4.png


보다시피 찾아오는것에 성공하는 것을 볼 수 있습니다.

다음으로 앞에 붙은 partial, total 은.... 당췌 이게 어떻게 돌아가는지 모르겠습니다 =_=;;;;; 뭘로 하던 내가 원하는 동작에 지장이 없었기에 넘어갔습니다.
차후 추가적인 확인이 필요할듯 합니다. 아마 사용자 정의 type 에서만 영향을 미치는지도 모르겠습니다. 기본형은 이미 다 되어있고 ...


그리고 이제 combine 을 방지해야 하는데... combine functor 를 새로 만듬으로서 가능했습니다. 
겸사겸사 실수로 substract 를 호출하는것을 방지하기 위해 inverse functor 도 만들었습니다. 어차피 오류낼거니 궂이 따로 만들 필요는 없어서 그냥 같이 쓰도록 되었네요.


5.png


그 결과가 이 코드입니다. 중간에 less는 std::less 입니다. 비교 functor 가 템플릿에서 앞에 있는 바람에 저렇게 들어가버렷네요.

어쨋든 멋지게 assert 를 내 주네요. 원하는 동작이 만들어 졋습니다. 구간별 데이터를 안전하게 저장 할때 사용할수 있겠습니다.
궂이 사용 예를 추가해 보자면 ip 별 지역 정보를 넣어놓고 빠르게 검색할때 사용할 수 있겠네요.

TAG •
?

Lyn
조회 수 20248 추천 수 0 댓글 1
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

111111.png

SQL Server 2014를 제외한 거의 모든 제품이 정식 으로 등록되었네요.
개인적으론 Hyper-V + WIndows 2012R2에 큰 기대중입니다. VMWare 보며 부러워 했던 기능들이 많이 추가되었네요.

TAG •
?

Lyn
조회 수 25250 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

두번째 방법으로는 CRT의 예외 핸들러에서 UnhandledExceptionFilter로 데이터를 넘겨서 생성하는 방법인데요...
이는 안정적이고 정석적이지만 치명적인 단점으로 CRT에서 던지는 예외가 하나가 아니라는겁니다... 


어쨋든 코드를 보면


#include <Windows.h>
#include <DbgHelp.h>
#include <cstdio>
#include <string>

using namespace std;

#pragma comment(lib, "dbghelp.lib")

LONG __stdcall TopLvFilter(PEXCEPTION_POINTERS pExceptionPointer)
{
	MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInformation;
	std::wstring DumpFileName = L"dmpfile.dmp";

	MinidumpExceptionInformation.ThreadId = ::GetCurrentThreadId();
	MinidumpExceptionInformation.ExceptionPointers = pExceptionPointer;
	MinidumpExceptionInformation.ClientPointers = FALSE;

	if (DumpFileName.empty() == true)
	{
		::TerminateProcess(::GetCurrentProcess(), 0);
	}

	HANDLE hDumpFile = ::CreateFile(DumpFileName.c_str(),
		GENERIC_WRITE,
		FILE_SHARE_WRITE,
		nullptr,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL, nullptr);

	MiniDumpWriteDump(GetCurrentProcess(),
		GetCurrentProcessId(),
		hDumpFile,
		MiniDumpNormal,
		&MinidumpExceptionInformation,
		nullptr,
		nullptr);

	::TerminateProcess(::GetCurrentProcess(), 0);

	return 0;
}
void InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{
	EXCEPTION_POINTERS ExceptionPointer;
	EXCEPTION_RECORD ExceptionRecord;
	_CONTEXT ContextRecord;

	ZeroMemory(&ContextRecord, sizeof(ContextRecord));
	RtlCaptureContext(&ContextRecord);

	ZeroMemory(&ExceptionRecord, sizeof(EXCEPTION_RECORD));
	ExceptionRecord.ExceptionCode = STATUS_INVALID_CRUNTIME_PARAMETER;	
	ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Eip;
		
	ExceptionPointer.ExceptionRecord = &ExceptionRecord;
	ExceptionPointer.ContextRecord = &ContextRecord;

	TopLvFilter(&ExceptionPointer);
}
void main()
{
	SetUnhandledExceptionFilter(TopLvFilter);
	_set_invalid_parameter_handler(InvalidParameterHandler);
	atoi(nullptr);	 
}



구조는 간단합니다. RtlCaptureContext 를 이용해서 현재 쓰래드의 Context를 캡쳐 해 오고, 익셉션 코드와 현재 코드가 실행중인 위치를 넘겨 주면 되는데요..
x86 시스템에서 현재 실행중인 위치는 Eip 레지스터에 있기 때문에 캡쳐해온 Context에서 Eip를 
ExceptionAddress로 넘겨 주면 됩니다.


이 방식은 안정적이고 백신이 오진을 할 가능성도 없고 Windows 8 에서도 아무 문제 없이 작동 하지만 ... 위에서 말한것처럼 예외가 이거 하나가 아니라는게 문제가 됩니다.
예를들어 메모리 할당 예외는 _set_invalid_parameter_handler 로 처리 할 수 없습니다. 하지만 어차피 몇개 안되기도 하고 (...) 그냥 몇개 더 만들어주면 될 문제지요.


정말 골때려 지는건 3rd party 에서 SetUnhandledExceptionFilter 를 호출해서 자기껄로 만들어버리는 라이브러리가 있다는겁니다 =_=; 적은 내안에만 있는게 아닌거죠...그래서 첫번째 방법과 두번째 방법을 모두 적용해 두는게 좋다고 생각 합니다


TAG •
?

Lyn
조회 수 32540 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

사후 디버깅을 위해 가장 많이 쓰이는 방법중 하나가 메모리 덤프를 남기는 방법입니다.

보통 아래와 같은 형태로 구현 하게 되는데요. 과연 이 프로그램은 덤프가 남을까요?


#include <Windows.h>
#include <DbgHelp.h>
#include <cstdio>
#include <string>


using namespace std;

#pragma comment(lib, "dbghelp.lib")

LONG __stdcall TopLvFilter(PEXCEPTION_POINTERS pExceptionPointer)
{
	MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInformation;
	std::wstring DumpFileName = L"dmpfile.dmp";

	MinidumpExceptionInformation.ThreadId = ::GetCurrentThreadId();
	MinidumpExceptionInformation.ExceptionPointers = pExceptionPointer;
	MinidumpExceptionInformation.ClientPointers = FALSE;

	if (DumpFileName.empty() == true)
	{
		::TerminateProcess(::GetCurrentProcess(), 0);
	}

	HANDLE hDumpFile = ::CreateFile(DumpFileName.c_str(),
		GENERIC_WRITE,
		FILE_SHARE_WRITE,
		nullptr,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL, nullptr);

	MiniDumpWriteDump(GetCurrentProcess(),
		GetCurrentProcessId(),
		hDumpFile,
		MiniDumpNormal,
		&MinidumpExceptionInformation,
		nullptr,
		nullptr);

	::TerminateProcess(::GetCurrentProcess(), 0);

	return 0;
}

void main()
{
	SetUnhandledExceptionFilter(TopLvFilter);	
	atoi(nullptr);
}


네. 결론부터 말하자면 위 코드에서는 덤프가 남지 않습니다.
왜냐면 CRT 에서 에러가 발생하면 UnhandledExceptionFilter 를 CRT가 자신의 예외 핸들러로 다시 세팅 하기 때문입니다.

그러나 우리가 바라는건 별로 친절하지도 않은 (...) CRT의 에러메세지가 아니라 메모리 덤프지요.

우리가 원하는대로 덤프를 남기는 방법은 여러 가지가 있지만 그 중 한가지로 해결 해 보겠습니다.

이번에 사용 할 방법은 코드를 패치해서 CRT가 감히 내가 만든 예외처리기를 바꾸지 못하도록 (...) 하는 방법입니다



#include <Windows.h>
#include <DbgHelp.h>
#include <cstdio>
#include <string>

using namespace std;

#pragma comment(lib, "dbghelp.lib")

BYTE HotPatchingBackup[5];

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI NullSetUnhandledExceptionFilter(
  _In_  LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
)
{
    return nullptr;
}

void InstallAPIHook_SetUnhandledExceptionFilter()
{
    BYTE *pSetUnhandledExceptionFilter;

    DWORD ProtectOption = 0;
    DWORD Temp = 0;

    pSetUnhandledExceptionFilter = (BYTE*)&SetUnhandledExceptionFilter;

	HANDLE hSelfProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE, ::GetCurrentProcessId());
	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, PAGE_EXECUTE_WRITECOPY, &ProtectOption);     	

    memcpy(HotPatchingBackup, pSetUnhandledExceptionFilter, 5);

    *pSetUnhandledExceptionFilter = 0xE9;
	pSetUnhandledExceptionFilter++;
    *((DWORD *)(pSetUnhandledExceptionFilter)) = ((DWORD)NullSetUnhandledExceptionFilter) - ((DWORD)pSetUnhandledExceptionFilter + 4);	
	pSetUnhandledExceptionFilter--;

	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, ProtectOption, &Temp);

	CloseHandle(hSelfProcess);
}

void UnInstallAPIHook_SetUnhandledExceptionFilter()
{
    BYTE *pSetUnhandledExceptionFilter;

    DWORD ProtectOption;
    DWORD Temp;

    pSetUnhandledExceptionFilter = (BYTE*)&SetUnhandledExceptionFilter;
	
	HANDLE hSelfProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE, ::GetCurrentProcessId());
	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, PAGE_EXECUTE_READWRITE, &ProtectOption);    

    memcpy(pSetUnhandledExceptionFilter, HotPatchingBackup, 5);

	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, ProtectOption, &Temp);     

	CloseHandle(hSelfProcess);
}

LONG __stdcall TopLvFilter(PEXCEPTION_POINTERS pExceptionPointer)
{
    MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInformation;
    std::wstring DumpFileName = L"dmpfile.dmp";

    MinidumpExceptionInformation.ThreadId = ::GetCurrentThreadId();
    MinidumpExceptionInformation.ExceptionPointers = pExceptionPointer;
    MinidumpExceptionInformation.ClientPointers = FALSE;

    if (DumpFileName.empty() == true)
    {
        ::TerminateProcess(::GetCurrentProcess(), 0);
    }

    HANDLE hDumpFile = ::CreateFile(DumpFileName.c_str(),
        GENERIC_WRITE,
        FILE_SHARE_WRITE,
        nullptr,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, nullptr);

    MiniDumpWriteDump(GetCurrentProcess(),
        GetCurrentProcessId(),
        hDumpFile,
        MiniDumpNormal,
        &MinidumpExceptionInformation,
        nullptr,
        nullptr);

    ::TerminateProcess(::GetCurrentProcess(), 0);

    return 0;
}

void main()
{
    SetUnhandledExceptionFilter(TopLvFilter);
    InstallAPIHook_SetUnhandledExceptionFilter();
    atoi(nullptr);
    UnInstallAPIHook_SetUnhandledExceptionFilter();
}


API 훅을 해서 필터를 바꾸려 하면 아무 일도 하지 않는 NullSetUnhandledExceptionFilter 이 호출되도록 하여 막는 방법입니다...
멋있어 보이기는 하지만 이 코드는 64bit/32bit 를 따로 만들어야 하고, 심지어 윈도우 8 에서는 이 코드가 정상적으로 동작 하지 않습니다 (....) 아마도 강화된 보안때문에 그런게 아닌가 싶은데...

어쨋든 윈도우7 까지는 정상적으로 덤프가 남습니다.


그럼 이런 편법 말고 좀 정석적인 방법이 필요한데... 그건 다음글로...

TAG •
?

Board Pagination Prev 1 ... 3 4 5 6 7 8 9 10 11 12 13 Next
/ 13