首页
社区
课程
招聘
[翻译]调用内核中未公开的API(x64平台)
2013-12-30 19:08 34288

[翻译]调用内核中未公开的API(x64平台)

2013-12-30 19:08
34288
   昨天晚上发现这篇文章不错,适合新手看,所以就翻译了下,第一次翻译翻译不当的地方,希望大家指出来啊
===============================
     这篇有别于其他的复杂深入研究windows内核文章。确切的说,阐述的是怎样访问那些出现在ntosknl中却没有被公开的API,如果你从r3层回溯一个windows api调用过程,将会发现将会结束点是类似这样子的(Win8 X64)。

     其中r10寄存器的值是第一个参数,eax中保存的是windows SSDT 的索引值(Windows internal syscall table)。需要注意的是上述代码是在x64运行一个 native x64 应用程序的情况。X86是通过NTDLL中的 KiFastSystemCall来实现一个syscall请求的.WOW64子系统通过创建一套机制使得x86应用程序可以跑在x64系统上。当syscall指令执行,对于NtOPenFile来说最终下面的代码会被执行(位于ntoskrnl中)。这实际上是一个对IoCreateFile的封装

  另外,需要注意的是,这个过程有许多的细节,syscall指令不只是简单直接的请求调Native Api,而是经过许多的例程,这些例程负责建立起陷阱框架(trp frames)并且执行访问权限核查流程,然后才到达native api执行流程。用于驱动的开发的导出的native 内核api 也有类似的过程,但是其机理不是很复杂,在内核中为每一个ZW* 函数提供了一个轻量封装的版本即Nt*,下面是一个例子

     这个过程通过创建栈帧,屏蔽内核中断(cli),保存标志位,随后用KiServiceLinkAge 函数分支执行返回指令。最后,Syscall 索引号0x31被放入eax中,并跳入KiServiceInteral例程中,这个例程,位于其他的例程之间,负责设置正确的PreviousMode并且遍历windows syscall 表(SSDT),之后调用Nt*  版的API。
===================================
     然而这些与本文主旨有何关系?答案是虽然内核为内核和驱动开发人员导出了成千上万的api,但是还有许多非常有价值的API提供了非常酷的功能(例如 ZwSuspendProcess/ZwResumeProcess, ZwReadVirtualMemory/ZwWriteVirtualMemory等。)但是这些函数没有被公开。这篇文章的目的就是接触这类API,这里有一些事情需要解决:
1.需要找到ntosknl 基址与其映像大小。
2.确定这些syscall,这里使用常规的方法来请求这些syscall
3.另外,要获取相关的API地址,(例如通过为了获取合法的进程句柄在内核中枚举目标进程(通过调用 ZwSuspend/ZwResume ))
===========
    这三点,第一点相对来说简单点,但是同样依赖于没有公开的一些特性。获取内核地址仅仅是调用未公开的API ZwQuerySystemInformation,其中SYSTEM_INFORMATION_CLASS 结构体将会返回一个指针指向SYSTEM_MODULE_INFORMATION结构体,这个结构体包含了加载的模块的数量,之后是变长的数组SYSTEM_MODULE 的指针,值得一提的是 NtInternals documentation 中关于这个结构体的说明有一些过时,首先这两个域的数据类型为ULONG-PTR而不是32bit的 ULONG,查找内核基址和映像的大小就是简单的遍历SYSTEM_MODULE 数组,查找内核名字,代码如下

    上面的函数返回PSYSTEM_MODULE ,它指向的是内核信息块。现在内核基地址与映像大小知道了,接下来就是找到请求未公开的syscall的方法,因为所有的未公开的Zw* 调用等同于简单分装之后调用KiSystemService,现在展示下请求这个调用过程(通过创建一个功能上相同的模板)

  在未分页的内存中,修补正确的地址(NullStub 替换了KiServiceLinkage)。然后请求KiSystemService(这里是通过移动64bit绝对地址到栈中,然后返回它),一旦在运行时完成修补,这个值就替换为相应的函数指针的值,然后像调用普通函数一样调用它,这里是该过程的一个展示

