Programming/Win32 API2008. 12. 3. 11:03

#include <stdio.h>
#include <conio.h>
#include <windows.h>

typedef long   NTSTATUS;

typedef enum _SYSTEM_INFORMATION_CLASS {
 SystemInformationClassMin=0,
 SystemBasicInformation=0,
 SystemProcessorInformation=1,
 SystemPerformanceInformation=2,
 SystemTimeOfDayInformation=3,
 SystemPathInformation=4,
 SystemNotImplemented1=4,
 SystemProcessInformation=5,
 SystemProcessesAndThreadsInformation=5,
 SystemCallCountInfoInformation=6,
 SystemCallCounts=6,
 SystemDeviceInformation=7,
 SystemConfigurationInformation=7,
 SystemProcessorPerformanceInformation=8,
 SystemProcessorTimes=8,
 SystemFlagsInformation=9,
 SystemGlobalFlag=9,
 SystemCallTimeInformation=10,
 SystemNotImplemented2=10,
 SystemModuleInformation=11,
 SystemLocksInformation=12,
 SystemLockInformation=12,
 SystemStackTraceInformation=13,
 SystemNotImplemented3=13,
 SystemPagedPoolInformation=14,
 SystemNotImplemented4=14,
 SystemNonPagedPoolInformation=15,
 SystemNotImplemented5=15,
 SystemHandleInformation=16,
 SystemObjectInformation=17,
 SystemPageFileInformation=18,
 SystemPagefileInformation=18,
 SystemVdmInstemulInformation=19,
 SystemInstructionEmulationCounts=19,
 SystemVdmBopInformation=20,
 SystemInvalidInfoClass1=20,
 SystemFileCacheInformation=21,
 SystemCacheInformation=21,
 SystemPoolTagInformation=22,
 SystemInterruptInformation=23,
 SystemProcessorStatistics=23,
 SystemDpcBehaviourInformation=24,
 SystemDpcInformation=24,
 SystemFullMemoryInformation=25,
 SystemNotImplemented6=25,
 SystemLoadImage=26,
 SystemUnloadImage=27,
 SystemTimeAdjustmentInformation=28,
 SystemTimeAdjustment=28,
 SystemSummaryMemoryInformation=29,
 SystemNotImplemented7=29,
 SystemNextEventIdInformation=30,
 SystemNotImplemented8=30,
 SystemEventIdsInformation=31,
 SystemNotImplemented9=31,
 SystemCrashDumpInformation=32,
 SystemExceptionInformation=33,
 SystemCrashDumpStateInformation=34,
 SystemKernelDebuggerInformation=35,
 SystemContextSwitchInformation=36,
 SystemRegistryQuotaInformation=37,
 SystemLoadAndCallImage=38,
 SystemPrioritySeparation=39,
 SystemPlugPlayBusInformation=40,
 SystemNotImplemented10=40,
 SystemDockInformation=41,
 SystemNotImplemented11=41,
 /* SystemPowerInformation=42, Conflicts with POWER_INFORMATION_LEVEL 1 */
 SystemInvalidInfoClass2=42,
 SystemProcessorSpeedInformation=43,
 SystemInvalidInfoClass3=43,
 SystemCurrentTimeZoneInformation=44,
 SystemTimeZoneInformation=44,
 SystemLookasideInformation=45,
 SystemSetTimeSlipEvent=46,
 SystemCreateSession=47,
 SystemDeleteSession=48,
 SystemInvalidInfoClass4=49,
 SystemRangeStartInformation=50,
 SystemVerifierInformation=51,
 SystemAddVerifier=52,
 SystemSessionProcessesInformation=53,
 SystemInformationClassMax
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_HANDLE_INFORMATION {
 ULONG ProcessId;
 UCHAR ObjectTypeNumber;
 UCHAR Flags;
 USHORT Handle;
 PVOID Object;
 ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _SYSTEM_ALL_HANDLES_INFORMATION {
 ULONG NumberOfHandles;
 SYSTEM_HANDLE_INFORMATION *SystemHandleInformation;
} SYSTEM_ALL_HANDLES_INFORMATION;

typedef NTSTATUS (NTAPI *NTQUERYSYSTEMINFORMATION)(
 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
 IN OUT PVOID SystemInformation,
 IN ULONG SystemInformationLength,
 OUT PULONG ReturnLength OPTIONAL);

typedef enum _DEBUG_CONTROL_CODE {
 DebugGetTraceInformation=1,
 DebugSetInternalBreakpoint,
 DebugSetSpecialCall,
 DebugClearSpecialCalls,
 DebugQuerySpecialCalls,
 DebugDbgBreakPoint,
 DebugMaximum,
 DebugReadVirtualMemory,
 DebugWriteVirtualMemory
} DEBUG_CONTROL_CODE;

typedef NTSTATUS (NTAPI *NTSYSTEMDEBUGCONTROL)(
 IN DEBUG_CONTROL_CODE ControlCode,
 IN PVOID InputBuffer OPTIONAL,
 IN ULONG InputBufferLength,
 OUT PVOID OutputBuffer OPTIONAL,
 IN ULONG OutputBufferLength,
 OUT PULONG ReturnLength OPTIONAL);

typedef struct _MEMORY_CHUNKS {
 PVOID VirtualAddress;
 PVOID Buffer;
 ULONG BufferSize;
} MEMORY_CHUNKS, *PMEMORY_CHUNKS;

typedef LONG NTSTATUS; 
typedef LONG KPRIORITY; 
typedef ULONG_PTR KAFFINITY; 

typedef enum _PROCESS_INFORMATION_CLASS { 
 ProcessBasicInformation,         // 0 Y N 
 ProcessQuotaLimits,              // 1 Y Y 
 ProcessIoCounters,               // 2 Y N 
 ProcessVmCounters,               // 3 Y N 
 ProcessTimes,                    // 4 Y N 
 ProcessBasePriority,             // 5 N Y 
 ProcessRaisePriority,            // 6 N Y 
 ProcessDebugPort,                // 7 Y Y 
 ProcessExceptionPort,            // 8 N Y 
 ProcessAccessToken,              // 9 N Y 
 ProcessLdtInformation,           // 10 Y Y 
 ProcessLdtSize,                  // 11 N Y 
 ProcessDefaultHardErrorMode,     // 12 Y Y 
 ProcessIoPortHandlers,           // 13 N Y 
 ProcessPooledUsageAndLimits,     // 14 Y N 
 ProcessWorkingSetWatch,          // 15 Y Y 
 ProcessUserModeIOPL,             // 16 N Y 
 ProcessEnableAlignmentFaultFixup,// 17 N Y 
 ProcessPriorityClass,            // 18 N Y 
 ProcessWx86Information,          // 19 Y N 
 ProcessHandleCount,              // 20 Y N 
 ProcessAffinityMask,             // 21 N Y 
 ProcessPriorityBoost,            // 22 Y Y 
 ProcessDeviceMap,                // 23 Y Y 
 ProcessSessionInformation,       // 24 Y Y 
 ProcessForegroundInformation,    // 25 N Y 
 ProcessWow64Information          // 26 Y N 
} PROCESS_INFORMATION_CLASS;

typedef struct _UNICODE_STRING {
 USHORT Length;
 USHORT MaximumLength;
 PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
 BYTE Reserved1[56];
 UNICODE_STRING ImagePathName;
 UNICODE_STRING CommandLine;
 BYTE Reserved2[92];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB_LDR_DATA {
 BYTE Reserved1[20];
 LIST_ENTRY InMemoryOrderModuleList;
 BYTE Reserved2[8];
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _PEB {
 BYTE Reserved1[2];
 BYTE BeingDebugged;
 BYTE Reserved2[9];
 PPEB_LDR_DATA LoaderData;
 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
 BYTE Reserved3[448];
 ULONG SessionId;
} PEB, *PPEB;

typedef struct _PROCESS_BASIC_INFORMATION {
 NTSTATUS ExitStatus;
 PPEB PebBaseAddress;
 KAFFINITY AffinityMask;
 KPRIORITY BasePriority;
 ULONG UniqueProcessId;
 ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

typedef NTSTATUS (NTAPI *NTQUERYINFORMATIONPROCESS)(
 IN HANDLE ProcessHandle,
 IN PROCESS_INFORMATION_CLASS ProcessInformationClass,
 OUT PVOID ProcessInformation,
 IN ULONG ProcessInformationLength,
 OUT PULONG ReturnLength);

typedef PVOID  PEPROCESS;

NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
NTSYSTEMDEBUGCONTROL NtSystemDebugControl;
NTQUERYINFORMATIONPROCESS NtQueryInformationProcess;
ULONG PidOffset;
ULONG PLinkOffset;

NTSTATUS KdReadVirtualMemory(PVOID VirtualAddress, PVOID Buffer, ULONG BufferSize)
{
 MEMORY_CHUNKS MemoryChunks;
 MemoryChunks.VirtualAddress=VirtualAddress;
 MemoryChunks.Buffer=Buffer;
 MemoryChunks.BufferSize=BufferSize;
 return NtSystemDebugControl(DebugReadVirtualMemory, &MemoryChunks, sizeof(MemoryChunks),
  NULL, 0, NULL);
}

NTSTATUS KdWriteVirtualMemory(PVOID VirtualAddress, PVOID Buffer, ULONG BufferSize)
{
 MEMORY_CHUNKS MemoryChunks;
 MemoryChunks.VirtualAddress=VirtualAddress;
 MemoryChunks.Buffer=Buffer;
 MemoryChunks.BufferSize=BufferSize;
 return NtSystemDebugControl(DebugWriteVirtualMemory, &MemoryChunks, sizeof(MemoryChunks),
  NULL, 0, NULL);
}

ULONG KdGetProcessId(HANDLE ProcessHandle)
{
 PROCESS_BASIC_INFORMATION ProcessInformation;
 if(NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation,
  &ProcessInformation, sizeof(PROCESS_BASIC_INFORMATION), NULL)>=0)
 {
  return (ULONG)ProcessInformation.UniqueProcessId;
 }
 return 0;
}

ULONG GetProcessIdOffset(PEPROCESS Process, HANDLE ProcessHandle)
{
 ULONG *Buffer=(PULONG)malloc(4096), ProcessId, Offset;
 memset(Buffer, 0, 4096);
 KdReadVirtualMemory(Process, Buffer, 4096);
 ProcessId=KdGetProcessId(ProcessHandle);
 if(!ProcessId)
 {
  free(Buffer);
  return 0;
 }
 for(Offset=0;Offset<4096;Offset++)
 {
  if(*(PULONG)((PCHAR)Buffer+Offset)==ProcessId)
  {
   free(Buffer);
   return Offset;
  }
 }
 free(Buffer);
 return 0;
}

ULONG GetProcessIdOffsetEx()
{
 ULONG NumberOfHandles, HandleIndex;
 ULONG *SystemInformation=(ULONG *)malloc(sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG));
 //미리 핸들을 하나 열어둔다.
 OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
    if(NtQuerySystemInformation(SystemHandleInformation, SystemInformation, sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG), 0)<0)
 {
  NumberOfHandles=*SystemInformation;
  free(SystemInformation);
  SystemInformation=(PULONG)malloc(NumberOfHandles*sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG));
 }
 NtQuerySystemInformation(SystemHandleInformation, SystemInformation, NumberOfHandles*sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG), 0);
 NumberOfHandles=*SystemInformation;
 printf("Number Of Handles : %d\n", NumberOfHandles);
 
 PSYSTEM_HANDLE_INFORMATION SystemHandleList=(PSYSTEM_HANDLE_INFORMATION)(SystemInformation+1);
 for(HandleIndex=0;HandleIndex<NumberOfHandles;HandleIndex++)
 {
  if(SystemHandleList[HandleIndex].ObjectTypeNumber==5 &&
   SystemHandleList[HandleIndex].ProcessId==GetCurrentProcessId())
  {
   ULONG Offset=GetProcessIdOffset(
    SystemHandleList[HandleIndex].Object,
    (HANDLE)SystemHandleList[HandleIndex].Handle);
   CloseHandle((HANDLE)SystemHandleList[HandleIndex].Handle);
   free(SystemInformation);
   return Offset;
  }
 }
 free(SystemInformation);
 return 0;
}

