• 【收集】启动函数


    在编写Win32应用程序时,都必须在源码里实现一个WinMain函数。但Windows程序执行并不是从WinMain函数开始的,首先被执行的是启动函数相关代码,这段代码是编译器生成的。启动代码完成初始化进程,再调用WinMain函数。

    对于Visual C++程序来说,它调用的是C/C++运行时启动函数,该函数负责对C/C++运行库进行初始化。Visual C++配有C运行库的源代码,可以在crtsrccrt0.c文件中找到启动函数的源代码(安装时Visual C++必须选取安装源代码选项);而用于控制台程序的启动代码存放在crtsrcwincmdln.c文件中。

    所有的C/C++运行时启动函数的作用基本都是相同的:检索指向新进程的命令行指针,检索指向新进程的环境变量指针,全局变量初始化,内存堆栈初始化等。当所有的初始化操作完毕后,启动函数就调用应用程序的进入点函数。调用WinMain函数如下所示:

    1
    2
    3
    <span style="font-size: 13.86px;">GetStartupInfo (&StartupInfo);
    Int nMainRetVal = WinMain(GetModuleHandle(NULL),NULL,pszCommandLineAnsi,(StartupInfo.dwFlags&STARTF_USESHOWWINDOW)?StartupInfo.wShowWindow:SW__SHOWDEFAULT);
    </span>

     

    当进入点返回时,启动函数便调用C运行库的exit函数,将返回值(nMainRetVal)传递给它,进行一些必要处理,最后调用系统函数ExitProcess退出。
    下面是一个Visual C++编译的程序,程序启动代码的汇编代码如下: 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <span style="font-size: 13.86px;">00401180      push ebp
    00401181    mov ebp, esp
    00401183    push FFFFFFFF
    00401185    push 004040D0
    0040118A    push 00401CB4
    0040118F    mov      eax, dword ptr fs:[00000000]
    00401195    push eax
    00401196    mov  dword ptr fs:[00000000], esp
    0040119D      sub  esp, 00000058
    004011A0    push ebx
    004011A1    push esi
    004011A2    push edi
    004011A3    mov dword ptr [ebp-18], esp
    004011A6    Call KERNEL32.GetVersion            ; 确定Windows系统版本
    ……  
    004011F4    Call KERNEL32.GetCommandLineA       ; 指向进程的完整命令行的指针
    …… 
    0040121E    push eax
    0040121F    Call KERNEL32.GetStartupInfoA   ; 获取一个进程的启动信息
    ……  
    00401241    push esi
    00401242    Call KERNEL32.GetModuleHandleA  ; 返回进程地址空间执行文件基地址
    00401248    push eax
    00401249    call 00401000                   ; 调用用户编写的进入点函数WinMain
                                                ; 分析程序时,直接跳到401000即可
    0040124E    mov dword ptr [ebp-60], eax
    00401251    push eax
    00401252    call 004012EC                   ; 退出程序
    …… 
    0040126A    ret
    </span>

     

  • 相关阅读:
    android studio导出apk
    Android开发入门经典实例
    L1-Day32
    L1-Day33
    L1-Day30
    Oracle中的null与空字符串''的区别
    Oracle中的job(定时任务)
    Oracle中的加解密函数
    LeetCode33题——搜索旋转排序数组
    Oracle中的DBMS_LOCK包的使用
  • 原文地址:https://www.cnblogs.com/blck/p/8970447.html
Copyright © 2020-2023  润新知