调用这个api的过程如下

在执行这些操作之前,KiServiceInternal 的地址需要获取,这样就可以很好得修补这些地址。某种角度上这就是为什么找到基地址的这么重要了。获取这个地址是通过扫描ntoskrnl内存KiServiceInternal 特征码来实现的,这个特征码必须充分的长而且比较特殊,但是也不能太长,因为这样就会花费更多的时间来查找,下面是该过程

这些工作都做完了,那么我们现在就开始调用任何我们想调用的Syscall。
======================
下面是一个例子,展示了怎样在目标进程虚拟地址空间中写入数据。这个进程将名字赋值给OpenProcess然后获取对应进程的EPROCESS块并且打开该进程的一个句柄,将这个句柄与未公开的api关联起来(比如进程操作之类(ZwProtectVirtualMemory/ZwWriteVirtualMemory)),一个内部未公开的函PsGetNextProcess)需要被获取,用它来帮助枚举进程。
#include "stdafx.h"
 
#include "Undocumented.h"
#include 
 
#ifdef __cplusplus
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath);
#endif
 
pPsGetProcessImageFileName PsGetProcessImageFileName;
pPsGetProcessSectionBaseAddress PsGetProcessSectionBaseAddress;
pPsGetNextProcess PsGetNextProcess;
pZwSuspendProcess ZwSuspendProcess;
pZwResumeProcess ZwResumeProcess;
pZwProtectVirtualMemory ZwProtectVirtualMemory;
pZwWriteVirtualMemory ZwWriteVirtualMemory;
pKiSystemService KiSystemService;
 
#ifdef _M_IX86
__declspec(naked) VOID SyscallTemplate(VOID) {
    __asm {
    /*B8 XX XX XX XX   */ mov eax, 0xC0DE
    /*8D 54 24 04      */ lea edx, [esp + 0x4]
    /*9C               */ pushfd
    /*6A 08            */ push 0x8
    /*FF 15 XX XX XX XX*/ call KiSystemService
    /*C2 XX XX         */ retn 0xBBBB
    }
}
#elif defined(_M_AMD64)
 
BYTE NullStub = 0xC3;
 
BYTE SyscallTemplate[] =
{
    0x48, 0x8B, 0xC4,                                           /*mov rax, rsp*/
    0xFA,                                                       /*cli*/
    0x48, 0x83, 0xEC, 0x10,                                     /*sub rsp, 0x10*/
    0x50,                                                       /*push rax*/
    0x9C,                                                       /*pushfq*/
    0x6A, 0x10,                                                 /*push 0x10*/
    0x48, 0xB8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, /*mov rax, NullStubAddress*/
    0x50,                                                       /*push rax*/
    0xB8, 0xBB, 0xBB, 0xBB, 0xBB,                               /*mov eax, Syscall*/
    0x68, 0xCC, 0xCC, 0xCC, 0xCC,                               /*push LowBytes*/
    0xC7, 0x44, 0x24, 0x04, 0xCC, 0xCC, 0xCC, 0xCC,             /*mov [rsp+0x4], HighBytes*/
    0xC3                                                        /*ret*/
};
#endif
 
PVOID FindFunctionInModule(IN CONST BYTE *Signature,
    IN ULONG SignatureSize,
    IN PVOID KernelBaseAddress,
    IN ULONG ImageSize) {
 
    BYTE *CurrentAddress = 0;
    ULONG i = 0;
 
    DbgPrint("+ Scanning from %p to %p\n", KernelBaseAddress, (ULONG_PTR)KernelBaseAddress + ImageSize);
    CurrentAddress = (BYTE *)KernelBaseAddress;
    DbgPrint("+ Scanning from %p to %p\n", KernelBaseAddress, (ULONG_PTR)KernelBaseAddress + ImageSize);
    CurrentAddress = (BYTE *)KernelBaseAddress;
 
    for(i = 0; i < ImageSize; ++i) {
        if(RtlCompareMemory(CurrentAddress, Signature, SignatureSize) == SignatureSize) {
            DbgPrint("+ Found function at %p\n", CurrentAddress);
            return (PVOID)CurrentAddress;
        }
    ++CurrentAddress;
    }
    return NULL;
}
 
