reactos操作系统实现(84)
来源:互联网 发布:法国黑人知乎 编辑:程序博客网 时间:2024/04/27 11:32
在系统里User32.dll,kernel32.dll,shell32.dll,gdi32.dll,rpcrt4.dll,comctl32.dll,advapi32.dll,version.dll等dll代表了Win32 API的基本提供者。Win32 API中的所有调用最终都转向了ntdll.dll,再由它转发至ntoskrnl.exe。ntdll.dll是本机 API用户模式的终端。真正的接口在ntoskrnl.exe里完成。事实上,内核模式的驱动大部分时间调用这个模块,如果它们请求系统服务。Ntdll.dll的主要作用就是让内核函数的特定子集可以被用户模式下运行的程序调用。Ntdll.dll通过软件中断int 2Eh进入ntoskrnl.exe,就是通过中断门切换CPU特权级。比如kernel32.dll导出的函数DeviceIoControl()实际上调用ntdll.dll中导出的NtDeviceIoControlFile(),反汇编一下这个函数可以看到,EAX载入magic数0x38,实际上是系统调用号,然后EDX指向堆栈。目标地址是当前堆栈指针ESP+4,所以EDX指向返回地址后面一个,也就是指向在进入NtDeviceIoControlFile()之前存入堆栈的东西。事实上就是函数的参数。下一个指令是int 2Eh,转到中断描述符表IDT位置0x2E处的中断处理程序。
下面就来分析怎么样加载NTDLL.DLL,具体实现代码始下:
#001 NTSTATUS
#002 NTAPI
#003 PsLocateSystemDll(VOID)
#004 {
#005 OBJECT_ATTRIBUTES ObjectAttributes;
#006 IO_STATUS_BLOCK IoStatusBlock;
#007 HANDLE FileHandle, SectionHandle;
#008 NTSTATUS Status;
#009 ULONG_PTR HardErrorParameters;
#010 ULONG HardErrorResponse;
#011
初始化NTDLL.DLL的对象,其中PsNtDllPathName是它的名称//SystemRoot//system32//ntdll.dll。在前面已经把系统路径设置好了。
#012 /* Locate and open NTDLL to determineImageBase and LdrStartup */
#013 InitializeObjectAttributes(&ObjectAttributes,
#014 &PsNtDllPathName,
#015 0,
#016 NULL,
#017 NULL);
打开文件NTDLL.DLL。
#018 Status = ZwOpenFile(&FileHandle,
#019 FILE_READ_ACCESS,
#020 &ObjectAttributes,
#021 &IoStatusBlock,
#022 FILE_SHARE_READ,
#023 0);
#024 if (!NT_SUCCESS(Status))
#025 {
#026 /* Failed, bugcheck */
#027 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 2, 0, 0);
#028 }
#029
检查NTDLL.DLL文件是否合法。
#030 /* Check if the image is valid */
#031 Status = MmCheckSystemImage(FileHandle,TRUE);
#032 if (Status ==STATUS_IMAGE_CHECKSUM_MISMATCH)
#033 {
#034 /* Raise a hard error */
#035 HardErrorParameters =(ULONG_PTR)&PsNtDllPathName;
#036 NtRaiseHardError(Status,
#037 1,
#038 1,
#039 &HardErrorParameters,
#040 OptionOk,
#041 &HardErrorResponse);
#042 return Status;
#043 }
#044
为NTDLL.DLL文件创建代码和数据段。
#045 /* Create a section for NTDLL */
#046 Status =ZwCreateSection(&SectionHandle,
#047 SECTION_ALL_ACCESS,
#048 NULL,
#049 NULL,
#050 PAGE_EXECUTE,
#051 SEC_IMAGE,
#052 FileHandle);
#053 ZwClose(FileHandle);
#054 if (!NT_SUCCESS(Status))
#055 {
#056 /* Failed, bugcheck */
#057 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 3, 0, 0);
#058 }
#059
添加引用段对象。
#060 /* Reference the Section */
#061 Status =ObReferenceObjectByHandle(SectionHandle,
#062 SECTION_ALL_ACCESS,
#063 MmSectionObjectType,
#064 KernelMode,
#065 (PVOID*)&PspSystemDllSection,
#066 NULL);
#067 ZwClose(SectionHandle);
#068 if (!NT_SUCCESS(Status))
#069 {
#070 /* Failed, bugcheck */
#071 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 4, 0, 0);
#072 }
#073
把NTDLL.DLL映射到内核空间。PspSystemDllBase是动态连接库的基地址。
#074 /* Map it */
#075 Status =PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase, FALSE);
#076 if (!NT_SUCCESS(Status))
#077 {
#078 /* Failed, bugcheck */
#079 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,Status, 5, 0, 0);
#080 }
#081
#082 /* Return status */
#083 return Status;
#084 }
- reactos操作系统实现(84)
- reactos操作系统实现(1)
- reactos操作系统实现(2)
- reactos操作系统实现(3)
- reactos操作系统实现(4)
- reactos操作系统实现(5)
- reactos操作系统实现(6)
- reactos操作系统实现(7)
- reactos操作系统实现(8)
- reactos操作系统实现(9)
- reactos操作系统实现(10)
- reactos操作系统实现(11)
- reactos操作系统实现(12)
- reactos操作系统实现(13)
- reactos操作系统实现(14)
- reactos操作系统实现(15)
- reactos操作系统实现(16)
- reactos操作系统实现(17)
- commons.primitives包结构分析
- 表的字段明明有index的,但为什么用不上呢?
- 中国移动结缘Symbian!
- Unicode XMan 1.0 正式版发布,Unicode代码及标准字符表工具
- linux下挂载(mount)光盘镜像文件、移动硬盘、U盘、Windows和NFS网络共享
- reactos操作系统实现(84)
- 开始学习java
- Verilog HDL数据类型
- 谈谈红楼梦(第43回)
- ORA-00932: 数据类型不一致: 应为 -, 但却获得 –
- linux操作系统下的voip通话实时性保证
- 090910(星期四):MFC程序的初始化
- vc 读书笔记
- 算法分析之分治法学习总结(一)