ÀÌ ±ÛÀº ÇÊÀÚ°¡ Ä¿³Î µå¶óÀ̹ö¸¦ °³¹ßÇϸ鼭 Å͵æ(?)Çß´ø ¹æ¹ýµéÀ» ³ª¿­ÇÑ °ÍÀÔ´Ï´Ù. 1. UniqueProcessId ±¸Çϱâ. * PEPROCESS+0x80(¿ÀÇÁ¼ÂÀÌ Ç×»ó ÀÌ °ª º¸´Ù´Â Å©¹Ç·Î) ºÎÅÍ +PAGE_SIZE±îÁö TraverseÇÑ´Ù. * PEPROCESS´Â IoGetCurrentProcess()¸¦ ÀÌ¿ëÇϰí PID´Â PsGetCurrentProcessId()¸¦ ÀÌ¿ëÇÏ¿© ±¸ÇÑ´Ù. * for¹®À¸·Î 4ÀÇ ¹è¼ö¿¡ ¸ÂÃß¾î °Ë»öÇÏ¿© PID¿Í °°Àº °ªÀÌ ¹ß°ßµÇ¸é ±× µÚ¿¡(µÚ¿¡ ¹Ù·Î ActiveProcessLinks°¡ ³ª¿À¹Ç·Î) ActiveProcessLinksÀÇ Æ÷ÀÎÅͰ¡ ValidÇÑ VAÀÎÁö È®ÀÎÇϰí, ´Ù½Ã ³» EPROCESS±¸Á¶Ã¼·Î linkµÇ´ÂÁö üũÇÏ¿© Á¤È®ÇÏ°Ô Ã£¾Æ³½´Ù. ´ë·«ÀûÀÎ C ÄÚµå´Â ¾Æ·¡¿Í °°½À´Ï´Ù. VOID CalcPIDOffset(VOID) { PEPROCESS Proc = IoGetCurrentProcess(); HANDLE PID = PsGetCurrentProcessId(); PVOID ThisEntry = NULL, NextEntry = NULL; int i = 0; for(i = 0x80; i < PAGE_SIZE - 8; i += 4) { if(*(PHANDLE)((PCHAR)Proc + i) == PID) { // ActiveProcessLinks Offset is PID Offset+4 NextEntry = *(PVOID *)((PCHAR)Proc + i + 8); if(MmIsAddressValid(NextEntry)) { ThisEntry = *(PVOID *)NextEntry; if((PCHAR)ThisEntry == (PCHAR)Proc + i + 4) { // Probably, this is PID offset PID_OFFSET = i; return; } } } } PID_OFFSET = 0x1ec; // Exception case, so, put Offset as WinNT/2003(generic). } * ¸ðµç »óȲ¿¡ ´ëóÇÒ ¼ö ÀÖµµ·Ï, ¿¹¿Ü 󸮷δ NT/2003ÀÇ PID_OFFSETÀ» ´ëÀÔÇÏ°Ô ÇÏ¿´½À´Ï´Ù. 2. Process Name Offset ±¸Çϱâ. PEPROCESSÀÇ ÇÁ·Î¼¼½º À̸§ OffsetÀ» µû³»´Â ¹æ¹ýÀÔ´Ï´Ù. ¾Æ·¡¿Í °°ÀÌ µþ ¼ö ÀÖ½À´Ï´Ù. VOID CalcProcessNameOffset(VOID) { PEPROCESS SysProc = PsInitialSystemProcess; int i = 0; for(i = 0; i < PAGE_SIZE; i++) { if(strncmp((PCHAR)SysProc + i, "System", 6) == 0) { IMAGE_NAME_OFFSET = i; return; } } } * PsInitialSystemProcessÀÇ PEPROCESS¸¦ Æ®·¹¹ö½ÌÇÏ¿© System ¹®ÀÚ¿­°ú ÀÏÄ¡ÇÏ´Â offsetÀ» ã½À´Ï´Ù. 3. Handle Table Offset ±¸Çϱâ. PEPROCESSÀÇ Handle Table OffsetÀ» ±¸ÇÏ´Â ¹ýÀÔ´Ï´Ù. Handle TableÀ̶õ EPROCESSÀÇ ¾Æ·¡ Çʵ带 ÀǹÌÇÕ´Ï´Ù. lkd> dt !_EPROCESS 8a2407f8 ntdll!_EPROCESS +0x000 Pcb : _KPROCESS +0x06c ProcessLock : _EX_PUSH_LOCK +0x070 CreateTime : _LARGE_INTEGER 0x0 +0x078 ExitTime : _LARGE_INTEGER 0x0 +0x080 RundownProtect : _EX_RUNDOWN_REF +0x084 UniqueProcessId : 0x00000004 +0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x8a10d2e8 - 0x8056a558 ] +0x090 QuotaUsage : [3] 0 +0x09c QuotaPeak : [3] 0 +0x0a8 CommitCharge : 7 +0x0ac PeakVirtualSize : 0x759000 +0x0b0 VirtualSize : 0x1d0000 +0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0x0 - 0x0 ] +0x0bc DebugPort : (null) +0x0c0 ExceptionPort : (null) +0x0c4 ObjectTable : 0xe1001e00 Ptr32 _HANDLE_TABLE ... ÀÌ °ÍÀ» ±¸ÇÏ´Â ¹æ¹ýÀº Å©°Ô µÎ°¡Áö¸¦ »ý°¢Çغ¼ ¼ö ÀÖ½À´Ï´Ù. 1. ´Ù¸¥ Çʵå·ÎºÎÅÍ µ¨Å¸(Delta; ¿ÀÇÁ¼Â Â÷À̰ª)À» °è»êÇÏ¿© ±× °ªÀ» °¡»êÇÔÀ¸·Î½á ¿ÀÇÁ¼ÂÀ» ¾ò´Â ¹æ¹ý. -> ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ·Á¸é ¸¹Àº Å×½ºÆ®°¡ ÀÌ·ç¾îÁ®¾ß Çϸç, ºÒ¾ÈÁ¤Çϱ⠶§¹®¿¡ ¿©±â¼­´Â »ç¿ëÇÏÁö ¾Ê°Ú½À´Ï´Ù. ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ·Á¸é ¸ðµç ¹öÁ¯¿¡¼­ ÇØ´ç Â÷À̰ªÀÌ µ¿ÀÏÇÏ´Ù´Â È®½ÇÇÑ ±Ù°Å°¡ ÀÖ¾î¾ßÇÕ´Ï´Ù. 2. ÇØ´ç ÇʵåÀÇ ±¸Á¶¸¦ ÀÌ¿ëÇÏ´Â ¹æ¹ý. -> _HANDLE_TABLEÀº ¾Æ·¡¿Í °°Àº ±¸Á¶·Î µÇ¾îÀÖ½À´Ï´Ù. lkd> dt !_HANDLE_TABLE 0xe1001e00 ntdll!_HANDLE_TABLE +0x000 TableCode : 0xe1890001 +0x004 QuotaProcess : (null) +0x008 UniqueProcessId : 0x00000004 +0x00c HandleTableLock : [4] _EX_PUSH_LOCK +0x01c HandleTableList : _LIST_ENTRY [ 0xe18640d4 - 0x8056b848 ] +0x024 HandleContentionEvent : _EX_PUSH_LOCK +0x028 DebugInfo : (null) +0x02c ExtraInfoPages : 0 +0x030 FirstFree : 0x570 +0x034 LastFree : 0xc58 +0x038 NextHandleNeedingPool : 0x1000 +0x03c HandleCount : 387 +0x040 Flags : 0 +0x040 StrictFIFO : 0y0 º¸À̽ʴϱî? UniqueProcessId¸¦ 0x08¹øÁö¿¡ °¡Áö°í ÀÖ´Â°É º¼ ¼ö ÀÖ½À´Ï´Ù. À̸¦ ÀÌ¿ëÇÏ¿© ÇÚµé Å×À̺í OffsetÀ» ±¸ÇÒ ¼ö ÀÖ°í, ±× ¿ÀÇÁ¼ÂÀ¸·ÎºÎÅÍÀÇ Delta°ªÀ» ÀÌ¿ëÇÏ¿© ´Ù¸¥ Çʵ嵵 ±¸ÇÒ ¼ö ÀÖÀ»°Ì´Ï´Ù.(¾Æ±îµµ ´çºÎÇßÁö¸¸, Delta°ªÀ» ÀÌ¿ëÇÑ ¹æ¹ýÀº ¿©·¯ OS¿¡¼­ Å×½ºÆ®¸¦ ÇØºÁ¾ßÇÕ´Ï´Ù.) À̸¦ ÀÌ¿ëÇÑ C ÄÚµå´Â ¾Æ·¡¿Í °°½À´Ï´Ù. VOID CalcHandleTableOffset(VOID) { PEPROCESS Proc = IoGetCurrentProcess(); HANDLE PID = PsGetCurrentProcessId(); PVOID GuessHandleTable = NULL; int i = 0; for(i = 0; i < PAGE_SIZE; i+=4) { GuessHandleTable = *(PVOID *)((PCHAR)Proc + i); if(MmIsAddressValid(GuessHandleTable)) { if(*(PHANDLE)((PCHAR)GuessHandleTable + 0x08) == PID) { HANDLE_TABLE_OFFSET = i; return; } } } } 4. ActiveProcessLinks UniqueProcessId Offset + 4¸¦ Çϸé ActiveProcessLinks Offset(LIST_ENTRY)°¡ ³ª¿É´Ï´Ù. ÀÌ´Â NT °è¿­¿¡¼­´Â ¸ðµÎ µ¿ÀÏ(NT4~Vista¿¡¼­ ÇÊÀÚ°¡ È®ÀÎ)Çϱ⠶§¹®¿¡, »ç¿ëÇØµµ µË´Ï´Ù. ActiveProcessLinks_Offset = PID_OFFSET + 4; 5. DebugPort ÁÖ·Î ÇÁ·Î¼¼½º°¡ µð¹ö±ëÁßÀÎÁö Ä¿³Î´Ü¿¡¼­ °­·ÂÇÏ°Ô È®ÀÎÇÒ ¶§ »ç¿ëµÇ¾îÁý´Ï´Ù. µð¹ö°Å°¡ Ȱ¼ºÈ­ µÇ¾îÀÖ´Ù¸é ÀÌ °ªÀº NULLÀÌ ¾Æ´Ñ °ªÀÌ µÇ¹Ç·Î üũÇÒ ¶§ »ç¿ëµË´Ï´Ù. ¿ÀÇÁ¼ÂÀº ÇÚµé Å×À̺íÀÇ ¿ÀÇÁ¼Â - 0x08À¸·Î ¾Æ·¡¿Í °°ÀÌ ¾µ ¼ö ÀÖ½À´Ï´Ù. DEBUG_PORT_OFFSET = HANDLE_TABLE_OFFSET - 0x08; ********************************************************************** ÀÌ ºÎºÐÀº ³í¿ÜÀÌÁö¸¸, ½É½ÉÇϹǷÎ(?) ³»°¡ ¿øÇÏ´Â ProcessÀÇ PEPROCESS¸¦ ¾ò¾î¿À´Â ¹æ¹ý¿¡ ´ëÇØ¼­ °£´ÜÇÏ°Ô »ý°¢Çغ¾½Ã´Ù. ¿ì¼± Native API¸¦ ÀÌ¿ëÇÏ´Â ¹æ¹ýÀ¸·Î PsLookupProcessByProcessId()¸¦ ÀÌ¿ëÇØº¼ ¼ö ÀÖ½À´Ï´Ù. ÀÌ ÇÔ¼ö´Â PspCidTable¿¡¼­ Process¸¦ ã¾Æ³»¾î ¹ÝȯÇÏ´Â ¿ªÇÒÀ» ÇÕ´Ï´Ù. µû¶ó¼­ °¡Àå Àú ¼öÁØÀÇ ¿ªÇÒÀ» ÇÏ´Â Native API·Î À̸¦ ÈÄÅ·Çϸé ÇÁ·Î¼¼½º Á¢±ÙÀ» °­·ÂÇÏ°Ô ¸·À»¼öµµ ÀÖÀ»°ÍÀÔ´Ï´Ù. ¶ÇÇÑ ±âÁ¸ ÇÚµé·ÎºÎÅÍ ¾òÀ»¼öµµ ÀÖÀ»°Ì´Ï´Ù. ÀÌ´Â NtDuplicateObject¿Í NtQuerySystemInformationÀ» ÀÌ¿ëÇÏ¸é µË´Ï´Ù. ±× ÈÄ, ObReferenceObjectByHandleÀ» ÇÏ¸é ¾òÀ» ¼ö ÀÖÀ»°Ì´Ï´Ù. (À©µµ¿ì¿¡¼­´Â CSRSS.exe°¡ ¸ðµç ÇÁ·Î¼¼½º¿¡ ´ëÇÑ ÇÚµéÀ» Çϳª¾¿ °¡Áö°í ÀÖÀ¸¹Ç·Î À̸¦ ÀÌ¿ëÇϸé NtOpenProcess¸¦ °ÅÄ¡Áö ¾Ê°íµµ ¿­ ¼ö ÀÖ½À´Ï´Ù.) À̹ø¿£ Ä¿³Î ±¸Á¶Ã¼¸¦ ÀÌ¿ëÇÏ´Â ¹æ¹ýµé·Î, ¿ì¼± ActiveProcessLinks¸¦ Traversing ÇÏ´Â ¹æ¹ýÀÌ ÀÖ°Ú½À´Ï´Ù. °¡Àå º¸ÆíÀûÀÎ ¹æ¹ýÀ̸ç, À©µµ¿ì°¡ ÀÌ ¹æ¹ýÀ» »ç¿ëÇϰí ÀÖ½À´Ï´Ù. ¶ÇÇÑ º¸Åë ÇÁ·Î¼¼½º¸¦ ¼û±æ¶§´Â À̸¦ ²÷¾î¼­ ¸ñ·Ï¿¡¼­ ¾Èº¸ÀÌ°Ô ÇÕ´Ï´Ù. ÀÌ °Í ¿Ü¿¡µµ Handle TableÀÇ Link¸¦ ÀÌ¿ëÇϰųª, Á÷Á¢ PspCidTableÀÇ Æ÷ÀÎÅ͸¦ ±¸Çس»¾î(PsLookupProcessByProcessId¸¦ traverse) Á÷Á¢ ã¾Æ³»°Å³ª, ±× Å×À̺íÀ» Á¶ÀÛÇØ¼­ ÇÚµéÀ» ¾ò¾î³½ ÈÄ ObReferenceObjectByHandle()À» ÇÑ´Ù¸é PEPROCESS¸¦ ¾òÀ» ¼ö ÀÖÀ»°Ì´Ï´Ù.