NTSTATUS ResolveFunctions(IN PSYSTEM_MODULE KernelInfo) {
 
    UNICODE_STRING PsGetProcessImageFileNameStr = {0};
    UNICODE_STRING PsGetProcessSectionBaseAddressStr = {0};
#ifdef _M_IX86
    CONST BYTE PsGetNextProcessSignature[] =
    {
        0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x51, 0x83, 0x65,
        0xFC, 0x00, 0x56, 0x57, 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00,
        0x8B, 0xF0, 0xFF, 0x8E, 0xD4, 0x00, 0x00, 0x00, 0xB9, 0xC0,
        0x38, 0x56, 0x80, 0xE8, 0xB4, 0xEE, 0xF6, 0xFF, 0x8B, 0x45,
        0x08, 0x85, 0xC0
    };
#elif defined(_M_AMD64)
    CONST BYTE PsGetNextProcessSignature[] =
    {
        0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 0x6C, 0x24, 0x10,
        0x48, 0x89, 0x74, 0x24, 0x18, 0x57, 0x41, 0x54, 0x41, 0x55,
        0x41, 0x56, 0x41, 0x57, 0x48, 0x83, 0xEC, 0x20, 0x65, 0x48,
        0x8B, 0x34, 0x25, 0x88, 0x01, 0x00, 0x00, 0x45, 0x33, 0xED,
        0x48, 0x8B, 0xF9, 0x66, 0xFF, 0x8E, 0xC6, 0x01, 0x00, 0x00,
        0x4D, 0x8B, 0xE5, 0x41, 0x8B, 0xED, 0x41, 0x8D, 0x4D, 0x11,
        0x33, 0xC0,
    };
#endif
#ifdef _M_IX86
    CONST BYTE KiSystemServiceSignature[] =
    {
        0x6A, 0x00, 0x55, 0x53, 0x56, 0x57, 0x0F, 0xA0, 0xBB, 0x30,
        0x00, 0x00, 0x00, 0x66, 0x8E, 0xE3, 0x64, 0xFF, 0x35, 0x00,
        0x00, 0x00, 0x00
    };
#elif defined(_M_AMD64)
    CONST BYTE KiSystemServiceSignature[] =
    {
        0x48, 0x83, 0xEC, 0x08, 0x55, 0x48, 0x81, 0xEC, 0x58, 0x01,
        0x00, 0x00, 0x48, 0x8D, 0xAC, 0x24, 0x80, 0x00, 0x00, 0x00,
        0x48, 0x89, 0x9D, 0xC0, 0x00, 0x00, 0x00, 0x48, 0x89, 0xBD,
        0xC8, 0x00, 0x00, 0x00, 0x48, 0x89, 0xB5, 0xD0, 0x00, 0x00,
        0x00, 0xFB, 0x65, 0x48, 0x8B, 0x1C, 0x25, 0x88, 0x01, 0x00,
        0x00
    };
#endif
    RtlInitUnicodeString(&PsGetProcessImageFileNameStr, L"PsGetProcessImageFileName");
    RtlInitUnicodeString(&PsGetProcessSectionBaseAddressStr, L"PsGetProcessSectionBaseAddress");
 
    PsGetProcessImageFileName = (pPsGetProcessImageFileName)MmGetSystemRoutineAddress(&PsGetProcessImageFileNameStr);
    if(PsGetProcessImageFileName == NULL) {
        DbgPrint("- Could not find PsGetProcessImageFileName\n");
        return STATUS_UNSUCCESSFUL;
    }
    DbgPrint("+ Found PsGetProcessImageFileName at %p\n", PsGetProcessImageFileName);
 
    PsGetProcessSectionBaseAddress = (pPsGetProcessSectionBaseAddress)MmGetSystemRoutineAddress(&PsGetProcessSectionBaseAddressStr);
    if(PsGetProcessSectionBaseAddress == NULL) {
        DbgPrint("- Could not find PsGetProcessSectionBaseAddress\n");
        return STATUS_UNSUCCESSFUL;
    }
    DbgPrint("+ Found PsGetProcessSectionBaseAddress at %p\n", PsGetProcessSectionBaseAddress);
 
    PsGetNextProcess = (pPsGetNextProcess)FindFunctionInModule(PsGetNextProcessSignature,
        sizeof(PsGetNextProcessSignature), KernelInfo->ImageBaseAddress, KernelInfo->ImageSize);
    if(PsGetNextProcess == NULL) {
        DbgPrint("- Could not find PsGetNextProcess\n");
        return STATUS_UNSUCCESSFUL;
    }
    DbgPrint("+ Found PsGetNextProcess at %p\n", PsGetNextProcess);
 
    KiSystemService = (pKiSystemService)FindFunctionInModule(KiSystemServiceSignature,
        sizeof(KiSystemServiceSignature), KernelInfo->ImageBaseAddress, KernelInfo->ImageSize);
    if(KiSystemService == NULL) {
        DbgPrint("- Could not find KiSystemService\n");
        return STATUS_UNSUCCESSFUL;
    }
    DbgPrint("+ Found KiSystemService at %p\n", KiSystemService);
 
    return STATUS_SUCCESS;
}
 
