모종의 음모/Notepad22009. 5. 8. 13:22


간만에 백신을 돌려보았더니
notepad2를 실행하는 부분의 레지스트리가 바이러스로 검출이 되도록 패턴이 수정되었다.


...
어떻게 피해가야 하나 -ㅁ-?
Posted by 구차니
모종의 음모/Notepad22009. 1. 4. 22:30
메뉴상에서 notepad.exe를 notepad2.exe로 대체 할 것인지에 대한 메뉴를 추가 하였다.
일단 사용한 함수는 RegSetValueEx 이다.

 
 LONG WINAPI RegSetValueEx(
   __in        HKEY hKey,
   __in_opt    LPCTSTR lpValueName,
   __reserved  DWORD Reserved,
   __in        DWORD dwType,
   __in_opt    const BYTE *lpData,
   __in        DWORD cbData
 );

기존에는 RegSetValue를 사용했었는데, 이 녀석은 Key , SubKey에 대해서 만 등록을 할 수 있지,
Value는 등록하지 못하므로 Value를 등록 할 수 있는 RegSetValueEx를 사용하게 되었다.

 RegSetValueExW(key1, L"Debugger", 0, REG_SZ, cmd, len * 2);
데이터는 위의 prototype를 보면 알겠지만,
"키,value name, 0, 변수 타입, value, 길이" 의 순서인데 reserved 값으로 0이 고정 되어 있다.

notepad2 프로젝트는 unicode로 되어 있으므로, 이에 대응하기 위해서 RegSetValueExW로 함수를 사용하였는데,
버그인지는 모르겠지만, len 부분에서 2배를 해주어야 만 제대로 value가 들어 가는 문제가 있었다.
2배라고 함은 unicode는 2byte 문자열이므로 이를 맞추어 주기 위해 2배가 된 것 같기는 하지만,
문자열이 unicode인데 길이만 따로 ascii 식으로 세어 준다는 것은 무언가의 문제가 있는 것으로 보인다.

그리고 prototype 상으로는 BYTE 타입의 문자열을 원하므로 Unicode 함수임에도 불구하고 warning을 출력한다.
--------------------Configuration: Notepad2 - Win32 Release--------------------
Compiling...
Notepad2.c
C:\cvsdown\np2src_VC6\src\Notepad2.c(2994) : warning C4133: 'function' : incompatible types - from 'unsigned short [264]' to 'const unsigned char *'
Linking...

Notepad2.exe - 0 error(s), 1 warning(s)


