본문 바로가기

혼자서꿍시렁

Windows에서 프로세스 이름 숨기기

Windows에서 프로세스 이름 숨기기
 (Delete the process name from being displayed in Windows task manager.)

몇년 전(2005.08.26)에 제 홈페이지(AiRPAGE.ORG)에 올려 놓았던 글을 정리삼아 이곳에 퍼 둡니다.


뭐?  
Windows Task manager의 프로세스 탭에 나타나는 프로세스 이름을 숨기기 위한 가이드 강좌입니다. 이글과 관련한 내용이 인터넷을 뒤지면 수백개 이상이지만, 속시원히 드라이버 코드를 제시해 놓은 예는 별로 없더군요.(아예 없지는 않습니다.) 그냥 이유가 있겠지 생각하고 저도 걍 따라 하는 대신^^- 자세히 써보려 합니다.


준비물  
 


 - 환경
	Microsoft Windows® XP에서 테스트 되었습니다. 

 - Tool	
	Microsoft Visual C++® 6.0
	Windows® XP DDK

 - Library
	GunShadow Library [GunShadow Library page]
ntifs.h [ntifs.h]
 


구성  

진행해 볼 전체 목록 구성은 대충 이렇습니다.

- Windows 프로세스 관리를 위한 구조체 파악
- GunShadow Library 드라이버 일부 코드 제시

 



 ::TOP


내용  
 

자, 그럼 시작합니다!

아래 자료는 Windows가 프로세스를 관리하는 내부적인 구조체의 모습입니다. 위의 준비물 링크에서 얻을 수 있는 ntifs.h 파일에서 EPROCESS 구조체의 모습이기도 합니다. 커널 디버거에서 아래와 같이 커맨드를 주면 나타납니다.
1 kd> !processfields  
2  EPROCESS structure offsets:  
3     Pcb:                               0x0  
4     ExitStatus:                        0x6c  
5     LockEvent:                         0x70  
6     LockCount:                         0x80  
7     CreateTime:                        0x88  
8     ExitTime:                          0x90  
9     LockOwner:                         0x98  
10     UniqueProcessId:                   0x9c  
11     ActiveProcessLinks:                0xa0  
12     QuotaPeakPoolUsage[0]:             0xa8  
13     QuotaPoolUsage[0]:                 0xb0  
14     PagefileUsage:                     0xb8  
15     CommitCharge:                      0xbc  
16     PeakPagefileUsage:                 0xc0  
17     PeakVirtualSize:                   0xc4  
18     VirtualSize:                       0xc8  
19     Vm:                                0xd0  
20     DebugPort:                         0x120  
21     ExceptionPort:                     0x124  
22     ObjectTable:                       0x128  
23     Token:                             0x12c  
24     WorkingSetLock:                    0x130  
25     WorkingSetPage:                    0x150  
26     ProcessOutswapEnabled:             0x154  
27     ProcessOutswapped:                 0x155  
28     AddressSpaceInitialized:           0x156  
29     AddressSpaceDeleted:               0x157  
30     AddressCreationLock:               0x158  
31     ForkInProgress:                    0x17c  
32     VmOperation:                       0x180  
33     VmOperationEvent:                  0x184  
34     PageDirectoryPte:                  0x1f0  
35     LastFaultCount:                    0x18c  
36     VadRoot:                           0x194  
37     VadHint:                           0x198  
38     CloneRoot:                         0x19c  
39     NumberOfPrivatePages:              0x1a0  
40     NumberOfLockedPages:               0x1a4  
41     ForkWasSuccessful:                 0x182  
42     ExitProcessCalled:                 0x1aa  
43     CreateProcessReported:             0x1ab  
44     SectionHandle:                     0x1ac  
45     Peb:                               0x1b0  
46     SectionBaseAddress:                0x1b4  
47     QuotaBlock:                        0x1b8  
48     LastThreadExitStatus:              0x1bc  
49     WorkingSetWatch:                   0x1c0  
50     InheritedFromUniqueProcessId:      0x1c8  
51     GrantedAccess:                     0x1cc  
52     DefaultHardErrorProcessing         0x1d0  
53     LdtInformation:                    0x1d4  
54     VadFreeHint:                       0x1d8  
55     VdmObjects:                        0x1dc  
56     DeviceMap:                         0x1e0  
57     ImageFileName[0]:                  0x1fc  
58     VmTrimFaultValue:                  0x20c  
59     Win32Process:                      0x214  
60     Win32WindowStation:                0x1c4  
view plain | print | copy to clipboard | ?

UniqueProcessId 는 프로세스의 고유 ID입니다. ImageFileName스트링은 Ctrl - Alt - Tab키를 누를 경우 나타나는 태스크 관리자의 프로세스 탭에서 리스트되어 볼 수 있는 프로세스 이미지 이름입니다. 자- 나머지 하나 ActiveProcessLinks 가 중요합니다. 잠시 아래의 그림을 보겠습니다.



