GPK是一款盛大全新推出的游戏保护工具,它可以有效地保护游戏不受外挂侵犯。GPK从设计之初就已针对各类外挂做了充分的准备,从GPK构架上就已经杜绝了脱机外挂存在的可能,与此同时,GPK拥有数十种先进、成熟的技术手段打击各类外挂。
http://baike.baidu.com/view/2025396.htm
额用tx 看了下
[*]len(6) Ke386IoSetAccessProcess[ntkrnlpa.exe] [0x804F9486]->[0xA0265168][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 68 51 26 A0 C3 8B FF 55 8B EC 33
[*]len(6) KeAttachProcess[ntkrnlpa.exe] [0x804F9B32]->[0xA02683EA][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 EA 83 26 A0 C3 8B FF 55 8B EC 56
[*]len(6) KeInitializeApc[ntkrnlpa.exe] [0x804FD39E]->[0xA0268A62][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 62 8A 26 A0 C3 8B FF 55 8B EC 8B
[*]len(6) KeStackAttachProcess[ntkrnlpa.exe] [0x804F9C32]->[0xA02686BA][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 BA 86 26 A0 C3 8B FF 55 8B EC 56
[*]len(4) NtDuplicateObject[ntkrnlpa.exe] [0x805BF037]->[0x9C191E62][E:\软件\mafhekzy.sys] Inline 27 2E BD 1B 73 D4 FF FF
[*]len(6) ObCheckObjectAccess[ntkrnlpa.exe] [0x805C1174]->[0xA0267BA0][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 A0 7B 26 A0 C3 8B FF 55 8B EC 83
len(6) ZwOpenSection[ntkrnlpa.exe] [0x80501700]->[0xA026810C][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 0C 81 26 A0 C3 B8 7D 00 00 00 8D
[*]len(6) NtCreateThread[ntkrnlpa.exe] [0x805D2002]->[0xA0264662][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 62 46 26 A0 C3 6A 28 68 D8 B8 4D
[*]len(6) NtProtectVirtualMemory[ntkrnlpa.exe] [0x805B93F6]->[0xA0264D16][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 16 4D 26 A0 C3 6A 44 68 98 B0 4D
len(6) NtQueueApcThread[ntkrnlpa.exe] [0x805D2260]->[0xA0265032][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 32 50 26 A0 C3 8B FF 55 8B EC 51
[*]len(6) NtTerminateProcess[ntkrnlpa.exe] [0x805D39B2]->[0xA026952A][E:\游戏\龙之谷\GPK\1394hub.sys] Inline 68 2A 95 26 A0 C3 8B FF 55 8B EC 83
[*]len(6) NtWriteVirtualMemory[ntkrnlpa.exe] [0x805B53A4]->[0xA026974E][E:\游戏\龙之谷\GPK\1394hub.sys]
ssdt /shadow hook也勾住了几个
进程无法打开。。。
常规注入的话必须要有句柄才行
但是。。。我这个方法比较另类 在加载驱动前注入就可以了
创建进程流程
;进程创建过程开始 CreateProcessA
call kernel32!CreateProcessA
;10个参数
; BOOL WINAPI CreateProcess(
; __in_opt LPCTSTR lpApplicationName,
; __inout_opt LPTSTR lpCommandLine,
; __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
; __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
; __in BOOL bInheritHandles,
; __in DWORD dwCreationFlags, NORMAL_PRIORITY_CLASS
; __in_opt LPVOID lpEnvironment,
; __in_opt LPCTSTR lpCurrentDirectory,
; __in LPSTARTUPINFO lpStartupInfo,
; __out LPPROCESS_INFORMATION lpProcessInformation
; );
; 直接调用kernel32!CreateProcessInternalA
call kernel32!CreateProcessInternalA
; 12个参数,第一个与最后一个为零,中间10个延接了上面传入的10个参数
; 主要任务是将ANSI字符转换成Unicode字符,很多代码用于了转换与检查,所以,直接用Unicode编程将大大增加执行效率
call kernel32!CreateProcessInternalW
; 12个参数
; 基本延续上面的
; 第6个参数 and 0F7FFFFFFh
以下为kernel32!CreateProcessInternalW中的流程:
call ntdll!ZwQueryInformationJobObject
; ZwQueryInformationJobObjectretrieves information about a job object.
; NTSYSAPI
; NTSTATUS
; NTAPI
; ZwQueryInformationJobObject(
; IN HANDLE JobHandle, == 0
; IN JOBOBJECTINFOCLASS JobInformationClass, == 4
; OUT PVOID JobInformation, == Address
; IN ULONG JobInformationLength, == 4
; OUT PULONG ReturnLengthOPTIONAL == 0
; );
; 判断返回值是否为C0000022h (拒绝访问)
call kernel32!SearchPathW
; 进行路径搜索
call kernel32!GetFileAttributesW
; 获取文件属性
call kernel32!BasepIsSetupInvokedByWinLogon
; 判断是否WinLogon进程
call ntdll!RtlDosPathNameToNtPathName_U
call ntdll!RtlDetermineDosPathNameType_U
; 路径转换
call ntdll!NtOpenFile
; 打开文件
call ntdll!NtCreateSection
; NtCreateSection(
; OUT PHANDLE SectionHandle,
; IN ACCESS_MASK DesiredAccess,
; IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
; IN PLARGE_INTEGER MaximumSize OPTIONAL,
; IN ULONG Protect,
; IN ULONG Attributes,
; IN HANDLE FileHandle OPTIONAL
; );
; 创建Section CreateFileMapping是对NtCreateSection的封装,所以在这一步,程序被映射进了内存
call kernel32!BasepIsProcessAllowed
; 就一个参数为Unicode进程名字
; 其内部调用了RtlEnterCriticalSection进入临界区
; 再调用NtOpenKey打开:
; "\Registry\MACHINE\System\CurrentControlSet\Control\Session Manager\AppCertDlls"
; 解释:
; AppCertDlls details.
; Create in the "\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls"
;
; The Key with name "AppSecDll" type REG_EXPAND_SZ, and put there, something like that "%SystemRoot%\system32\.Dll" ... In fact, they may be there a lot, so keep this in mind.
;
; This yours DLL must have mandatory entry point with name CreateProcessNotify, and prototype as specified below.
; 结束
; 最后调用RtlLeaveCriticalSection
call kernel32!BasepCheckBadapp
; 对进程行行兼容性检查
; 1. IsShimInfrastructureDisabled
; 2. RtlAllocateHeap NTDLL
; 3. __imp__memmove
; 4. BaseCheckAppcompatCache KERNEL32
; 1. __SEH_prolog
; 2. BasepShimCacheCheckBypass KERNEL32
; 3. BasepShimCacheLock KERNEL32
; 4. BasepShimCacheLookup KERNEL32
; 5. BasepShimCacheUnlock KERNEL32
; 6. __SEH_epilog
; 5. RtlFreeHeap NTDLL
; 其中会加载:
; call kernel32!LdrLoadDllC:\WINDOWS\system32\Apphelp.dll
; 调用其中的“ApphelpCheckRunApp”
call kernel32!BasepCheckWinSaferRestrictions
; 1. RtlEnterCriticalSection NTDLL
; 2. NtOpenThreadToken
; NtOpenThreadToken ( IN HANDLE ThreadHandle, == 0FFFFFFFEh(-2 当前线程)
; IN ACCESS_MASK DesiredAccess, == 2000000h
; IN BOOLEAN OpenAsSelf, == 1
; OUT PHANDLE TokenHandle
; )
; 判断返值是否等于0C000007Ch(试图引用不存在的令牌)否跳走(跳走后的没跟,估计是跳向了NtSetInformationThread)
; 是则继续向下Call
; 3. NtOpenProcessToken
; NtOpenProcessTokenEx ( IN HANDLE ProcessHandle, == -1 当前进程
; IN ACCESS_MASK DesiredAccess, == 0ah
; IN ULONG HandleAttributes,
; OUT PHANDLE TokenHandle
; )
; 判断返回值是否为0C0000022h(拒绝访问),
; 是跳走,否继续
; 4. NtQueryInformationToken
; NtQueryInformationToken ( IN HANDLE TokenHandle, == 上面得到的句柄
; IN TOKEN_INFORMATION_CLASS TokenInformationClass, == 1
; OUT PVOID TokenInformation,
; IN ULONG TokenInformationLength,
; OUT PULONG ReturnLength
; )
; 5. RtlInitializeSid
; RtlInitializeSid( IN PSID Sid,
; IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
; IN UCHAR SubAuthorityCount );
; 6. RtlSubAuthoritySid
; 7. RtlEqualSid
; 8. NtOpenKey "\Registry\MACHINE\System\CurrentControlSet\Control\SafeBoot\Option"
; 打开失败,继续打开下面的:
; "\Registry\Machine\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers"
; 打开成功:
; Call NtQueryValueKey 取"TransparentEnabled"项的值
; 判断得到的值是否为零,不为零为设某变量为1
; Call NtQueryValueKey 取"AuthenticodeEnabled"项的值
; 判断得到的值是否为零,不为零则跳转,我这里是零
; 9. NtClose
; 10. call kernel32!LdrLoadDll "ADVAPI32.DLL" ; 装入DLL
; 11. call kernel32!LdrGetProcedureAddress ;获取下列API地址
; "SaferIdentifyLevel"
; "SaferComputeTokenFromLevel"
; "SaferCloseLevel"
; "SaferRecordEventLogEntry"
; 12. NtClose
; 13. call kernel32!__security_check_cookie
call ntdll!ZwQuerySection
; ZwQuerySection ( IN HANDLE SectionHandle, == Section句柄
; IN SECTION_INFORMATION_CLASS SectionInformationClass, == 1
; OUT PVOID SectionInformation,
; IN SIZE_T Length,
; OUT PSIZE_T ResultLength
; )
call kernel32!LdrQueryImageFileExecutionOptions
; 获取调试信息,映像劫持~
; LdrQueryImageFileExecutionOptions ( IN PUNICODE_STRING SubKey, == "\??\E:\AAAAA.exe"进程名
; IN PCWSTR ValueName, == "Debugger"
; IN ULONG Type, == 1
; OUT PVOID Buffer,
; IN ULONG BufferSize,
; OUT PULONG ReturnedLength OPTIONAL
; )
call kernel32!BasepIsImageVersionOk
call kernel32!LoadLibraryA "advapi32.dll"
call kernel32!GetProcAddress "CreateProcessAsUserSecure"
call ntdll!ZwQuerySystemInformation
; ZwQuerySystemInformation(
; IN SYSTEM_INFORMATION_CLASSSystemInformationClass, == 47H == "SystemCreateSession"
; INOUT PVOIDSystemInformation,
; IN ULONGSystemInformationLength,
; OUT PULONGReturnLength OPTIONAL
; );
call kernel32!FreeLibrary "advapi32.dll"
call kernel32!BaseFormatObjectAttributes
call ntdll!ZwCreateProcessEx
mov eax,30h
call ntdll!KiFastSystemCall
call ntdll!ZwSetInformationProcess
; NtSetInformationProcess ( IN HANDLE ProcessHandle, == ZwCreateProcessEx时得到的进程句柄
; IN PROCESSINFOCLASS ProcessInformationClass, == 12h == ProcessDefaultHardErrorMode
; IN PVOID ProcessInformation, == 2 == SEM_NOGPFAULTERRORBOX
; IN ULONG ProcessInformationLength == 2
; )
call kernel32!BasepSxsCreateProcessCsrMessage
; 1. BasepSxsGetProcessImageBaseAddress KERNEL32
; 2. RtlMultiAppendUnicodeStringBuffer NTDLL
; 3. BasepSxsCreateStreams KERNEL32
; 4. BasepSxsIsStatusFileNotFoundEtc
; 5. BasepSxsIsStatusResourceNotFound
call ntdll!NtQueryInformationProcess
; ZwQueryInformationProcess(
; IN HANDLE ProcessHandle, == 进程句柄
; IN PROCESSINFOCLASS ProcessInformationClass, == 0 == ProcessBasicInformation
; OUT PVOID ProcessInformation,
; IN ULONG ProcessInformationLength,
; OUT PULONG ReturnLength OPTIONAL
; );
call kernel32!BasePushProcessParameters
; 1. __SEH_prolog
; 2. GetFullPathNameW KERNEL32
; 3. BaseComputeProcessDllPath KERNEL32
; 4. RtlInitUnicodeString
; 5. RtlCreateProcessParameters NTDLL
; 6. NtAllocateVirtualMemory
; 7. NtWriteVirtualMemory
; 8. __security_check_cookie
; 9. __SEH_epilog
call kernel32!BaseCreateStack
; 1. RtlImageNtHeader NTDLL
; 2. NtAllocateVirtualMemory
; 3. NtProtectVirtualMemory
call kernel32!BaseInitializeContext
; BaseInitializeContext(PCONTEXT Context, // 0x200 bytes
; PPEB Peb,
; PVOID EntryPoint,
; DWORD StackTop,
; int Type // union (Process, Thread, Fiber)
; );
call kernel32!BaseFormatObjectAttributes
call ntdll!ZwCreateThread
mov eax,35h
call ntdll!KiFastSystemCall
call kernel32!GetModuleHandleA "NULL"
eax == 0400000h ;程序装入地址
call ntdll!RtlImageNtHeader eax
; 验证NTHeader
; 下面是通知Cress.exe的几个函数
call ntdll!CsrCaptureMessageMultiUnicodeStringsInPlace
call ntdll!CsrClientCallServer
call ntdll!CsrFreeCaptureBuffer
;--------------
call ntdll!ZwResumeThread ;启动线程移交控制权并返回
ret
;;进程创建过程结束 CreateProcessA
最后要执行ZwResumeThread 函数恢复线程
如果我们把这个函数hook了进行判断就可以在进程创建完成前进行注入
以上是原理 为了保险我还用了断链隐藏DLL这样更可以逃避反外挂之类的程序了
效果图
编写语言:Basic
开发工具:Visual Basic 6.0 PowerBasic 9.05
测试平台:win 2000~win 7
主要代码用PB写的