#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);
}