Inv*_*ion 9 windows x86 assembly portable-executable
Windows必须做一些事情来解析PE头,在内存中加载可执行文件,并将命令行参数传递给main().
使用OllyDbg我已将调试器设置为在main()上中断,以便我可以查看调用堆栈:

好像符号缺失所以我们无法获得函数名称,只能看到它的内存地址.但是我们可以看到main的调用者kernel32.767262C4,也就是被调用者ntdll.77A90FD9.在堆栈的底部,我们看到RETURN ntdll.77A90FA4,我认为它是第一个被调用来运行可执行文件的函数.看起来传递给该函数的值得注意的参数是Windows的结构化异常处理程序地址和可执行文件的入口点.
那么这些函数究竟是如何最终将程序加载到内存中并为入口点执行做好准备呢?调试器之前main()是否显示了OS执行的整个过程?
RbM*_*bMm 10
如果你在CreateProcess内部调用系统调用ZwCreateThread[Ex]来创建进程中的第一个线程
当你创建线程 - 你(如果直接调用ZwCreateThread)或系统初始化CONTEXT新线程的记录 - 这里Eip(i386)或线程Rip(amd64)的入口点.如果你这样做 - 你可以指定任何地址.但是当你打电话说Create[Remote]Thread[Ex]- 我怎么说 - 系统填充CONTEXT并将自编程设置为线程入口点.您的原始入口点已保存Eax(i386)或Rcx(amd64)注册.
此例程的名称取决于Windows版本.
早期这是BaseThreadStartThunk或BaseProcessStartThunk(从CreateProcess被召唤的话)来自kernel32.dll.
但现在系统指定RtlUserThreadStart来自ntdll.dll.在RtlUserThreadStart通常所说BaseThreadInitThunk的kernel32.dll(除了本地(启动执行)的应用,如smss.exe和chkdsk.exe这有没有kernel32.dll自我的地址空间的话).BaseThreadInitThunk已调用原始线程入口点,并在(if)之后返回 - RtlExitUserThread调用.
这个常见的线程启动包装器的主要目标 - 设置顶级SEH过滤器.只因为这个我们可以调用SetUnhandledExceptionFilter函数.如果线程从您的入口点直接开始,没有包装器 - 顶级异常过滤器的功能变得不可用.
但无论线程的入口点-线程在用户空间- NEVER开始从该点执行!
用户模式线程开始执行时的早期 - 系统插入APC到带有LdrInitializeThunkApc例程的线程- 这是通过复制(保存)线程CONTEXT到用户堆栈然后调用KiUserApcDispatcher哪个调用来完成的LdrInitializeThunk.当LdrInitializeThunk完成了-我们回到KiUserApcDispatcher呼吁NtContinue与保存线程CONTEXT-这已经线程的入口点开始执行之后.
但是现在系统在这个过程中做了一些优化 - 它将线程复制(保存)CONTEXT到用户堆栈并直接调用LdrInitializeThunk.在这个函数的末尾NtContinue调用 - 和正在执行的线程入口点.
所以每个线程都从用户模式开始执行LdrInitializeThunk.(具有确切名称的此函数存在并在从nt4到win10的所有Windows版本中调用)
这个功能是做什么的?这是什么?你可能会听到DLL_THREAD_ATTACH通知吗?当进程中的新线程开始执行时(例如特殊系统工作线程除外LdrpWorkCallback) - 他按加载的DLL列表行走,并通知DLL调用DLL入口点DLL_THREAD_ATTACH(当然,如果DLL有入口点而DisableThreadLibraryCalls没有调用此DLL).但是这是如何实现的?感谢LdrInitializeThunk哪个调用LdrpInitialize- > LdrpInitializeThread- > LdrpCallInitRoutine(对于DLLs EP)
当进程中的第一个线程开始时 - 这是特例.需要为流程初始化做许多额外的工作.此时只有两个模块加载进程 - EXE和ntdll.dll.LdrInitializeThunk
呼吁LdrpInitializeProcess这份工作.如果非常简短:
LdrpDoDebuggerBreak- 这个函数看起来 - 调试器附加到进程,如果是 - int 3调用 - 所以调试器接收异常消息STATUS_BREAKPOINT- 大多数调试器只能从这一点开始UI调试.但是存在调试器,它允许调试过程LdrInitializeThunk- 来自这种调试器的所有屏幕截图ntdll.dll(可能来自kernel32.dll) - 来自另一个DLL的代码,任何尚未在进程中执行的第三方代码.DLL_PROCESS_DETACH调用TLS初始化和TLS回调(如果存在)
ZwTestAlert被调用 - 这个调用检查在线程队列中存在APC,并执行它.这一点存在于从NT4到win 10的所有版本中.例如,创建进程处于挂起状态,然后将APC call(QueueUserAPC)插入到thread(PROCESS_INFORMATION.hThread)中 - 结果,此调用将在进程完全初始化后执行,所有
DLL_PROCESS_DETACH调用,但在EXE入口点之前.在第一个进程线程的上下文中.
另请阅读CreateProcess的流程
| 归档时间: |
|
| 查看次数: |
2363 次 |
| 最近记录: |