BOOL SetProcessId(ULONG ProcessId, ULONG NewProcessId)
{
 ULONG NumberOfHandles, HandleIndex;
  HANDLE ProcessHandle;
 ULONG *SystemInformation;
 //핸들을 미리 열어 둔다.
 ProcessHandle=OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
 if(!ProcessHandle)
 {
  return FALSE;
 }
 SystemInformation=(ULONG *)malloc(sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG));
 if(NtQuerySystemInformation(SystemHandleInformation, SystemInformation, sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG), 0)<0)
 {
  NumberOfHandles=*SystemInformation;
  free(SystemInformation);
  SystemInformation=(PULONG)malloc(NumberOfHandles*sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG));
 }
 NtQuerySystemInformation(SystemHandleInformation, SystemInformation, NumberOfHandles*sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG), 0);
 NumberOfHandles=*SystemInformation;
 
 PSYSTEM_HANDLE_INFORMATION SystemHandleList=(PSYSTEM_HANDLE_INFORMATION)(SystemInformation+1);
 printf("PID\tHANDLE\tObject\t\tFlags\tAccess\tObjectType\n");
 printf("-----------------------------------------------------------\n");
 for(HandleIndex=0;HandleIndex<NumberOfHandles;HandleIndex++)
 {
  //ObjectTypeNumber=5이면 프로세스, 6이면 스레드
  if(SystemHandleList[HandleIndex].ObjectTypeNumber==5 &&
   SystemHandleList[HandleIndex].ProcessId==GetCurrentProcessId() &&
   (HANDLE)SystemHandleList[HandleIndex].Handle==ProcessHandle)
  {
   //EPROCESS의 주소는 Object에 있다.
   //EPROCESS::UniqueProcessId에 NewProcessId의 값으로 채운다.
   KdWriteVirtualMemory(
    (PCHAR)SystemHandleList[HandleIndex].Object+PidOffset,
    &NewProcessId,
    4);
   printf("%d\t%x\t%x\t%x\t%x\t%x\n",
    SystemHandleList[HandleIndex].ProcessId,
    SystemHandleList[HandleIndex].Handle,
    SystemHandleList[HandleIndex].Object,
    SystemHandleList[HandleIndex].Flags,
    SystemHandleList[HandleIndex].GrantedAccess,
    SystemHandleList[HandleIndex].ObjectTypeNumber);
   CloseHandle((HANDLE)SystemHandleList[HandleIndex].Handle);
   free(SystemInformation);
   return TRUE;
  }
 }
 free(SystemInformation);
}