VOID OnUnload(IN PDRIVER_OBJECT DriverObject) {
 
    DbgPrint("+ Unloading\n");
}
 
PSYSTEM_MODULE GetKernelModuleInfo(VOID) {
 
    PSYSTEM_MODULE SystemModule = NULL;
    PSYSTEM_MODULE FoundModule = NULL;
    ULONG_PTR SystemInfoLength = 0;
    PVOID Buffer = NULL;
    ULONG Count = 0;
    ULONG i = 0;
    ULONG j = 0;
    //Other names for WinXP
    CONST CHAR *KernelNames[] = { "ntoskrnl.exe", "ntkrnlmp.exe", "ntkrnlpa.exe", "ntkrpamp.exe" };
 
    //Perform error checking on the calls in actual code
    (VOID)ZwQuerySystemInformation(SystemModuleInformation, &SystemInfoLength, 0, &SystemInfoLength);
    Buffer = ExAllocatePool(NonPagedPool, SystemInfoLength);
    (VOID)ZwQuerySystemInformation(SystemModuleInformation, Buffer, SystemInfoLength, NULL);
 
    Count = ((PSYSTEM_MODULE_INFORMATION)Buffer)->ModulesCount;
    for(i = 0; i < Count; ++i) {
        SystemModule = &((PSYSTEM_MODULE_INFORMATION)Buffer)->Modules[i];
        for(j = 0; j < sizeof(KernelNames) / sizeof(KernelNames[0]); ++j) {
            if(strstr((LPCSTR)SystemModule->Name, KernelNames[j]) != NULL) {
                FoundModule = (PSYSTEM_MODULE)ExAllocatePool(NonPagedPool, sizeof(SYSTEM_MODULE));
                RtlCopyMemory(FoundModule, SystemModule, sizeof(SYSTEM_MODULE));
                ExFreePool(Buffer);
                return FoundModule;
            }
        }
    }
    DbgPrint("Could not find the kernel in module list\n");
    return NULL;
}
 
