지난 10월에..
DRM기술때문에 골아파 했던적이 있다..
내 Disk로 Data를 복사하려 하면..
자동으로 Encrypt Module이 Crypt 해버려서..
복사 하면 Decrypt가 불가능 했다..
(내 머리론 아직 analyzing skill이 부족하다..)
Program을 Filter Driver로 구현해서..
Ctrl + Alt + Del 키로 Process를 죽이는 것 만으로는 해결 할 수 없었다..
(Process 조차도.. API Hooking으로 숨겨 버렸다.. OTL..)
그래서 Services Registry Key를 지우는 방법으로..
Windows 시작시 Starting Key를 읽지 못하도록 하는 방법을 생각했다..
그런데 이 망할 나비씨는..
Registry 관련 API 조차 Hooking해서 접근이 불가능하게 막아버린게 아닌가!!..
이대로 물러서야 하는건가에 대해 열심히 고민하던 도중..
나 역시 그들처럼..
윈도우 시작시 Filter Driver나, Native Application으로 Registry에 접근후..
Key를 지워버리는 방식을 사용하기로 했다..
Windows에서 SMSS.exe를 생성한 다음..
Native Application을 시작 할 때는 Trust된 Windows의 일부로 인식하기에..
아무 이상 없이 잘 될거라 믿고 Unloader를 제작했다..
사실 이렇게 실전으로 Native Application을 개발하는건.. 처음이었다..
그래서 착오도 많았고..
...
Format도 많이 했다..(!?)
(사실 VM을 이용해서 그다지 힘들진 않았다..)
여튼..
최종 코드는 아래처럼 완성되었다..
간단하게 Registry Key를 지우는 거라..
극!! 초보적인 코드이다..
이런거로 고민했던 내가 좀 한심했긴 했지만..
어쨌든..
완성판을보니..
나름 뿌듯함도 있었다..
#include "ntddk.h"
#include "NativeAPI.h"
BOOLEAN RegDeleteKey(WCHAR* pwszKey);
BOOLEAN RegOpenKey(HANDLE* phKey, WCHAR* pwszSubKey);
BOOLEAN RemoveDataFromRegValue(
WCHAR* pwszSubKey,
WCHAR* pwszValue,
WCHAR* pwszData
);
void NtProcessStartup(PSTARTUP_ARGUMENT Argument)
{
ULONG i;
UNICODE_STRING uString;
WCHAR Buffer[128];
WCHAR RootKey[] = L"Services\\";
WCHAR targetKey[][16] = {
L"FDDec", // FDDec : SAFASOFT Encrpty Mobile Driver
L"FileHook", // FileHook : SAFASOFT File System Filter
L"ProcHide", // ProcHide : ProcHide Driver
L"SDFA", // SDFA : SDFA Driver
L"SFMouse", // SFMouse : SAFASOFT Mouse Filter
L"SFReg", // SFReg : SAFASOFT Registry Filter
L"SFRes", // SFRes : SAFASOFT Resource Driver
L"SFfolder", // SFfolder : SAFASOFT Encrpty Folder Driver
L"SFkbd", // SFkbd : SAFASOFT Keyboard Filter
L"Safandrv", // Safandrv : Streams Drivers
L"WWC", // WWC : Ww Client for NT
L"WwHook", // WwHook : WwHook Driver
-1
};
RtlInitUnicodeString(&uString, L"Starting WwcNT Unloader..\n");
NtDisplayString(&uString);
RemoveDataFromRegValue(
L"Control\\Session Manager",
L"BootExecute",
L"unloader"
);
RemoveDataFromRegValue(
L"Control\\Class\\{4D36E96F-E325-11CE-BFC1-08002BE10318}",
L"UpperFilters",
L"SFMouse"
);
RemoveDataFromRegValue(
L"Control\\Class\\{4D36E96B-E325-11CE-BFC1-08002BE10318}",
L"UpperFilters",
L"SFKbd"
);
for (i=0; *targetKey[i] != -1; i++) {
wcscpy(Buffer, RootKey);
wcscat(Buffer, targetKey[i]);
RegDeleteKey(Buffer);
}
NtTerminateProcess(NtCurrentProcess(), 0);
}
BOOLEAN RegDeleteKey(WCHAR* pwszKey)
{
HANDLE hKey, hReg;
WCHAR szTemp[128], szKeyBuffer[1024] = {0,};
ULONG uIndex=0, uRetSize=0;
PVOID pBuffer[1024] = {0,};
PKEY_BASIC_INFORMATION pKeyInfo = NULL;
if (!RegOpenKey(&hKey, pwszKey))
return FALSE;
wcscpy(szTemp, pwszKey);
wcscat(szTemp, L"\\");
while (1)
{
wcscpy(szKeyBuffer, szTemp);
RtlZeroMemory(pBuffer, 1024);
switch (NtEnumerateKey(
hKey,
uIndex++,
KeyBasicInformation,
pBuffer, 1024, &uRetSize))
{
case STATUS_SUCCESS:
pKeyInfo = (PKEY_BASIC_INFORMATION)pBuffer;
wcscat(szKeyBuffer, pKeyInfo->Name);
if (RegOpenKey(&hReg, szKeyBuffer)) {
NtDeleteKey(hReg);
NtClose(hReg);
uIndex--;
}
pKeyInfo = NULL;
break;
case STATUS_NO_MORE_ENTRIES:
NtDeleteKey(hKey);
NtClose(hKey);
return TRUE;
default:
NtClose(hKey);
return FALSE;
}
}
}
BOOLEAN RemoveDataFromRegValue(
WCHAR* pwszSubKey,
WCHAR* pwszValue,
WCHAR* pwszData )
{
HANDLE hReg;
UNICODE_STRING ustrValue;
PVOID pBuffer[1024] = {0,};
ULONG uRetSize;
WCHAR *pStr, szBuffer[1024] = {0,};
ULONG uStr=0, sIndex=0, uBuffer=0;
PKEY_VALUE_PARTIAL_INFORMATION pValue = NULL;
if (RegOpenKey(&hReg, pwszSubKey)) {
RtlInitUnicodeString(&ustrValue, pwszValue);
if (NtQueryValueKey(
hReg,
&ustrValue,
KeyValuePartialInformation,
pBuffer, 1024, &uRetSize) != STATUS_SUCCESS)
{
NtClose(hReg);
return FALSE;
}
pValue = (PKEY_VALUE_PARTIAL_INFORMATION)pBuffer;
if (pValue->Type == REG_MULTI_SZ) {
pStr = (WCHAR*)pValue->Data;
while (1) {
uStr = wcslen(&pStr[sIndex]) + 1;
if (uStr < 2)
break;
if (wcscmp(&pStr[sIndex], pwszData) != 0) {
memcpy(
&szBuffer[uBuffer],
&pStr[sIndex],
uStr*sizeof(WCHAR)
);
uBuffer += uStr;
}
sIndex += uStr;
}
szBuffer[++uBuffer] = 0;
NtSetValueKey(
hReg,
&ustrValue,
0,
REG_MULTI_SZ,
szBuffer, uBuffer*sizeof(WCHAR)
);
}
NtClose(hReg);
return TRUE;
}
return FALSE;
}
BOOLEAN RegOpenKey(HANDLE* phKey, WCHAR* pwszSubKey)
{
UNICODE_STRING ustrKeyName;
WCHAR Buf[1024] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\";
OBJECT_ATTRIBUTES ObjectAttributes;
wcscat(Buf, pwszSubKey);
RtlInitUnicodeString(&ustrKeyName, Buf);
InitializeObjectAttributes(
&ObjectAttributes,
&ustrKeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
return ((!NT_SUCCESS(
NtOpenKey(
phKey,
KEY_ALL_ACCESS,
&ObjectAttributes)
)
) ? FALSE : TRUE );
}