[출처 : http://msdn.microsoft.com/en-us/library/ms724923(VS.85).aspx]
Posted by 구차니
모종의 음모/Notepad22009. 1. 4. 00:18
Visual Studio Debugger How to: Launch the Debugger Automatically

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options

위의 키는 현재 notepad2.inf에서
(아마도) C:\WINDOWS\NOTEPAD.EXE(혹은 C:\WINDOWS\SYSTEM32\NOTEPAD.EXE)를
대체해서 실행하도록 하는 용도로 쓰이고 있다. (도대체 어느 녀석이 어느 녀석이지?)
하지만 원래 용도는, 프로그램 실행중에 죽는 경우에 디버깅을 하기 위한 방법으로 사용하는 것 이라고 한다.

[참고 : http://byung.egloos.com/3572751]
[참고 : http://www.osix.net/modules/article/?id=781]
[출처 : http://msdn.microsoft.com/en-us/library/a329t4ed.aspx]


WindowsXP SP2 에서 notepad.exe를 notepad2.exe로 교체 하는 방법에 대한 내용이다.
여기서 건진 키워드는 WFP (files protected by Windows File Protection)
[출처 : http://weblogs.asp.net/rweigelt/archive/2004/08/12/213085.aspx]

WFP는 Windows2000 부터 지원하고 있으며 C:\WINDOWS\SYSTEM32\dllcache 폴더 그리고 레지스트리와
연관이 되어 있다

WFP 기능의 작동 방법

WFP 기능은 두 가지 메커니즘을 사용하여 시스템 파일을 보호합니다. 첫 번째 메커니즘은 백그라운드에서 실행됩니다. 이 보호 기능은 WFP에 보호된 디렉터리의 파일에 대한 디렉터리 변경 알림이 나타난 후 실행됩니다. WFP에 이 알림이 나타나면 WFP는 어떤 파일이 변경되었는지 확인합니다. 파일이 보호되면 WFP는 카탈로그 파일에서 파일 서명을 찾아 새 파일이 올바른 버전인지 확인합니다. 이 파일이 올바른 버전이 아니면 WFP는 새 파일을 캐시 폴더(파일이 캐시 폴더에 있는 경우) 또는 설치 원본에 있는 파일로 교체합니다. WFP는 다음과 같은 순서로 해당 위치에서 올바른 파일을 검색합니다.
  1. 캐시 폴더(기본적으로 %systemroot%\system32\dllcache)
  2. 네트워크 설치 경로(네트워크 설치를 사용하여 시스템을 설치한 경우)
  3. Windows CD-ROM(CD-ROM을 사용하여 시스템을 설치한 경우)
WFP가 캐시 폴더에서 파일을 찾거나 설치 원본이 자동으로 발견되면 WFP는 이 파일을 자동으로 교체합니다.
[공식 : http://support.microsoft.com/kb/222193]

파일이 두개인 이유는 아마도 하위 호환성으로 인해서 기존의 하위 버전에서는 존재하지 않던
C:\WINDOWS\SYSTEM32 폴더의 호환성을 위해 C:\WINDOWS에도 notepad.exe를 놔두었다고 한다.
[출처 : http://labnol.blogspot.com/2006/03/why-two-notebookexe-files-in-windows.html]
Posted by 구차니
모종의 음모/Notepad22008. 12. 29. 23:54
메모장2 한글화를 위해서 context-menu 역시 한글로 하자는 의견이 나와서 수정을 하게 되었다.
물론.. 이번에는 검색도 없이 조언을 받아 약간의 시행오차를 거쳐 수정하게 되었다.

frhed를 이용한 테스트

step 1. 레지스트리는 HKEY_CLASSES_ROOT\*\shell 에 추가되는데 "Open in frhed" 라는 key가 보인다.


step 2. 하위 항목인 "command" 키에는 실행될 프로그램의 경로 및 인자를 넘겨 주기 위한 %1이 존재한다.


step 3. "Open in frhed" 키에 존재하는 (기본값) 의 내용을 수정해 준다.


step 4. context-menu에서 출력되는 모습을 구경한다. 기본값을 설정해준 대로 변경되었다.
   


이것을 이용하면, 출력 포맷은 바뀌어도 key는 변하지 않으므로 수정이 용이하다고 한다. (BLUE'nLIVE 님의 조언)


레지스트리 편집기를 이용하는 것 말고 프로그램으로 이것을 적용하려면 아래와 같이 하면된다.
            HKEY key1;
            LONG res = RegCreateKey(HKEY_CLASSES_ROOT,L"*\\shell\\Open with notepad2",&key1);
            if (res == ERROR_SUCCESS)
            {
                WCHAR cmd[] = L"메모장2로 열기(&E)";
                RegSetValue(key1, NULL, REG_SZ, cmd, wcslen(cmd)); // wcslen - strlen for unicode
            }

            res = RegCreateKey(HKEY_CLASSES_ROOT,L"*\\shell\\Open with notepad2\\command",&key1);
            if (res == ERROR_SUCCESS)
            {
                WCHAR cmd[MAX_PATH + 4];
                WCHAR path[MAX_PATH];
                int len;
                GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
                len = wsprintf(cmd, L"%s %%1", path);
                RegSetValue(key1, NULL, REG_SZ, cmd, len);
            }

[wcslen  : http://msdn.microsoft.com/en-us/library/78zh94ax(VS.71).aspx]
Posted by 구차니
모종의 음모/Notepad22008. 12. 28. 00:37
컴파일을 이상없이 되는 관계로!
이제 기능추가를 위해 몸부림을 쳤다 ^^;

추가 될 내용은 레지스트리 관련기능들 인데..
문제는 /D "_UNICODE" 로 인해서 함수들이 모두 유니코드 대응으로 변환되었다는 점이다.



이로 인해서 약간의 삽질이 추가 되었다.

            HKEY key1;
            LONG res = RegCreateKey(HKEY_CLASSES_ROOT,
                L"Unknown\\shell\\Open with notepad2\\command",
                &key1);
            if (res == ERROR_SUCCESS)
            {
                WCHAR cmd[MAX_PATH + 4];
                WCHAR path[MAX_PATH];
                int len;
                GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
                len = wsprintf(cmd, L"%s %%1", path);
                RegSetValue(key1, NULL, REG_SZ, cmd, len);

유니코드로 함수들이 변경되면서 char 형의 변수에서 WCHAR 형으로 바뀌고
각종 스트링들도 T 접두를 붙여서 unicode 형으로 바꾸어 주었다.
물론 sprintf 역시 유니코드를 지원하는 wsprintf로 변경!

이로서 간편하게 context-menu에서 실행이 가능하도록 설정을 할 수 있게 되었다.
Posted by 구차니
모종의 음모/Notepad22008. 12. 26. 00:48
Change Log
컨텍스트 메뉴(우클릭 메뉴) 연결을 위한 메시지 변경
Add to unknown file type -> Add context-menu to unknown file type
Add to all file type -> Add context-menu to all file type

일단은 ini 파일에 만 추가 하도록 작성을 할 예정인데, 이럴 경우에는 ini 파일 내용과
레지스트리의 설정이 일치 하지 않을 것이 우려 되어서 어디에 추가 하는 것이 깔끔할지 고려중

void LoadSettings();
void SaveSettings(BOOL);

이 두녀석으로 설정을 ini 파일로 부터 읽어 오고 저장을 하도록 하는데
최초 실행시에는 ini 파일을 생성하고

int  CreateIniFile();

종료할때 SaveSetting을 하도록 함으로서, 레지스트리에 모두 저장하는 frhed 와는
구조적으로 약간의 차이점이 있다. 아무래도 레지스트리 부분은 ini에 저장을 하되
별도로 레지스트리를 체크 하도록 별도 루팅을 적용해야 할 듯 하다.

단계
1. ini 파일에 설정을 읽는다.
2. 설정에 따른 레지스트리 설정을 확인한다.
3. ini 파일의 설정에 맞추도록 레지스트리를 설정한다.

아무래도 이렇게 해야지 안정적으로 ini 설정과 동기화가 가능할 듯 하다.
그리고 초기 설정값은 파일확장자와 연결하지 않는 것으로 하는게 편할 듯.


잡소리 : 생각해보면 별거 아닌데..
            그냥 copy & paste 하고 ini 파일에 하지 않으면 간단할 걸 너무 고민하는 것 같기도 하다.
Posted by 구차니
모종의 음모/Notepad22008. 12. 24. 00:31
MS Platform SDK를 설치 한다고 해서 바로 되는게 아니라
우선순위가 상당히 낮아져 있기 때문에 Visual Studio에서 설정을 바꾸어 주어야 한다는 말에
설정을 바꾸고 선언문을 삭제 하니 이상없이 컴파일이 되었다.




물론 소스상의 문제(?)로 프로토타입과 실제 함수의 리턴 타입이 맞지 않아 에러가 발생을 하긴 했지만 말이다.
일단 DWORD *func와 DWORD_PTR func가 같아 보이는데, 다르게 인식을 해서 생긴 문제였다.


아무튼 요즘에 Win32API 스타일로 프로그래밍을 하다 보니, 조금은 눈에 익은 녀석들이 보여서
상대적으로 그다지 어렵지는 않게 수정을 하고는 있지만, 생각보다 상당히 방대한 녀석이라..
Source Insight 없이 Visual Studio만으로 하기에는 상당히 귀찮은 느낌이 든다. ㅠ.ㅠ

오늘은 메뉴에 추가해서 체크 on/off까지만~


Posted by 구차니
모종의 음모/Notepad22008. 12. 22. 00:57

프로젝트 설정에서 기본 값으로는 PlatformSDK의 include를 사용하지 않기 때문에
Platform SDK를 설치 한다고 해서 에러가 사라지는 것은 아닌 듯 하다.

아래 글을 읽다가 문득 Platform SDK의 경로에 대해서 떠오르게 되었고, 프로젝트 설정에서
어떤 곳에도 include를 설정해 놓은곳이 없었다는 점이 떠올랐다.

[발견 : http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/0300699f-4f0d-46dc-9c47-c4f5f0a2356b]

그리고 나머지 에러는 undefined 에러 이므로.. 오리지널 소스와 비교해서 차이점을 보면 어떻게 될 듯 하고,
문제는 Scintilla 에서 선언된 것들을 끌어 오는 문제인데.. 아마도 프로젝트 환경 설정과 컴파일러 버전 차이로
/Wp64 /GS- /GF 이 세가지 옵션을 인식 못하는게 원인이라고 생각이 된다.

Visual C++ 컴파일러 옵션 /GS(버퍼 보안 검사)
[출처 : http://msdn.microsoft.com/ko-kr/library/8dbf701c.aspx]

Visual C++ 컴파일러 옵션 /GF(중복 문자열 제거)
[출처 : http://msdn.microsoft.com/ko-kr/library/s0s0asdt.aspx]



이 페이지에서 다루는 특정 제품:.
Microsoft Visual Studio 2008/.NET Framework 3.5

다음 제품들은 다른 버전에서 다루어 집니다.

이래저래.. 그냥 VC++ 6.0을 쓰지 말아야 하는 건가 ㄱ-


그리고 에러 중에 COLOR_HOTLIGHT 를 찾지 못하는 것이 있는데
이 녀석은 windows.h에서 include 하는 winuser.h에 정의 되어 있다고 한다.

COLOR_HOTLIGHT
26

Color for a hyperlink or hot-tracked item.


Requirements

Minimum supported clientWindows 2000 Professional
Minimum supported serverWindows 2000 Server
HeaderWinuser.h (include Windows.h)
LibraryUser32.lib
DLLUser32.dll

[출처 : http://msdn.microsoft.com/en-us/library/ms724371(VS.85).aspx]


그래서 내 꺼에서 파일을 봤더니..
#if(WINVER >= 0x0500)
#define COLOR_HOTLIGHT          26

헉.. 설마 CODEWIZ 님의 삽질을 유발했던 저 써글넘의 WINVER이 문제인건가 -ㅁ-!
[codewiz님의 삽질기 : http://www.jiniya.net/tt/635]


아무튼.. 소스 상에서는
#define _WIN32_WINNT 0x501 로 선언되어 있는데, 이 경우 컴파일 하면...
Notepad2.exe - 170 error(s), 41 warning(s)

이 녀석이 존재하는
Searching for '#define _WIN32_WINNT 0x501'...
C:\cvsdown\np2src_VC6\src\Dialogs.c(20):#define _WIN32_WINNT 0x501
C:\cvsdown\np2src_VC6\src\Dlapi.c(20):#define _WIN32_WINNT 0x501
C:\cvsdown\np2src_VC6\src\Edit.c(20):#define _WIN32_WINNT 0x501
C:\cvsdown\np2src_VC6\src\Helpers.c(22):#define _WIN32_WINNT 0x501
C:\cvsdown\np2src_VC6\src\Notepad2.c(21):#define _WIN32_WINNT 0x501
C:\cvsdown\np2src_VC6\src\Print.cpp(21):#define _WIN32_WINNT 0x501
C:\cvsdown\np2src_VC6\src\SciWrap.cpp(20):#define _WIN32_WINNT 0x501
C:\cvsdown\np2src_VC6\src\Styles.c(20):#define _WIN32_WINNT 0x501
8 occurrence(s) have been found.
8 녀석에게 일일이
#define WINVER 0x501 을 추가 하면
Notepad2.exe - 75 error(s), 33 warning(s)

우와~ 에러가 100개가 줄었어요 >_< (젠장!)
디버그의 신 : 너에게는 아직 100개가 줄은 것이 아니라 75개의 버그가 남은 것이란다~


잠시 검색을 했더니.. OTL 역시 적당하게 좀 더 게을렀어야 했다.

Visual C++ 2008을 시작하면 Visual C++는 Windows 95, Windows 98, Windows ME 또는 Windows NT를 지원하지 않습니다. WINVER 또는 _WIN32_WINNT 매크로를 이러한 Windows 버전 중 하나에 할당하면 해당 매크로를 수정해야 합니다. 이전 버전의 Visual C++에서 만든 프로젝트를 업그레이드하는 경우 WINVER 또는 _WIN32_WINNT 매크로를 더 이상 지원되지 않는 Windows 버전에 할당하면 해당 매크로와 관련된 컴파일 오류가 발생합니다.

해당 매크로를 수정하려면 헤더 파일에 다음 줄을 추가합니다.

#define WINVER 0x0500
#define _WIN32_WINNT 0x0500

이렇게 하면 Windows 2000 운영 체제를 대상으로 합니다. Windows XP, Windows Server 2003 및 Windows Vista에 대한 유효 값은 각각 0x0501, 0x0502 및 0x0600입니다.

/D 컴파일러 옵션을 사용하여 이 매크로를 정의할 수도 있습니다. 자세한 내용은 /D(전처리기 정의)를 참조하십시오.

[출처 : http://msdn.microsoft.com/ko-kr/library/6sehtctf.aspx]



Platfrom SDK가 설치된 상태의 Visual Studio 6.0의 환경설정이다.
문제는 Win32 Platform에 대해서만 존재하고, Microsfot SDK(platform SDK)에 경로가 잡혀 있음에도 불구하고
제대로 파일을 불러 오지 못한 것으로 보인다.

즉, 가장 위의  MIDL 에서 굳이 추가해줄 필요는 없었고, 위의 WINVER 선언만 컴파일 옵션에서 넣어 주면 되었던 것이다.
Posted by 구차니
모종의 음모/Notepad22008. 12. 21. 23:04
BLUE'nLIVE 님에게 Notepad2 VC++ 6.0 버전용을 받아서 컴파일 하려고

VC++ 6.0 깔고
Visual Studio 6.0 SP6 깔고
Platform SDK 도 깔았는데...


여전한 에러

DWORD_PTR 이란 변수명을 인식 못하고
컴파일 옵션중에 /Wp64 /S 를 인식을 못하는데.. 아직까지 해결 방법을 못찾았다.
Posted by 구차니