博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows程序设计_18_程序加载过程
阅读量:6282 次
发布时间:2019-06-22

本文共 6821 字,大约阅读时间需要 22 分钟。

  今天看Windows Program Via c/c++;突然想看一下Windows加载EXE文件或者可执行文件的过程。于是就建立了一个

项目进行测试:

  代码很简单,就是建立一个窗口。

/*    windows program via c/c++exp:    chapter  1*/#include 
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ){ TCHAR szAppName[]=TEXT("ErrorWin"); HWND hwnd; //窗口句柄 WNDCLASS wndclass; //窗口类 MSG message; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndclass.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hInstance =hInstance; wndclass.lpfnWndProc=WndProc; wndclass.lpszClassName=szAppName; wndclass.lpszMenuName=NULL; wndclass.style = CS_HREDRAW | CS_VREDRAW; if(!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("You need Windows NT to run this program"), TEXT("ErrorWin"), MB_ICONERROR); return 0; } hwnd=CreateWindow(szAppName, //窗口类名 TEXT("ErrorWin"), //窗口标题 WS_OVERLAPPEDWINDOW, //窗口层叠类型 CW_USEDEFAULT,//x CW_USEDEFAULT, //y 480, //hight 240, //width NULL, //父窗口句柄 NULL, //菜单句柄 hInstance, //实例句柄 NULL //附加参数 ); ShowWindow(hwnd,nShowCmd); UpdateWindow(hwnd); while(GetMessage(&message,hwnd,0,0)) { TranslateMessage(&message); DispatchMessage(&message); } return message.wParam;}LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ switch(message) { case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam);}

  下面是程序执行过程VS 2008 Output窗口显示的调试信息:

 

 

'chapter1_01.exe': Loaded 'G:\13_Windows_Program_Via_C\chapter1_01\Debug\chapter1_01.exe', Symbols loaded.'chapter1_01.exe': Loaded 'C:\Windows\System32\ntdll.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\kernel32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\KernelBase.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\user32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\gdi32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\lpk.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\usp10.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\msvcrt.dll''chapter1_01.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.21022.8_none_96748342450f6aa2\msvcr90d.dll', Symbols loaded.'chapter1_01.exe': Loaded 'C:\Windows\System32\imm32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\msctf.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\uxtheme.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\apphelp.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\baiducn.ime''chapter1_01.exe': Loaded 'C:\Windows\System32\oleacc.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\ole32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\rpcrt4.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\advapi32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\sechost.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\shell32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\shlwapi.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\oleaut32.dll''chapter1_01.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7601.17514_none_ec83dffa859149af\comctl32.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\version.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\profapi.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\dwmapi.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\cryptbase.dll''chapter1_01.exe': Loaded 'C:\Program Files\Baidu\BaiduPinyin\2.4.2.281\uipfull.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\winmm.dll''chapter1_01.exe': Loaded 'C:\Windows\System32\msimg32.dll''chapter1_01.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_72d18a4386696c80\GdiPlus.dll''chapter1_01.exe': Loaded 'C:\Program Files\Baidu\BaiduPinyin\2.4.2.281\imefreetype.dll', Binary was not built with debug information.'chapter1_01.exe': Loaded 'C:\Program Files\Baidu\BaiduPinyin\2.4.2.281\imepng.dll', Binary was not built with debug information.'chapter1_01.exe': Loaded 'C:\Program Files\Baidu\BaiduPinyin\2.4.2.281\imezlib.dll', Binary was not built with debug information.'chapter1_01.exe': Loaded 'C:\Windows\System32\sspicli.dll'The thread 'Win32 Thread' (0x7fc) has exited with code 0 (0x0).The thread 'Win32 Thread' (0xb74) has exited with code 0 (0x0).The thread 'Win32 Thread' (0x210) has exited with code 0 (0x0).The thread 'Win32 Thread' (0xd34) has exited with code 0 (0x0).The program '[3940] chapter1_01.exe: Native' has exited with code 0 (0x0).

  我们可以看各行的信息:

【1】

Loaded 'G:\13_Windows_Program_Via_C\chapter1_01\Debug\chapter1_01.exe', Symbols loaded.

  这一行的内容:  显示加载可执行文件到内存,并且加载程序的符号,毫无疑问,第一步必须将文件从硬盘加载到内存,才有可能执行。

【2】

'chapter1_01.exe': Loaded 'C:\Windows\System32\ntdll.dll'

  加载ntdll.dll中的内容,这个动态链接库文件,应该是一直常驻内存的;这个地方既然不是加载,那么就必然是调用函数,那么这个时候调用的会

是那个API函数呢?

  我们可以通过查看ntdll.dll文件的导出符号表,发现里面有一个NtCreateProcess函数,如下图所示:

  虽然我们在Windows API中有CreateProcess函数可以使用;但是函数CreateProcess最终都会调用NtCreateProcess函数来创建进程;这个函数

的作用就是创建内核进程对象,具体是:

所谓创建内核中的进程对象,实际上就是创建以EPROCESS为核心、为基础的相关数据结构,这就是系统调用NtCreateProcess()要做的事情,主要包括:    ● 分配并设置EPROCESS数据结构。    ● 其他相关的数据结构的设置,例如“打开对象表”。    ● 为目标进程创建初始的地址空间。    ● 对目标进程的“内核进程块”KPROCESS进行初始化。    ● 将系统DLL的映像映射到目标进程的(用户)地址空间。    ● 将目标进程的映像映射到其自身的用户空间。    ● 设置好目标进程的“进程环境块”PEB。    ● 映射其他需要映射到用户空间的数据结构,例如与“当地语言支持”、即NLS有关的数据结构。    ● 完成EPROCESS创建,将其挂入进程队列(注意受调度的是线程队列而不是进程队列)。

  当然这个过程也会进行一次线程的创建,如果是单线程的话,那么这个线程就是进程的主线程。

  但是这个函数并没有进行真正的进程创建工作,真正的工作是PspCreateProcess完成的。但是我找了好久的资料都没发现这个PspCreateProcess函数

存在于那个动态链接库文件中。

【3】

'chapter1_01.exe': Loaded 'C:\Windows\System32\kernel32.dll'

  这一行,表示进程执行过程中,调用了Kernel32.dll文件,在《Windows程序设计》里面,作者将kernel32.dll作为一个子系统来作用,这里我们可以看一下

这个动态链接库文件与其他链接库文件的依存关系:

             

  通过上面的图可以看出:kernel32.dll 调用了ntdll.dll中提供的函数;而在整个dll链中ntdll.dll,我们没有发现其有依存关系(迷惑中....ing)。

而在kernel32.dll中,我们可以看到CreateProcess函数

        

创建进程后,需要初始化内核对象。

【4】

'chapter1_01.exe': Loaded 'C:\Windows\System32\user32.dll'

  当进程内核对象创建完成,并完成初始化。

  进程内核对象初始化完成后,就需要进行一些界面上处理工作了,这个时候就需要注册窗口类了,

  RegisteClass函数是user32.dll提供的系统API函数。注册完就是创建窗口。

  这就是CreateWindow这些函数的事情了,在dll中可以查看

其函数有

  

  这就是我们的CreateWindows函数,创建窗口,很显然这个属于用户界面的范畴。

  创建完窗口,就是显示和更新窗口,这个也是属于用户界面的范畴。

  最终进入消息循环队列,这个还是属于user32.dll动态链接库的范畴,由用户子系统来处理消息。

 

  大体就是这么一个过程,可以发现执行一个Windows程序,系统需要做的工作非常之多。

凌晨0点了,累了,有机会再说吧。

转载地址:http://skxva.baihongyu.com/

你可能感兴趣的文章
收费视频网站Netflix:用户到底想要“点”什么?
查看>>
MacOS High Sierra 12 13系统转dmg格式
查看>>
关于再次查看已做的多选题状态逻辑问题
查看>>
动态下拉菜单,非hover
查看>>
政府安全资讯精选 2017年第十六期 工信部发布关于规范互联网信息服务使用域名的通知;俄罗斯拟建立备用DNS;Google打击安卓应用在未经同意情况下收集个人信...
查看>>
简单易懂的谈谈 javascript 中的继承
查看>>
iOS汇编基础(四)指针和macho文件
查看>>
Laravel 技巧锦集
查看>>
Android 使用 ViewPager+RecyclerView+SmartRefreshLayout 实现顶部图片下拉视差效果
查看>>
Flutter之基础Widget
查看>>
写给0-3岁产品经理的12封信(第08篇)——产品运营能力
查看>>
ArcGIS Engine 符号自动化配置工具实现
查看>>
小程序 · 跳转带参数写法,兼容url的出错
查看>>
flutter error
查看>>
Flask框架从入门到精通之模型数据库配置(十一)
查看>>
10年重新出发
查看>>
2019年-年终总结
查看>>
聊聊elasticsearch的RoutingService
查看>>
让人抓头的Java并发(一) 轻松认识多线程
查看>>
从源码剖析useState的执行过程
查看>>