BOOL SetDebugPrivilege()
{
 HANDLE TokenHandle;
 LUID Luid;
 TOKEN_PRIVILEGES TokenPrivileges;
 if(!OpenProcessToken((HANDLE)0xFFFFFFFF, TOKEN_ALL_ACCESS, &TokenHandle))
 {
  return FALSE;
 }
// LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid);
 Luid.LowPart=20;
 Luid.HighPart=0;
 TokenPrivileges.PrivilegeCount=1;
 TokenPrivileges.Privileges->Attributes=SE_PRIVILEGE_ENABLED;
 TokenPrivileges.Privileges->Luid=Luid;
 if(!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES),
  NULL, NULL))
 {
  CloseHandle(TokenHandle);
  return FALSE;
 }
 CloseHandle(TokenHandle);
 return TRUE;
}

void main()
{
 ULONG ProcessId, NewProcessId;
 NtQuerySystemInformation=(NTQUERYSYSTEMINFORMATION)
  GetProcAddress(LoadLibrary("ntdll.dll"), "NtQuerySystemInformation");
 NtSystemDebugControl=(NTSYSTEMDEBUGCONTROL)
  GetProcAddress(LoadLibrary("ntdll.dll"), "NtSystemDebugControl");
 NtQueryInformationProcess=(NTQUERYINFORMATIONPROCESS)
  GetProcAddress(LoadLibrary("ntdll.dll"), "NtQueryInformationProcess");
 SetDebugPrivilege();
 PidOffset=GetProcessIdOffsetEx();
 PLinkOffset=PidOffset+0x04;
 printf("변경할 프로세스 아이디 입력\n");
 scanf("%d", &ProcessId);
 printf("새로운 프로세스 아이디 입력\n");
 scanf("%d", &NewProcessId);
 SetProcessId(ProcessId, NewProcessId);
 FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
 printf("원래대로 하려면 아무키나 누르시오\n");
 getch();
 SetProcessId(ProcessId, ProcessId);
}

Posted by skensita