프로세스 정보들은 위와 같이 순환큐처럼 Linked list되어 앞과 뒤의 프로세스 정보를 가르키고 있습니다. 그렇게 앞과 뒤의 프로세스 정보를 가르키고 있는 링크가 바로 ActiveProcessLinks인 것입니다.
이 리스트의 제일 첫 헤드를 가르키고 있는 PsActiveProcessHead를 통해 우리는 프로세스  정보 링크를 순환할 수 있습니다. 하지만, PsActiveProcessHead는 Windows에서 Export되지 않은 심볼입니다. 그래서 다른 방법으로 우회하여 접근해야 하는데, PsInitialSystemProcess라는 노출되어 있는 심볼을 통해서 가능합니다. 물론 이것조차 노출되어 있지 않다 하더라도 각종 서적이나 웹에서 제시하고 있는 방법처럼, 현재 프로세스를 가르키는 PsGetCurrentProcess등의 API로부터 얻는 ActiveProcessLinks 포인터를 순환하여 PsActiveProcessHead를 찾을 수도 있습니다.
 그렇게, 얻게되는 PsInitialSystemProcess를 통해 프로세스 정보 리스트를 순환하여 우리는 각각의 프로세스 구조체에서 ImageFileName 변수를 얻어올 수 있습니다.

1                         //:  
2 #include <ntifs.h>  
3 //:  
4  
5 __declspec(dllimport) void *PsInitialSystemProcess;  
6 //:  
7 //:  
8  
9 PLIST_ENTRY KPEBListPtr, KPEBListPtr;  
10 PEPROCESS PFirstProcess = (PEPROCESS) PsInitialSystemProcess;  
11 PEPROCESS kpeb = NULL;  
12 ULONG uOffset_ActiveProcessLinks = 0x88; /* XP일 경우, 2000 -> 0xA0, NT 4.0 -> 0x98 */ 
13 char ProcessName[16];  
14 //:  
15 //:  
16  
17    
18 KPEBListPtr = KPEBListPtr = (PLIST_ENTRY) &PFirstProcess->ActiveProcessLinks;  
19 kpeb = (PEPROCESS)( ( (char *)KPEBListPtr ) - uOffset_ActiveProcessLinks );  
20 memcpy( ProcessName, kpeb-ImageFileName, 16 );  
21 //:  
22 //:  
view plain | print | copy to clipboard | ?

프로세스를 순환하는 방법은 링크드 리스트 순환방법이랑 똑같습니다.

1 while (KPEBListPtr->Flink!=KPEBListHead) {  
2  
3  
4 //:  
5 //:  
6 KPEBListPtr=KPEBListPtr->Flink;  
7  
8 }  
view plain | print | copy to clipboard | ?

자 그럼 프로세스를 숨겨 볼까요? 각프로세스 이름도 얻어올 수 있겠다, 프로세스 정보들도 순환할 수 있다면- 프로세스 숨기는 일도 간단하겠죠? 바로 이 링크의 순서를 바꾸는 것입니다.


데브구루(www.devguru.co.kr) 곽태진씨가 작성한 "아무도 모르는 Process"의 방법처럼 소프트아이스등의 각종 툴을 이용하여서도 조작이 가능합니다. 드라이버 상에서는 아래의 코드처럼 되겠죠?

1 //:  
2 //:  
3  PLIST_ENTRY tempKPEBListPtrBlink, tempKPEBListPtrFlink;  
4  
5  if(strcmp(toFindProcessName, ProcessName) == 0){  
6  
7                         __asm{ PUSHFD };  
8                         __asm{ CLI };  
9  
10                         tempKPEBListPtrBlink = KPEBListPtr->Blink;  
11                         tempKPEBListPtrFlink = KPEBListPtr->Flink;  
12  
13                         tempKPEBListPtrBlink->Flink = tempKPEBListPtrFlink;  
14                         tempKPEBListPtrFlink->Blink = tempKPEBListPtrBlink;  
15  
16                         __asm{ POPFD };  
17  }  
18 //:  
19 //:  
view plain | print | copy to clipboard | ?





2005.08.26, 이건우

 ::TOP


참고  


 Undocumented Windows 2000 Secrets - A Programmer's Cookbook
 (SVEN B. SCHREIBER)

 Windows구조와 원리 그리고 Codes
 (정덕영)

 아무도 모르는 Process
 (
www.devguru.co.kr, 곽태진)

 GunShadow Library page

마이크로 소프트웨어 기고 자료

- 윈도우 커널 해킹 1(마이크로소프트웨어 2005년 11월호) - 윈도우 커널 해킹 2(마이크로소프트웨어 2005년 12월호)



원본이 있는 사이트 : http://airpage.org/