(果然分析不下去了,這個樣本涉及的內容太廣,我得去補充補充知識再來接着分析了)
最近發現這個模塊比較有趣,還是個x64上的,正好可以練習一下x64的彙編,寫下來有個更好的理解。由於個人能力有限,這個過程可能會持續幾個月,或者更長,不知道能不能弄完。下面通過一些彙編片段來學習它的編程思路及技巧。
僅供參考,如有錯誤歡迎指出。
1,獲取系統信息,函數原型:
ULONG64 GetSystemInformation(ULONG InformationClass,PVOID64 Data);
InformationClass是系統信息的類型,Data指向存儲成功獲得的信息的地址。
解釋:默認Buffer大小爲0x4000,然後調用ZwQuerySystemInformation根據返回的數指決定接下的處理;成功返回系統信息內容。
2, 附加進程
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
USHORT UniqueProcessId;//進程號
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
NTSTATUS
ZwQueryObject(
__in_opt HANDLE Handle,
__in OBJECT_INFORMATION_CLASS ObjectInformationClass,
__out_bcount_opt(ObjectInformationLength) PVOID ObjectInformation,
__in ULONG ObjectInformationLength,
__out_opt PULONG ReturnLength
);
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,//1
ObjectTypeInformation,
ObjectTypesInformation,
ObjectHandleFlagInformation,
ObjectSessionInformation,
ObjectSessionObjectInformation,
MaxObjectInfoClass
} OBJECT_INFORMATION_CLASS;
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION
函數原型:NTSTATUS AttachProcess(PKPROCESS Process,PRKAPC_STATE ApcState);
解釋:首先判斷ProcessId是否合法,如果合法,(最開始的部分這裏)AllocatePool1()--->ApcState,PsLookupProcessByProcessId---->Process,
KeStackAttachProcess(Process,ApcState);如果不合法,GetSystemInformation--->HandleInformation,解析獲得句柄信息,
KeStackAttachProcess,ZwQueryObject---->NameInformation,KeUnstackDetachProcess,比較對象名是否爲"\Windows\ApiPort",
如果相同,保存當前句柄信息中進程號,接着執行最開始的部分;否則繼續解析句柄信息。
2019-08-03
3, NTSTATUS CallDriverEntryInMemory(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath);
解釋:根據DriverObject裏的相關信息,在內存中創建一份新的鏡像,然後找到pe文件入口也就是DriverEntry並調用。如果返回status_success,就把這份新鏡像的"MZ","PE"標示給抹掉並強制返回status_cancelled;如果返回不是status_success ,就把新鏡像給釋放掉並把原錯誤返回。當新驅動的DriverEntry成功執行後,可以看到rootkit作者對一些敏感信息做了處理。這份新的鏡像應該還在內存中運行,而由於CallDriverEntryInMemory返回status_cancelled給最開始的DriverEntry,導致驅動異常退出。
2019-08-04
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY64
{ PVOID64 Section;
PVOID64 MappedBase;
PVOID64 ImageBase;//0X10
ULONG ImageSize;//0X18
ULONG Flag;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[0x100];//0X28
}SYSTEM_MODULE_INFORMATION_ENTRY64,
2019-08-08
4,獲取進程的文件鏡像名稱
BOOLEAN GetProcessImageNameByProcessId(ULONG ProcessId,WCHAR* buffer,ULONG BufferLength);
解釋:第一步會起一個線程計算出ImageFileName在_EPROCESS結構中的偏移,第二步根據ProcessId獲取其EPROCESS然後將ImageFileName拷貝。
VOID GetImageFileNameOffsetInEPROCESS(PVOID StartContext)
一般情況下驅動運行的當前進程是system進程,通過內存中數據比對來確認ImageFileName的偏移。
2019-08-09
5,(進程間)內存讀寫
NTSTATUS ReadWriteMemory(HANDLE ProcessHandle,PVOID64 Address,PVOID64 buffer,
ULONG64 LenthToReadWrite,ULONG64 LengthReadWritten,BOOLEAN ReadOrWrite);
.text:0000000000030A54 ; =============== S U B R O U T I N E =======================================
.text:0000000000030A54
.text:0000000000030A54
.text:0000000000030A54 ReadWriteMemory proc near ; CODE XREF: ReadMemory+16p
.text:0000000000030A54 ; WriteMemory+16p
.text:0000000000030A54 ; DATA XREF: ...
.text:0000000000030A54
.text:0000000000030A54 Object = qword ptr -98h
.text:0000000000030A54 HandleInformation= qword ptr -90h
.text:0000000000030A54 var_88 = dword ptr -88h
.text:0000000000030A54 var_84 = dword ptr -84h
.text:0000000000030A54 var_80 = qword ptr -80h
.text:0000000000030A54 var_78 = qword ptr -78h
.text:0000000000030A54 var_70 = qword ptr -70h
.text:0000000000030A54 var_68 = byte ptr -68h
.text:0000000000030A54 arg_18 = dword ptr 20h
.text:0000000000030A54 arg_20 = qword ptr 28h
.text:0000000000030A54 arg_28 = dword ptr 30h
.text:0000000000030A54
.text:0000000000030A54 push rsi
.text:0000000000030A56 push rdi
.text:0000000000030A57 push r12
.text:0000000000030A59 push r13
.text:0000000000030A5B push r14
.text:0000000000030A5D push r15
.text:0000000000030A5F sub rsp, 88h
.text:0000000000030A66 mov r13d, r9d ; length
.text:0000000000030A69 mov r15, r8
.text:0000000000030A6C mov r14, rdx
.text:0000000000030A6F xor r12d, r12d
.text:0000000000030A72 mov [rsp+0B8h+var_80], r12
.text:0000000000030A77 xor esi, esi
.text:0000000000030A79 mov [rsp+0B8h+var_78], rsi
.text:0000000000030A7E mov [rsp+0B8h+arg_18], esi
.text:0000000000030A85 mov [rsp+0B8h+var_88], esi
.text:0000000000030A89 test r9d, r9d
.text:0000000000030A8C jnz short loc_30A95
.text:0000000000030A8E xor eax, eax
.text:0000000000030A90 jmp loc_30C46
.text:0000000000030A95 ; ---------------------------------------------------------------------------
.text:0000000000030A95
.text:0000000000030A95 loc_30A95: ; CODE XREF: ReadWriteMemory+38j
.text:0000000000030A95 mov [rsp+0B8h+HandleInformation], rsi ; HandleInformation
.text:0000000000030A9A lea rax, [rsp+0B8h+var_70] ; ProcessObject
.text:0000000000030A9F mov [rsp+0B8h+Object], rax ; Object
.text:0000000000030AA4 xor r9d, r9d ; AccessMode
.text:0000000000030AA7 xor r8d, r8d ; ObjectType
.text:0000000000030AAA xor edx, edx ; DesiredAccess
.text:0000000000030AAC call cs:ObReferenceObjectByHandle
.text:0000000000030AB2 test eax, eax
.text:0000000000030AB4 js loc_30C46
.text:0000000000030ABA call cs:IoGetCurrentProcess
.text:0000000000030AC0 cmp [rsp+0B8h+var_70], rax
.text:0000000000030AC5 jz loc_30BAE ; target process is the current process
.text:0000000000030ACB mov [rsp+0B8h+Object], rsi ; Irp
.text:0000000000030AD0 xor r9d, r9d ; ChargeQuota
.text:0000000000030AD3 xor r8d, r8d ; SecondaryBuffer
.text:0000000000030AD6 mov edx, r13d ; Length
.text:0000000000030AD9 mov rcx, r15 ; VirtualAddress
.text:0000000000030ADC call cs:IoAllocateMdl
.text:0000000000030AE2 mov rsi, rax
.text:0000000000030AE5 mov [rsp+0B8h+var_78], rax
.text:0000000000030AEA test rax, rax
.text:0000000000030AED jnz short loc_30AF9
.text:0000000000030AEF mov edi, 0C000009Ah ; status_insufficient_resources
.text:0000000000030AF4 jmp loc_30BF5
.text:0000000000030AF9 ; ---------------------------------------------------------------------------
.text:0000000000030AF9
.text:0000000000030AF9 loc_30AF9: ; CODE XREF: ReadWriteMemory+99j
.text:0000000000030AF9 lea rdx, [rsp+0B8h+var_68]
.text:0000000000030AFE mov rcx, [rsp+0B8h+var_70]
.text:0000000000030B03 call cs:KeStackAttachProcess ; attach to target process
.text:0000000000030B09 mov [rsp+0B8h+arg_18], 1 ; attached.
.text:0000000000030B14
.text:0000000000030B14 loc_30B14: ; DATA XREF: .text:0000000000067260o
.text:0000000000030B14 xor r8d, r8d
.text:0000000000030B17 cmp [rsp+0B8h+arg_28], r8d
.text:0000000000030B1F setnz r8b ; Operation
.text:0000000000030B23 xor edx, edx ; AccessMode
.text:0000000000030B25 mov rcx, rsi ; MemoryDescriptorList
.text:0000000000030B28 call cs:MmProbeAndLockPages ; IoWriteAccess=0x1
.text:0000000000030B2E mov [rsp+0B8h+var_88], 1
.text:0000000000030B36 mov dword ptr [rsp+0B8h+HandleInformation], 10h ; Priority
.text:0000000000030B3E mov dword ptr [rsp+0B8h+Object], 0 ; BugCheckOnFailure
.text:0000000000030B46 xor r9d, r9d ; BaseAddress
.text:0000000000030B49 xor edx, edx ; AccessMode
.text:0000000000030B4B lea r8d, [r9+1] ; CacheType
.text:0000000000030B4F mov rcx, rsi ; MemoryDescriptorList
.text:0000000000030B52 call cs:MmMapLockedPagesSpecifyCache
.text:0000000000030B58 mov r12, rax ; mapped!
.text:0000000000030B5B mov [rsp+0B8h+var_80], rax
.text:0000000000030B60 test rax, rax
.text:0000000000030B63 jnz short loc_30B73 ; 1 to read,0 to write!
.text:0000000000030B65 mov edi, 0C000009Ah
.text:0000000000030B6A mov [rsp+0B8h+var_84], edi
.text:0000000000030B6E jmp loc_30BF5
.text:0000000000030B73 ; ---------------------------------------------------------------------------
.text:0000000000030B73
.text:0000000000030B73 loc_30B73: ; CODE XREF: ReadWriteMemory+10Fj
.text:0000000000030B73 cmp [rsp+0B8h+arg_28], 0 ; 1 to read,0 to write!
.text:0000000000030B7B jz short loc_30B8D
.text:0000000000030B7D mov r8, r13 ; Size
.text:0000000000030B80 mov rdx, r14 ; Src
.text:0000000000030B83 mov rcx, rax ; Dst
.text:0000000000030B86 call memcpy
.text:0000000000030B8B jmp short loc_30B9C
.text:0000000000030B8D ; ---------------------------------------------------------------------------
.text:0000000000030B8D
.text:0000000000030B8D loc_30B8D: ; CODE XREF: ReadWriteMemory+127j
.text:0000000000030B8D mov r8, r13 ; Size
.text:0000000000030B90 mov rdx, rax ; Src
.text:0000000000030B93 mov rcx, r14 ; Dst
.text:0000000000030B96 call memcpy
.text:0000000000030B9B nop
.text:0000000000030B9C
.text:0000000000030B9C loc_30B9C: ; CODE XREF: ReadWriteMemory+137j
.text:0000000000030B9C ; DATA XREF: .text:0000000000067260o
.text:0000000000030B9C xor edi, edi
.text:0000000000030B9E jmp short loc_30BF5
.text:0000000000030BA0 ; ---------------------------------------------------------------------------
.text:0000000000030BA0
.text:0000000000030BA0 loc_30BA0: ; DATA XREF: .text:0000000000067260o
.text:0000000000030BA0 mov edi, eax
.text:0000000000030BA2 mov r12, [rsp+0B8h+var_80]
.text:0000000000030BA7 mov rsi, [rsp+0B8h+var_78]
.text:0000000000030BAC jmp short loc_30BF5
.text:0000000000030BAE ; ---------------------------------------------------------------------------
.text:0000000000030BAE
.text:0000000000030BAE loc_30BAE: ; CODE XREF: ReadWriteMemory+71j
.text:0000000000030BAE xor edi, edi
.text:0000000000030BB0
.text:0000000000030BB0 loc_30BB0: ; DATA XREF: .text:0000000000067270o
.text:0000000000030BB0 cmp [rsp+0B8h+arg_28], edi
.text:0000000000030BB7 jz short loc_30BC9
.text:0000000000030BB9 mov r8, r13 ; Size
.text:0000000000030BBC mov rdx, r14 ; Src
.text:0000000000030BBF mov rcx, r15 ; Dst
.text:0000000000030BC2 call memcpy
.text:0000000000030BC7 jmp short loc_30BD7
.text:0000000000030BC9 ; ---------------------------------------------------------------------------
.text:0000000000030BC9
.text:0000000000030BC9 loc_30BC9: ; CODE XREF: ReadWriteMemory+163j
.text:0000000000030BC9 mov r8, r13 ; Size
.text:0000000000030BCC mov rdx, r15 ; Src
.text:0000000000030BCF mov rcx, r14 ; Dst
.text:0000000000030BD2 call memcpy
.text:0000000000030BD7
.text:0000000000030BD7 loc_30BD7: ; CODE XREF: ReadWriteMemory+173j
.text:0000000000030BD7 mov rax, [rsp+0B8h+arg_20]
.text:0000000000030BDF test rax, rax
.text:0000000000030BE2 jz short loc_30BE7
.text:0000000000030BE4 mov [rax], r13d;LengthReadWritten
.text:0000000000030BE7
.text:0000000000030BE7 loc_30BE7: ; CODE XREF: ReadWriteMemory+18Ej
.text:0000000000030BE7 jmp short loc_30BF5
.text:0000000000030BE9 ; ---------------------------------------------------------------------------
.text:0000000000030BE9
.text:0000000000030BE9 loc_30BE9: ; DATA XREF: .text:0000000000067270o
.text:0000000000030BE9 mov edi, eax
.text:0000000000030BEB mov r12, [rsp+0B8h+var_80]
.text:0000000000030BF0 mov rsi, [rsp+0B8h+var_78]
.text:0000000000030BF5
.text:0000000000030BF5 loc_30BF5: ; CODE XREF: ReadWriteMemory+A0j
.text:0000000000030BF5 ; ReadWriteMemory+11Aj ...
.text:0000000000030BF5 test r12, r12
.text:0000000000030BF8 jz short loc_30C06
.text:0000000000030BFA mov rdx, rsi ; MemoryDescriptorList
.text:0000000000030BFD mov rcx, r12 ; BaseAddress
.text:0000000000030C00 call cs:MmUnmapLockedPages
.text:0000000000030C06
.text:0000000000030C06 loc_30C06: ; CODE XREF: ReadWriteMemory+1A4j
.text:0000000000030C06 cmp [rsp+0B8h+var_88], 0
.text:0000000000030C0B jz short loc_30C16 ; is attached?
.text:0000000000030C0D mov rcx, rsi ; MemoryDescriptorList
.text:0000000000030C10 call cs:MmUnlockPages
.text:0000000000030C16
.text:0000000000030C16 loc_30C16: ; CODE XREF: ReadWriteMemory+1B7j
.text:0000000000030C16 cmp [rsp+0B8h+arg_18], 0 ; is attached?
.text:0000000000030C1E jz short loc_30C2B
.text:0000000000030C20 lea rcx, [rsp+0B8h+var_68]
.text:0000000000030C25 call cs:KeUnstackDetachProcess
.text:0000000000030C2B
.text:0000000000030C2B loc_30C2B: ; CODE XREF: ReadWriteMemory+1CAj
.text:0000000000030C2B test rsi, rsi
.text:0000000000030C2E jz short loc_30C39
.text:0000000000030C30 mov rcx, rsi ; Mdl
.text:0000000000030C33 call cs:IoFreeMdl
.text:0000000000030C39
.text:0000000000030C39 loc_30C39: ; CODE XREF: ReadWriteMemory+1DAj
.text:0000000000030C39 mov rcx, [rsp+0B8h+var_70] ; Object
.text:0000000000030C3E call cs:ObfDereferenceObject
.text:0000000000030C44 mov eax, edi
.text:0000000000030C46
.text:0000000000030C46 loc_30C46: ; CODE XREF: ReadWriteMemory+3Cj
.text:0000000000030C46 ; ReadWriteMemory+60j
.text:0000000000030C46 add rsp, 88h
.text:0000000000030C4D pop r15
.text:0000000000030C4F pop r14
.text:0000000000030C51 pop r13
.text:0000000000030C53 pop r12
.text:0000000000030C55 pop rdi
.text:0000000000030C56 pop rsi
.text:0000000000030C57 retn
.text:0000000000030C57 ReadWriteMemory endp
.text:0000000000030C57
解釋:首先判斷LengthToReadWrite是否合法,接着調用ObReferenceObjectByHandle獲得ProcessHandle所指的進程對象,並 將該對象與當前進程對象比較。如果相等就表示接下來的內存讀寫都在同一進程環境下,可以直接memcpy;否則,先IoAllocateMdl(buffer,****),再KeStackAttachProcess,接MmProbeAndLockPages(*,*,IoWriteAccess/IoReadAccess)+MmMapLockedPagesSpecifyCache,最後根據讀寫請求在memcpy中調整Address和buffer的位置。重點注意:在目標進程不是當前進程時,先要在當前進程中將buffer與mdl對應起來,再附加到目標進程(可以試驗一下,調換先後循序)。如果是讀請求,MmProbeAndLockPages(*,*,IoWriteAccess),'讀'是從目標進程讀,然後寫到buffer中,這裏IoWriteAccess是對於buffer的;寫請求相反。
2019-8-12
(win10 1903)
typedef enum _ndis_request_type
{
NdisRequestQueryInformation=0,
NdisRequestSetInformation=1,
NdisRequestQueryStatistics=2,
NdisRequestOpen=3,
NdisRequestClose=4,
NdisRequestSend=5,
NdisRequestTransferData=6,
NdisRequestReset=7,
NdisRequestGeneric1=8,
NdisRequestGeneric2=9,
NdisRequestGeneric3=10,
NdisRequestGeneric4=11,
NdisRequestMethod=12
}NDIS_REQUEST_TYPE,*PNDIS_REQUEST_TYPE;
typedef struct _ndis_request
{
UCHAR MacReserved[32]; //0X0
NDIS_REQUEST_TYPE RequestType; //0X20
NDIS_REQUEST::DATA Data; //0X28
UCHAR NdisReserved[72]; //0X48
union //0X90
{
UCHAR CallMgrReserved[16];
UCHAR ProtocolReserved[16];
};
UCHAR MiniportReserved[16]; //0xa0
}NDIS_REQUEST,*PNDIS_REQUEST;
typedef struct _NDIS_REQUEST::_DATA
{
union
{
NDIS_REQUEST::DATA::QUERY_INFORMATION QUERY_INFORMATION;
NDIS_REQUEST::DATA::SET_INFORMATION SET_INFORMATION;
};
}NDIS_REQUEST::DATA;*NDIS_REQUEST::PDATA;
typedef sturct _ndis_request::_data::_set_information
{
ULONG Oid;//0x0
PVOID64 InformationBuffer;//0x8
ULONG InformationBufferLength;//0x10;
ULONG BytesRead;//0x14
ULONG BytesNeeded;//0x18
}NDIS_REQUEST::DATA::SET_INFORMATION,*NDIS_REQUEST::DATA::PSET_INFORMATION;
typedef struct _ndis_request::_data::_query_information
{
ULONG Oid;//0x0
PVOID64 InformationBuffer;//0x8
ULONG InformationBufferLength;//0x10;
ULONG BytesWritten;//0x14
ULONG BytesNeeded;//0x18
}NDIS_REQUEST::DATA::QUERY_INFORMATION;*NDIS_REQUEST::DATA::PQUERY_INFORMATION;
2019-08-14
6,線程執行
8F4 ; void __stdcall StartRoutine(PVOID StartContext)
.text:000000000001A8F4 StartRoutine proc near ; DATA XREF: RunInThread+8Bo
.text:000000000001A8F4 ; .pdata:000000000008F2A0o ...
.text:000000000001A8F4 push rbx
.text:000000000001A8F6 push rbp
.text:000000000001A8F7 push rsi
.text:000000000001A8F8 push rdi
.text:000000000001A8F9 push r12
.text:000000000001A8FB push r13
.text:000000000001A8FD push r14
.text:000000000001A8FF push r15
.text:000000000001A901 sub rsp, 28h
.text:000000000001A905 mov r13, rcx
.text:000000000001A908 call KeGetCurrentThread ; returns pkthread.
.text:000000000001A90D mov r14, [r13+0] ; sub_***
.text:000000000001A911 mov r15, [r13+8] ; ProcessId
.text:000000000001A915 mov rbx, rax
.text:000000000001A918 xor eax, eax
.text:000000000001A91A mov rsi, rax
.text:000000000001A91D mov rdi, rax
.text:000000000001A920 mov r12, rax
.text:000000000001A923 mov rbp, rax
.text:000000000001A926 call rand;產生隨機數據用來填充到_ethread中的StartAddress
.text:000000000001A92B mov rdx, cs:off_69080
.text:000000000001A932 movsxd r8, eax
.text:000000000001A935 xor eax, eax
.text:000000000001A937 add r8, [rdx+10h]
.text:000000000001A93B xor ecx, ecx
.text:000000000001A93D lock cmpxchg cs:qword_7E250, rcx
.text:000000000001A946 jz short loc_1A957
.text:000000000001A948 mov rsi, cs:qword_7E250
.text:000000000001A94F mov r12, [rsi+rbx];保存原來的StartAddress到r12
.text:000000000001A953 mov [rsi+rbx], r8
.text:000000000001A957
.text:000000000001A957 loc_1A957: ; CODE XREF: StartRoutine+52j
.text:000000000001A957 xor eax, eax
.text:000000000001A959 lock cmpxchg cs:qword_7E258, rcx
.text:000000000001A962 jz short loc_1A973
.text:000000000001A964 mov rdi, cs:qword_7E258
.text:000000000001A96B mov rbp, [rdi+rbx]
.text:000000000001A96F mov [rdi+rbx], r8 ; fill StartAddress in _ethread with random data
.text:000000000001A973
.text:000000000001A973 loc_1A973: ; CODE XREF: StartRoutine+6Ej
.text:000000000001A973 mov rcx, r13
.text:000000000001A976 call FreePool
.text:000000000001A97B mov rcx, r15 ; ProcessId
.text:000000000001A97E call r14 ;執行真正的線程 函數
.text:000000000001A981 xor ecx, ecx
.text:000000000001A983 cmp r12, rcx
.text:000000000001A986 jz short loc_1A98C
.text:000000000001A988 mov [rsi+rbx], r12;還原StartAddress
.text:000000000001A98C
.text:000000000001A98C loc_1A98C: ; CODE XREF: StartRoutine+92j
.text:000000000001A98C cmp rbp, rcx
.text:000000000001A98F jz short loc_1A995
.text:000000000001A991 mov [rdi+rbx], rbp
.text:000000000001A995
.text:000000000001A995 loc_1A995: ; CODE XREF: StartRoutine+9Bj
.text:000000000001A995 mov ecx, eax
.text:000000000001A997 add rsp, 28h
.text:000000000001A99B pop r15
.text:000000000001A99D pop r14
.text:000000000001A99F pop r13
.text:000000000001A9A1 pop r12
.text:000000000001A9A3 pop rdi
.text:000000000001A9A4 pop rsi
.text:000000000001A9A5 pop rbp
.text:000000000001A9A6 pop rbx
.text:000000000001A9A7 jmp cs:PsTerminateSystemThread
.text:000000000001A9A7 StartRoutine endp
解釋:PsCreateSystemThread時通過StartContext傳入參數塊,在StartRoutine中將當前線程的_ethread中StartAddress用隨機數填充(估計是爲了隱蔽),然後調用StartContext中的函數,最後還原。
2019-08-15
VOID STDCALL KeInitializeApc(PKAPC Apc,
PKTHREAD Thread,
KAPC_ENVIRONMENT TargetEnvironment,
PKERNEL_ROUTINE KernelRoutine,
PKRUNDOWN_ROUTINE RundownRoutine,
PKNORMAL_ROUTINE NormalRoutine,
KPROCESSOR_MODE Mode,
PVOID Context);
BOOLEAN NTAPI KeInsertQueueApc(PKAPC Apc,
PVOID SystemArgument1,PVOID SystemArgument2,
KPRIORITY PriorityBoost);