PEPROCESS GetEPROCESSFromName(IN CONST CHAR *ImageName) {
 
    PEPROCESS ProcessHead = PsGetNextProcess(NULL);
    PEPROCESS Process = PsGetNextProcess(NULL);
    CHAR *ProcessName = NULL;
 
    do {
        ProcessName = PsGetProcessImageFileName(Process);
        DbgPrint("+ Currently looking at %s\n", ProcessName);
        if(strstr(ProcessName, ImageName) != NULL) {
            DbgPrint("+ Found the process -- %s\n", ProcessName);
            return Process;
        }
        Process = PsGetNextProcess(Process);
    } while(Process != NULL && Process != ProcessHead);
    DbgPrint("- Could not find %s\n", ProcessName);
    return NULL;
}
 
HANDLE GetProcessIdFromEPROCESS(PEPROCESS Process) {
 
    return PsGetProcessId(Process);
}
 
HANDLE OpenProcess(IN CONST CHAR *ProcessName, OUT OPTIONAL PEPROCESS *pProcess) {
 
    HANDLE ProcessHandle = NULL;
    CLIENT_ID ClientId = {0};
    OBJECT_ATTRIBUTES ObjAttributes = {0};
    PEPROCESS EProcess = GetEPROCESSFromName(ProcessName);
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
 
    if(EProcess == NULL) {
        return NULL;
    }
    InitializeObjectAttributes(&ObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
    ObjAttributes.ObjectName = NULL;
    ClientId.UniqueProcess = GetProcessIdFromEPROCESS(EProcess);
    ClientId.UniqueThread = NULL;
 
    Status = ZwOpenProcess(&ProcessHandle, PROCESS_ALL_ACCESS, &ObjAttributes, &ClientId);
    if(!NT_SUCCESS(Status)) {
        DbgPrint("- Could not open process %s. -- %X\n", ProcessName, Status);
        return NULL;
    }
    if(pProcess != NULL) {
        *pProcess = EProcess;
    }
    return ProcessHandle;
}
 
PVOID CreateSyscallWrapper(IN LONG Index, IN SHORT NumParameters) {
 
#ifdef _M_IX86
    SIZE_T StubLength = 0x15;
    PVOID Buffer = ExAllocatePool(NonPagedPool, StubLength);
    BYTE *SyscallIndex = ((BYTE *)Buffer) + sizeof(BYTE);
    BYTE *Retn = ((BYTE *)Buffer) + (0x13 * (sizeof(BYTE)));
    RtlCopyMemory(Buffer, SyscallTemplate, StubLength);
    NumParameters = NumParameters * sizeof(ULONG_PTR);
    RtlCopyMemory(SyscallIndex, &Index, sizeof(LONG));
    RtlCopyMemory(Retn, &NumParameters, sizeof(SHORT));
    return Buffer;
#elif defined(_M_AMD64)
    PVOID Buffer = ExAllocatePool(NonPagedPool, sizeof(SyscallTemplate));
    BYTE *NullStubAddress = &NullStub;
    BYTE *NullStubAddressIndex = ((BYTE *)Buffer) + (14 * sizeof(BYTE));
    BYTE *SyscallIndex = ((BYTE *)Buffer) + (24 * sizeof(BYTE));
    BYTE *LowBytesIndex = ((BYTE *)Buffer) + (29 * sizeof(BYTE));
    BYTE *HighBytesIndex = ((BYTE *)Buffer) + (37 * sizeof(BYTE));
    ULONG LowAddressBytes = ((ULONG_PTR)KiSystemService) & 0xFFFFFFFF;
    ULONG HighAddressBytes = ((ULONG_PTR)KiSystemService >> 32);
    RtlCopyMemory(Buffer, SyscallTemplate, sizeof(SyscallTemplate));
    RtlCopyMemory(NullStubAddressIndex, (PVOID)&NullStubAddress, sizeof(BYTE *));
    RtlCopyMemory(SyscallIndex, &Index, sizeof(LONG));
    RtlCopyMemory(LowBytesIndex, &LowAddressBytes, sizeof(ULONG));
    RtlCopyMemory(HighBytesIndex, &HighAddressBytes, sizeof(ULONG));
    return Buffer;
#endif
}
 
VOID InitializeSyscalls(VOID) {
 
#ifdef _M_IX86
    ZwSuspendProcess = (pZwSuspendProcess)CreateSyscallWrapper(0x00FD, 1);
    ZwResumeProcess = (pZwResumeProcess)CreateSyscallWrapper(0x00CD, 1);
    ZwProtectVirtualMemory = (pZwProtectVirtualMemory)CreateSyscallWrapper(0x0089, 5);
    ZwWriteVirtualMemory = (pZwWriteVirtualMemory)CreateSyscallWrapper(0x0115, 5);
#elif defined(_M_AMD64)
    ZwSuspendProcess = (pZwSuspendProcess)CreateSyscallWrapper(0x017A, 1);
    ZwResumeProcess = (pZwResumeProcess)CreateSyscallWrapper(0x0144, 1);
    ZwProtectVirtualMemory = (pZwProtectVirtualMemory)CreateSyscallWrapper(0x004D, 5);
    ZwWriteVirtualMemory = (pZwWriteVirtualMemory)CreateSyscallWrapper(0x0037, 5);
#endif
}
 
VOID FreeSyscalls(VOID) {
 
    ExFreePool(ZwSuspendProcess);
    ExFreePool(ZwResumeProcess);
    ExFreePool(ZwProtectVirtualMemory);
    ExFreePool(ZwWriteVirtualMemory);
}
 
PVOID GetProcessBaseAddress(IN PEPROCESS Process) {
 
    return PsGetProcessSectionBaseAddress(Process);
}
 
NTSTATUS WriteToProcessAddress(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN BYTE *NewBytes, IN SIZE_T NewBytesSize) {
 
    ULONG OldProtections = 0;
    SIZE_T BytesWritten = 0;
    SIZE_T NumBytesToProtect = NewBytesSize;
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
 
    //Needs error checking
    Status = ZwSuspendProcess(ProcessHandle);
    Status = ZwProtectVirtualMemory(ProcessHandle, &BaseAddress, &NumBytesToProtect, PAGE_EXECUTE_READWRITE, &OldProtections);
    Status = ZwWriteVirtualMemory(ProcessHandle, BaseAddress, NewBytes, NewBytesSize, &BytesWritten);
    Status = ZwProtectVirtualMemory(ProcessHandle, &BaseAddress, &NumBytesToProtect, OldProtections, &OldProtections);
    Status = ZwResumeProcess(ProcessHandle);
 
    return STATUS_SUCCESS;
}
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath) {
 
    PSYSTEM_MODULE KernelInfo = NULL;
    PEPROCESS Process = NULL;
    HANDLE ProcessHandle = NULL;
    PVOID BaseAddress = NULL;
    BYTE NewBytes[0x100] = {0};
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
 
    DbgPrint("+ Driver successfully loaded\n");
 
    DriverObject->DriverUnload = OnUnload;
 
    KernelInfo = GetKernelModuleInfo();
    if(KernelInfo == NULL) {
        DbgPrint("Could not find kernel module\n");
        return STATUS_UNSUCCESSFUL;
    }
    DbgPrint("+ Found kernel module.\n"
        "+ Name: %s -- Base address: %p -- Size: %p\n", KernelInfo->Name,
        KernelInfo->ImageBaseAddress, KernelInfo->ImageSize);
 
    if(!NT_SUCCESS(ResolveFunctions(KernelInfo))) {
        return STATUS_UNSUCCESSFUL;
    }
 
    InitializeSyscalls();
 
    ProcessHandle = OpenProcess("notepad.exe", &Process);
    if(ProcessHandle == NULL) {
        return STATUS_UNSUCCESSFUL;
    }
    BaseAddress = GetProcessBaseAddress(Process);
    if(BaseAddress == NULL) {
        return STATUS_UNSUCCESSFUL;
    }
 
    DbgPrint("Invoking\n");
    RtlFillMemory(NewBytes, sizeof(NewBytes), 0x90);
    (VOID)WriteToProcessAddress(ProcessHandle, BaseAddress, NewBytes, sizeof(NewBytes));
    DbgPrint("+ Done\n");
 
    ExFreePool(KernelInfo);
    FreeSyscalls();
    ZwClose(ProcessHandle);
 
    return STATUS_SUCCESS;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (28)
雪    币: 72
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
心灵守望 2013-12-30 19:15
2
0
感谢楼主,很有帮助。非常适合菜鸟
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
C兔 2013-12-30 19:16
3
0
天王盖地虎,撸主好威武!!
雪    币: 209
活跃值: (638)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
惊电 2013-12-30 20:06
4
0
只是 Undocumented.h 在哪里呢??
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
mccoysc 2013-12-30 20:27
5
0
搞得这么麻烦,不就是调用ssdt函数么……
实际上,zw系列函数,是从index为0的zw函数开始,挨个顺序排列的,而且每个zw函数的字节数完全一致。所以:
第一,根据任何两个已导出的zw函数的地址以及他们的index值,算出一个zw函数所占字节数。
第二,根据上面算出的单个zw函数的字节数以及任何一个已导出的zw函数的索引值,还有这个函数的地址,算出index为0的zw函数的地址。
第三,调用任何一个zw函数(不管导出没导出,只要知道index就是了)时,用index为0的函数的地址base,加上单个函数字节数乘以index,最后的和就是要被调用的函数的地址,形如:pZwFunc=ulIndex*SizePerFunc+pBase;
雪    币: 144
活跃值: (46)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gotmilk 2 2013-12-30 20:27
6
0
没有这个文件,这是一个网站,里面有windows未公开的api的详解  网址是http://undocumented.ntinternals.net/
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
mccoysc 2013-12-30 20:30
7
0
整个过程基本不存在任何硬编码,不比费那么大劲儿高效兼容性好吗
雪    币: 144
活跃值: (46)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gotmilk 2 2013-12-30 20:33
8
0
我也是新手,接触内核不多,只是觉得这篇不错就翻译了下,干嘛这么激动啊。。。
雪    币: 23
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
GhostDL 2013-12-30 21:17
9
0
支持一下  
雪    币: 124
活跃值: (344)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
topofall 2013-12-30 22:01
10
0
mark并且支持一下
雪    币: 47
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jpys 2013-12-31 08:34
11
0
mark
雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2013-12-31 09:34
12
0
mark
雪    币: 199
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaoyang 2013-12-31 12:35
13
0
mark
雪    币: 341
活跃值: (133)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
地狱怪客 2 2014-1-1 09:09
14
0
越来越刁了。。都朝着系统 内核去了
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mumaren 2014-1-1 12:45
15
0
感谢共享

谢谢
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mubiaope 2014-1-4 12:37
16
0
mccoysc 说得很正确,在 rootkit winows 内核安全一书中的ssdt hook就用这个这个原理的宏
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
寒窗苦读 2014-2-21 13:23
17
0
不错,很难得的资料,感谢楼主分享!
雪    币: 177
活跃值: (1956)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xingbing 2014-3-2 18:51
18
0
64位系统下的资料很少。
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
silence刘 2014-3-5 15:15
19
0
楼主的文章不错,上面那位大神的想法也很简单。。。学习了
雪    币: 5
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pooiy 2014-3-24 22:52
20
0
mark
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小W 2014-3-24 23:01
21
0
到了64位系统,什么杀毒什么保护都是浮云。。。微软就是不给你动它内核,你耐他何?
雪    币: 77
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cqzj70 2014-4-13 18:42
22
0
mark
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rqqeq 2014-4-13 19:05
23
0
我会说64位全系列的系统的内核保护都浮云了么
雪    币: 50
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
return 2014-4-18 14:35
24
0
支持作者!
雪    币: 144
活跃值: (46)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gotmilk 2 2014-4-19 15:57
25
0
看到大家的回复很感谢,我也是菜鸟,以后会翻译更多的paper ,并且也会写点新东西,愿与大家一起分享
游客
登录 | 注册 方可回帖
返回