API调用流程(x86)
Windows内核中的执行体层暴露了大量执行体中的对象给Windows用户层的API来操作,那么用户层的API是怎么调用这些功能的呢,比如说创建一个文件,文件是一个内核对象必须得有内核层来处理,所以肯定有一个从用户层到内核层然后内核层解决再返回到用户层的一个流程。
这里以CreateFile举例:(大致流程如下)
可以看到在调用CreateFile时,是直接采用的Kernel32中的CreateFileW函数:
然后跟进Kernel32.CreateFileW函数中:
会跳转到KernelBase中的CreateFileW函数中,继续步入查看:
一直往下翻才能看到NtCreateFile函数,前面的我猜是给创建新文件所需进行初始化的一些代码。
正所谓前人栽树后人乘凉,书上的大牛写的是调用ntdll中的NtCreateFile我们就不要怀疑了,然后步入Ntdll.NtCreateFile查看:
这里的call esi就是调用NtCreateFile的地方,然后继续步入查看:
就成了这样子,这个我也不知道什么意思,就继续call dword ptr ds:[edx]查看:
最后的最后是由三个汇编指令为结尾:
retn是返回指令,表示已经执行完成。
sysenter在od中无法看到,不管是步入还是步过只会直接执行完跳过。
所以目前而言的API调用过程是这样的:
现在不理解的就是NtCreateFile函数内部的代码逻辑:
这几行汇编代码是什么意思。
首先是NtCreateFile中的第一层汇编代码:
这附近的汇编代码都是这样的样式:
这里的eax叫做系统服务号,它代表进入0环后,调用那一个API,就类似于数组和下标的关系,根据下标一对一对应内核中的某一个API,然后内核调用内核的对应的API。
也就是说由eax的值来决定内核API的调用。
所有通过ntdll调用的函数,给edx所传递的值都是一样的,这里都是0x7FFE0300
该值是_KUSER_SHARED_DATA结构体的一个成员,该结构体所在的内存空间是一个提供给User层和Kernel层共享的一个内存空间,该空间主要用来在User和Kernel之间快速传递信息。
该结构体所在的内存空间是固定的:User层下:0x7FFE0000,Kernel层下:0xFFDF0000
edx是该结构体中的SystemCall成员,该结构体成员指定了从User层到Kernel层的调用方式,这里我们可以通过WinDbg来查看一下:
那么图就可以变成这样子:
然后重点就来到了剩下的两个。
这个其实就是函数传参,参数在栈里面,然后把栈的首地址交给edx。
sysenter才是整个调用的关键。
整个调用方式最关键的就是通过sysenter从User层到达Kernel层,可以说前面的都是在给这一步做铺垫。
sysenter叫做快速系统调用,叫快速是因为之前的系统调用不快,在Pentium II(奔腾2代CPU)之后才有的sysenter,在其之前是采用的 KiIntSystemCall函数来处理的。
在IDA下查看:该函数:
这里的int 2Eh,采用的就是一种CPU机制,叫做中断门:
Windows内核中的CPU架构-6-中断门(32-Bit Interrupt Gate) - Sna1lGo - 博客园 (cnblogs.com)
这样调用会用到内存,比较麻烦,所以就引入了快速系统调用:
sysenter/sysexit 两个函数和三个MSR寄存器。
MSR寄存器比较类似内存,直接根据序号来命名,没有像通用寄存器EAX,EBX一样,单独命名。
和sysenter连用的是MSR174和,MSR175,MSR176三个寄存器
sysenter内部逻辑为:
using namespace std;
int
main()
{
cout <<
"Begin"
<< endl;
auto hFile
=
CreateFileW(
L
"temp.txt"
,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
return
NULL;
}
using namespace std;
int
main()
{
cout <<
"Begin"
<< endl;
auto hFile
=
CreateFileW(
L
"temp.txt"
,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
return
NULL;
}
mov edx,esp
sysenter
retn
mov edx,esp
sysenter
retn
mov eax,xx
mov edx,xxx
call dword ptr ds:[edx]
retn xxx
...
mov edx,esp
sysenter
mov eax,xx
mov edx,xxx
call dword ptr ds:[edx]
retn xxx
...
mov edx,esp
sysenter
mov eax,xx
mov edx,xx
call dword ptr ds:[edx]
retn xxx
mov eax,xx
mov edx,xx
call dword ptr ds:[edx]
retn xxx
/
/
0x5f0
bytes (sizeof)
struct _KUSER_SHARED_DATA
{
ULONG TickCountLowDeprecated;
/
/
0x0
ULONG TickCountMultiplier;
/
/
0x4
volatile struct _KSYSTEM_TIME InterruptTime;
/
/
0x8
volatile struct _KSYSTEM_TIME SystemTime;
/
/
0x14
volatile struct _KSYSTEM_TIME TimeZoneBias;
/
/
0x20
USHORT ImageNumberLow;
/
/
0x2c
USHORT ImageNumberHigh;
/
/
0x2e
WCHAR NtSystemRoot[
260
];
/
/
0x30
ULONG MaxStackTraceDepth;
/
/
0x238
ULONG CryptoExponent;
/
/
0x23c
ULONG TimeZoneId;
/
/
0x240
ULONG LargePageMinimum;
/
/
0x244
ULONG Reserved2[
7
];
/
/
0x248
enum _NT_PRODUCT_TYPE NtProductType;
/
/
0x264
UCHAR ProductTypeIsValid;
/
/
0x268
ULONG NtMajorVersion;
/
/
0x26c
ULONG NtMinorVersion;
/
/
0x270
UCHAR ProcessorFeatures[
64
];
/
/
0x274
ULONG Reserved1;
/
/
0x2b4
ULONG Reserved3;
/
/
0x2b8
volatile ULONG TimeSlip;
/
/
0x2bc
enum _ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
/
/
0x2c0
ULONG AltArchitecturePad[
1
];
/
/
0x2c4
union _LARGE_INTEGER SystemExpirationDate;
/
/
0x2c8
ULONG SuiteMask;
/
/
0x2d0
UCHAR KdDebuggerEnabled;
/
/
0x2d4
UCHAR NXSupportPolicy;
/
/
0x2d5
volatile ULONG ActiveConsoleId;
/
/
0x2d8
volatile ULONG DismountCount;
/
/
0x2dc
ULONG ComPlusPackage;
/
/
0x2e0
ULONG LastSystemRITEventTickCount;
/
/
0x2e4
ULONG NumberOfPhysicalPages;
/
/
0x2e8
UCHAR SafeBootMode;
/
/
0x2ec
union
{
UCHAR TscQpcData;
/
/
0x2ed
struct
{
UCHAR TscQpcEnabled:
1
;
/
/
0x2ed
UCHAR TscQpcSpareFlag:
1
;
/
/
0x2ed
UCHAR TscQpcShift:
6
;
/
/
0x2ed
};
};
UCHAR TscQpcPad[
2
];
/
/
0x2ee
union
{
ULONG SharedDataFlags;
/
/
0x2f0
struct
{
ULONG DbgErrorPortPresent:
1
;
/
/
0x2f0
ULONG DbgElevationEnabled:
1
;
/
/
0x2f0
ULONG DbgVirtEnabled:
1
;
/
/
0x2f0
ULONG DbgInstallerDetectEnabled:
1
;
/
/
0x2f0
ULONG DbgSystemDllRelocated:
1
;
/
/
0x2f0
ULONG DbgDynProcessorEnabled:
1
;
/
/
0x2f0
ULONG DbgSEHValidationEnabled:
1
;
/
/
0x2f0
ULONG SpareBits:
25
;
/
/
0x2f0
};
};
ULONG DataFlagsPad[
1
];
/
/
0x2f4
ULONGLONG TestRetInstruction;
/
/
0x2f8
ULONG SystemCall;
/
/
0x300
ULONG SystemCallReturn;
/
/
0x304
ULONGLONG SystemCallPad[
3
];
/
/
0x308
union
{
volatile struct _KSYSTEM_TIME TickCount;
/
/
0x320
volatile ULONGLONG TickCountQuad;
/
/
0x320
ULONG ReservedTickCountOverlay[
3
];
/
/
0x320
};
ULONG TickCountPad[
1
];
/
/
0x32c
ULONG Cookie;
/
/
0x330
ULONG CookiePad[
1
];
/
/
0x334
LONGLONG ConsoleSessionForegroundProcessId;
/
/
0x338
ULONG Wow64SharedInformation[
16
];
/
/
0x340
USHORT UserModeGlobalLogger[
16
];
/
/
0x380
ULONG ImageFileExecutionOptions;
/
/
0x3a0
ULONG LangGenerationCount;
/
/
0x3a4
ULONGLONG Reserved5;
/
/
0x3a8
volatile ULONGLONG InterruptTimeBias;
/
/
0x3b0
volatile ULONGLONG TscQpcBias;
/
/
0x3b8
volatile ULONG ActiveProcessorCount;
/
/
0x3c0
volatile USHORT ActiveGroupCount;
/
/
0x3c4
USHORT Reserved4;
/
/
0x3c6
volatile ULONG AitSamplingValue;
/
/
0x3c8
volatile ULONG AppCompatFlag;
/
/
0x3cc
ULONGLONG SystemDllNativeRelocation;
/
/
0x3d0
ULONG SystemDllWowRelocation;
/
/
0x3d8
ULONG XStatePad[
1
];
/
/
0x3dc
struct _XSTATE_CONFIGURATION XState;
/
/
0x3e0
};
/
/
0x5f0
bytes (sizeof)
struct _KUSER_SHARED_DATA
{
ULONG TickCountLowDeprecated;
/
/
0x0
ULONG TickCountMultiplier;
/
/
0x4
volatile struct _KSYSTEM_TIME InterruptTime;
/
/
0x8
volatile struct _KSYSTEM_TIME SystemTime;
/
/
0x14
volatile struct _KSYSTEM_TIME TimeZoneBias;
/
/
0x20
USHORT ImageNumberLow;
/
/
0x2c
USHORT ImageNumberHigh;
/
/
0x2e
WCHAR NtSystemRoot[
260
];
/
/
0x30
ULONG MaxStackTraceDepth;
/
/
0x238
ULONG CryptoExponent;
/
/
0x23c
ULONG TimeZoneId;
/
/
0x240
ULONG LargePageMinimum;
/
/
0x244
ULONG Reserved2[
7
];
/
/
0x248
enum _NT_PRODUCT_TYPE NtProductType;
/
/
0x264
UCHAR ProductTypeIsValid;
/
/
0x268
ULONG NtMajorVersion;
/
/
0x26c
ULONG NtMinorVersion;
/
/
0x270
UCHAR ProcessorFeatures[
64
];
/
/
0x274
ULONG Reserved1;
/
/
0x2b4
ULONG Reserved3;
/
/
0x2b8
volatile ULONG TimeSlip;
/
/
0x2bc
enum _ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
/
/
0x2c0
ULONG AltArchitecturePad[
1
];
/
/
0x2c4
union _LARGE_INTEGER SystemExpirationDate;
/
/
0x2c8
ULONG SuiteMask;
/
/
0x2d0
UCHAR KdDebuggerEnabled;
/
/
0x2d4
UCHAR NXSupportPolicy;
/
/
0x2d5
volatile ULONG ActiveConsoleId;
/
/
0x2d8
volatile ULONG DismountCount;
/
/
0x2dc
ULONG ComPlusPackage;
/
/
0x2e0
ULONG LastSystemRITEventTickCount;
/
/
0x2e4
ULONG NumberOfPhysicalPages;
/
/
0x2e8
UCHAR SafeBootMode;
/
/
0x2ec
union
{
UCHAR TscQpcData;
/
/
0x2ed
struct
{
UCHAR TscQpcEnabled:
1
;
/
/
0x2ed
UCHAR TscQpcSpareFlag:
1
;
/
/
0x2ed
UCHAR TscQpcShift:
6
;
/
/
0x2ed
};
};
UCHAR TscQpcPad[
2
];
/
/
0x2ee
union
{
ULONG SharedDataFlags;
/
/
0x2f0
struct
{
ULONG DbgErrorPortPresent:
1
;
/
/
0x2f0
ULONG DbgElevationEnabled:
1
;
/
/
0x2f0
ULONG DbgVirtEnabled:
1
;
/
/
0x2f0
ULONG DbgInstallerDetectEnabled:
1
;
/
/
0x2f0
ULONG DbgSystemDllRelocated:
1
;
/
/
0x2f0
ULONG DbgDynProcessorEnabled:
1
;
/
/
0x2f0
ULONG DbgSEHValidationEnabled:
1
;
/
/
0x2f0
ULONG SpareBits:
25
;
/
/
0x2f0
};
};
ULONG DataFlagsPad[
1
];
/
/
0x2f4
ULONGLONG TestRetInstruction;
/
/
0x2f8
ULONG SystemCall;
/
/
0x300
ULONG SystemCallReturn;
/
/
0x304
ULONGLONG SystemCallPad[
3
];
/
/
0x308
union
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-7-14 14:45
被SnA1lGo编辑
,原因: