修改目标进程的父进程
2010-02-15 13:10:56| 分类:
Delphi
| 标签:
|举报
|字号大中小 订阅
pjf(jfpan20000@sina.com) http://pjf.blogone.net
windows下的父进程并不是指创建目标的源进程,而是指将被子进程所“继承”的对象,子进程的很多重要域,像QuotaBlock、
DeviceMap、SessionId、Token、process address
space之类都从父进程继承而来。父进程是怎么指定的呢?不论是NtCreateProcess还是NtCreateProcessEx参数中都有一个
ParentProcess的handle指明了父进程是谁,它并不要求父进程是当前进程,虽然CreateProcessW总是这样做。所以说前面有了
“源进程和父进程”之分。
那么具体怎样实现父进程不是当前进程呢?Gary Nebbett在n年前给出了一种代码,修改一下贴出来:
以下内容为程序代码:
#define _WIN32_
#include <stdio.h>
#include <windows.h>
extern "C" {
#define NTAPI __stdcall
typedef struct _PEB *PPEB;
#define PAGE_SIZE 0x1000
typedef LONG NTSTATUS;
#define DECLSPEC_IMPORT __declspec(dllimport)
#define NTSYSAPI DECLSPEC_IMPORT
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _PORT_MESSAGE {
USHORT DataSize;
USHORT MessageSize;
USHORT MessageType;
USHORT VirtualRangesOffset;
CLIENT_ID ClientId;
ULONG MessageId;
ULONG SectionSize;
// UCHAR Data[];
} PORT_MESSAGE, *PPORT_MESSAGE;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
#ifdef MIDL_PASS
[size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
PWSTR Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _PROCESS_PARAMETERS {
ULONG AllocationSize;
ULONG Size;
ULONG Flags;
ULONG Zero;
LONG Console;
ULONG ProcessGroup;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
UNICODE_STRING CurrentDirectoryName;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImageFile;
UNICODE_STRING CommandLine;
PWSTR Environment;
ULONG dwX;
ULONG dwY;
ULONG dwXSize;
ULONG dwYSize;
ULONG dwXCountChars;
ULONG dwYCountChars;
ULONG dwFillAttribute;
ULONG dwFlags;
ULONG wShowWindow;
UNICODE_STRING WindowTitle;
UNICODE_STRING Desktop;
UNICODE_STRING Reserved;
UNICODE_STRING Reserved2;
} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_VALID_ATTRIBUTES 0x000003F2L
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef unsigned long ULONG_PTR, *PULONG_PTR;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
typedef struct _SECTION_IMAGE_INFORMATION { // Information Class 1
PVOID EntryPoint;
ULONG Unknown1;
ULONG StackReserve;
ULONG StackCommit;
ULONG Subsystem;
USHORT MinorSubsystemVersion;
USHORT MajorSubsystemVersion;
ULONG Unknown2;
ULONG Characteristics;
USHORT ImageNumber;
BOOLEAN Executable;
UCHAR Unknown3;
ULONG Unknown4[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
typedef enum _SECTION_INFORMATION_CLASS {
SectionBasicInformation,
SectionImageInformation
} SECTION_INFORMATION_CLASS;
typedef struct _USER_STACK {
PVOID FixedStackBase;
PVOID FixedStackLimit;
PVOID ExpandableStackBase;
PVOID ExpandableStackLimit;
PVOID ExpandableStackBottom;
} USER_STACK, *PUSER_STACK;
typedef LONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
MaxProcessInfoClass
} PROCESSINFOCLASS;
#define InitializeObjectAttributes(p, n, a, r, s){ \
(p)->Length = sizeof(OBJECT_ATTRIBUTES) ; \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#define FILE_OPEN 0x00000001
#define DIRECTORY_QUERY (0x0001)
NTSTATUS
NTAPI
CsrClientCallServer(
IN PVOID Message,
IN PVOID,
IN ULONG Opcode,
IN ULONG Size) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwAllocateVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG AllocationSize,
IN ULONG AllocationType,
IN ULONG Protect) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL) ;
NTSTATUS
NTAPI
RtlCreateProcessParameters(
OUT PPROCESS_PARAMETERS *ProcessParameters,
IN PUNICODE_STRING ImageFile,
IN PUNICODE_STRING DllPath OPTIONAL,
IN PUNICODE_STRING CurrentDirectory OPTIONAL,
IN PUNICODE_STRING CommandLine OPTIONAL,
IN ULONG CreationFlags,
IN PUNICODE_STRING WindowTitle OPTIONAL,
IN PUNICODE_STRING Desktop OPTIONAL,
IN PUNICODE_STRING Reserved OPTIONAL,
IN PUNICODE_STRING Reserved2 OPTIONAL) ;
NTSTATUS
NTAPI
RtlDestroyProcessParameters(
IN PPROCESS_PARAMETERS ProcessParameters) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwDeleteFile(
IN POBJECT_ATTRIBUTES ObjectAttributes) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateSection(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PLARGE_INTEGER SectionSize OPTIONAL,
IN ULONG Protect,
IN ULONG Attributes,
IN HANDLE FileHandle) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
IN HANDLE Handle) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN HANDLE InheritFromProcessHandle,
IN BOOLEAN InheritHandles,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL) ;
#define NtCurrentProcess() ((HANDLE)-1)
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySection(
IN HANDLE SectionHandle,
IN SECTION_INFORMATION_CLASS SectionInformationClass,
OUT PVOID SectionInformation,
IN ULONG SectionInformationLength,
OUT PULONG ResultLength OPTIONAL) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwProtectVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN OUT PULONG ProtectSize,
IN ULONG NewProtect,
OUT PULONG OldProtect) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId,
IN PCONTEXT ThreadContext,
IN PUSER_STACK UserStack,
IN BOOLEAN CreateSuspended) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwResumeThread(
IN HANDLE ThreadHandle,
OUT PULONG PreviousSuspendCount OPTIONAL) ;
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
PUNICODE_STRING DestinationString,
PCWSTR SourceString) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength) ;
}
VOID InformCsrss(HANDLE hProcess, HANDLE hThread, ULONG pid, ULONG tid)
{
struct CSRSS_MESSAGE {
ULONG Unknown1;
ULONG Opcode;
ULONG Status;
ULONG Unknown2;
};
struct {
PORT_MESSAGE PortMessage;
CSRSS_MESSAGE CsrssMessage;
PROCESS_INFORMATION ProcessInformation;
CLIENT_ID Debugger;
ULONG CreationFlags;
ULONG VdmInfo[2];
} csrmsg = {{0}, {0}, {hProcess, hThread, pid, tid}, {0}, 0, {0}};
CsrClientCallServer(&csrmsg, 0, 0x10000, 0x24);
}
PWSTR CopyEnvironment(HANDLE hProcess)
{
PWSTR env = GetEnvironmentStringsW();
ULONG n;
for (n = 0; env[n] != 0; n += wcslen(env + n) + 1) ; n *= sizeof *env;
ULONG m = n;
PVOID p = 0;
ZwAllocateVirtualMemory(hProcess, &p, 0, &m, MEM_COMMIT, PAGE_READWRITE);
ZwWriteVirtualMemory(hProcess, p, env, n, 0);
return PWSTR(p);
}
VOID CreateProcessParameters(HANDLE hProcess, PPEB Peb, PUNICODE_STRING ImageFile)
{
PPROCESS_PARAMETERS pp;
RtlCreateProcessParameters(&pp, ImageFile, 0, 0, 0, 0, 0, 0, 0, 0);
pp->Environment = CopyEnvironment(hProcess);
ULONG n = pp->Size;
PVOID p = 0;
ZwAllocateVirtualMemory(hProcess, &p, 0, &n, MEM_COMMIT, PAGE_READWRITE);
ZwWriteVirtualMemory(hProcess, p, pp, pp->Size, 0);
ZwWriteVirtualMemory(hProcess, PCHAR(Peb) + 0x10, &p, sizeof p, 0);
RtlDestroyProcessParameters(pp);
}
int exec(PUNICODE_STRING name, PWSTR param)
{
PWSTR tmp;
HANDLE hProcess, hThread, hSection, hFile;
OBJECT_ATTRIBUTES oa;
RtlZeroMemory(&oa, sizeof(OBJECT_ATTRIBUTES)) ;
InitializeObjectAttributes( &oa,name, OBJ_CASE_INSENSITIVE, 0, NULL);
IO_STATUS_BLOCK iosb;
ZwOpenFile(&hFile,FILE_READ_DATA|FILE_EXECUTE|SYNCHRONIZE, &oa, &iosb,
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
oa.ObjectName = 0;
ZwCreateSection(&hSection, SECTION_ALL_ACCESS, 0, 0, PAGE_EXECUTE, SEC_IMAGE, hFile);
ZwClose(hFile);
HANDLE hep = OpenProcess(PROCESS_ALL_ACCESS, 0, wcstol(param, &tmp, 10));
ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, 0,
hep, TRUE, hSection, 0, 0);
CloseHandle(hep);
SECTION_IMAGE_INFORMATION sii;
ZwQuerySection(hSection, SectionImageInformation, &sii, sizeof sii, 0);
ZwClose(hSection);
USER_STACK stack = {0};
ULONG n = sii.StackReserve;
ZwAllocateVirtualMemory(hProcess, &stack.ExpandableStackBottom, 0, &n,
MEM_RESERVE, PAGE_READWRITE);
stack.ExpandableStackBase = PCHAR(stack.ExpandableStackBottom) + sii.StackReserve;
stack.ExpandableStackLimit = PCHAR(stack.ExpandableStackBase) - sii.StackCommit;
n = sii.StackCommit + PAGE_SIZE;
PVOID p = PCHAR(stack.ExpandableStackBase) - n;
ZwAllocateVirtualMemory(hProcess, &p, 0, &n, MEM_COMMIT, PAGE_READWRITE);
ULONG x; n = PAGE_SIZE;
ZwProtectVirtualMemory(hProcess, &p, &n, PAGE_READWRITE | PAGE_GUARD, &x);
CONTEXT context = {CONTEXT_FULL};
context.SegGs = 0;
context.SegFs = 0x38;
context.SegEs = 0x20;
context.SegDs = 0x20;
context.SegSs = 0x20;
context.SegCs = 0x18;
context.EFlags = 0x3000;
context.Esp = ULONG(stack.ExpandableStackBase) - 4;
context.Eip = ULONG(sii.EntryPoint);
CLIENT_ID cid;
ZwCreateThread(&hThread, THREAD_ALL_ACCESS, 0, hProcess, &cid, &context, &stack, TRUE);
PROCESS_BASIC_INFORMATION pbi;
ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof pbi, 0);
CreateProcessParameters(hProcess, pbi.PebBaseAddress, name);
InformCsrss(hProcess, hThread, ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread));
ZwResumeThread(hThread, 0);
ZwClose(hProcess);
ZwClose(hThread);
return int(cid.UniqueProcess);
}
extern "C"
int wmain(int argc, wchar_t *argv[])
{
UNICODE_STRING ImageFile;
RtlInitUnicodeString(&ImageFile, argv[1]);
exec(&ImageFile, argv[2]);
return 0;
}
使用:比如编译后为ppp.exe,要用ppp运行c:根目录上qqq.exe,欲设定其父进程为explorer.exe,explorer.exe的pid为***。在控制台输入:
ppp.exe \??\c:\qqq.exe ***
回车后用别的工具看看qqq.exe的父进程,不是ppp而是explorer。因为创建时qqq.exe的EPROCESS中的
InheritedFromUniqueProcessId已被设置为了explorer的pid,而通过ZwQuery***查询就是返回
InheritedFromUniqueProcessId。
并不是所有PE格式应用程序都可以用上面程序加载,按需要修改吧。
有什么用呢,主要是演示,有一些小用,比如说调试别的进程时修改父进程为explorer而不是自己可以防父进程查询的手段(最简单可通过hook来改掉ZwCreateProcess的参数)等等。
评论这张
转发至微博
转发至微博
评论