zoukankan      html  css  js  c++  java
  • 《Windows核心编程》学习笔记(3)– 程序入口函数

    1 进程实例句柄

    加载到进程地址空间的每一个可执行文件或者dll文件都被赋予了一个独一无二的实例句柄.

    他实际上是一个内存基地址,系统将可执行程序的映像加载到进程地址空间中的这个位置。

    Ps :

    HMODULE HINSTANCE

    其实就是一回事.

     

    获得一个可执行文件或者dll文件的句柄/基地址:

    1GetModuleHandle函数

    HMODULE GetModuleHandle( LPCTSTR lpModuleName );

    调用这个函数时,参数指定了已在主调进程的地址空间中加载的一个可执行文件或者DLL文件的名称。或者参数为NULL时,会返回主调函数的可执行文件的基地址

     

    (2)GetModuleHandleEx 函数

            BOOL WINAPI GetModuleHandleEx(

            __in          DWORD dwFlags,

            __in          LPCTSTR lpModuleName,

            __out         HMODULE* phModule

            );

    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS作为他的第一个参数,将当前函数的地址作为第二个参数,最后一个参数是一个指向HMODULE的指针,GetModuleHandleEx函数会用传入函数(既第二个参数)所在DLL的基地址来填写该指针.

     

    3)利用链接器提供的为变量__ImageBase,他指向当前正在运行的模块的基地址.

    例如:

    #include<windows.h>

    #include<tchar.h>

    #include<stdio.h>

    extern "C" const IMAGE_DOS_HEADER  __ImageBase;

    void DumpModule()

    {

           HMODULE hModule = GetModuleHandle( NULL );

           _tprintf( TEXT( "with GetModuleHandle(NULL) = 0x%x\r\n" ),hModule );

     

           _tprintf( TEXT( "with __ImageBase = 0x%x\r\n" ),( HINSTANCE )&__ImageBase );

     

           hModule = NULL;

           GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,

                  (PCTSTR)DumpModule,

                  &hModule);

           printf("with GetModuleHandleEx = 0x%x\r\n", hModule);

    }

    int main( int argc, char* argv[] )

    {

           DumpModule();

           system("pause");

           return 0;

    }

    ps:当调用GetModuleHandle函数,并向其传递NULL值,会返回进程的地址空间中的可执行文件的基地址。所以,即使调用GetModuleHandleNULL)的代码是一个DLL文件中,返回值仍是可执行文件的基地址,而非DLL文件的基地址。

     

    2.进程前一个实例的句柄

    该参数用于16Windows系统,仍然将其保留为WinMain的一个参数,目的只是方便我们移植到16Windows应用程序.

     

    3.进程的环境变量  

    每个进程都有一个与它关联的环境块(environment block,这是在进程地址空间内分配的一个 内存块,其中包含和下面相似的一组字符串: (可以使用GetEnvironmentStrings函数获得)

    =::=::\ ... 

    VarName1=VarValue1\0 

    VarName2=VarValue2\0 

    VarName3=VarValue3\0 ... 

    VarNameX=VarValueX\0 

    \0 

    (1)可以使用

    GetEnvironmentVariable 函数来判断一个环境变量是否存在;如果存在,它的值是什么。如下 

    所示: 

    DWORD GetEnvironmentVariable( 

       PCTSTR pszName, 

       PTSTR pszValue, 

       DWORD cchValue); 

    调用GetEnvironmentVariable时,pszName指向预期的变量名称,pszValue指向保存变量值的缓冲区,而 cchValue指出缓冲区大小(用字符数来表示)。如果在环境中找到变量名,GetEnvironmentVariable函数将返回复制到缓冲区的字符数;如果在环境中没有找到变量名, 就返回0。然而,由于我们不知道为了保存一个环境变量的值需要多少个字符,所以当0值被当 cchValue参数的值传入时,GetEnvironmentVariable会返回包括末尾的NULL字符在内的字符的数量。以下代码演示了如何安全地使用这个函数: 

    void PrintEnvironmentVariable(PCTSTR pszVariableName) { 

       PTSTR pszValue = NULL; 

       // 先获得环境变量中的字符数

      DWORD dwResult = GetEnvironmentVariable(pszVariableName, pszValue, 0); 

       if (dwResult != 0) { 

         // 为环境变量分配足够的内存,并获得环境变量的值

         DWORD size = dwResult * sizeof(TCHAR); 

         pszValue = (PTSTR)malloc(size); 

         GetEnvironmentVariable(pszVariableName, pszValue, size); 

         _tprintf(TEXT("%s=%s\n"), pszVariableName, pszValue); 

         free(pszValue); 

       } else { 

         _tprintf(TEXT("'%s'=<unknown value>\n"), pszVariableName); 

       } 

     

    (2)可以使用 ExpandEnvironmentStrings 函数来展开一个环境变量 ,: %USERPROFILE%\Documents   在我的机器上

    USERPROFILE环境变量值为C:\Users\mzf,因此替换后的字符串为:

    C:\Users\mzf

    \Documents

    DWORD ExpandEnvironmentStrings

       PTCSTR pszSrc, 

       PTSTR pszDst, 

      DWORD chSize); 

    调用这个函数时,pszSrc参数是包含可替换环境变量字符串的一个字符串的地址。pszDst 参数是用于接收扩展字符串的一个缓冲区的地址,而chSize参数是这个缓冲区的最大大小(用字符数来表示)。返回值是保存扩展字符串所需的缓冲区的大小(用字符数来表示)。如果chSize 参数小于此值,%%变量就不会扩展,而是被空字符串替换。所以,通常要调用两次 ExpandEnvironmentStrings 函数,如下所示: 

    DWORD chValue = 

      ExpandEnvironmentStrings(TEXT("PATH='%PATH%'"), NULL, 0); 

    PTSTR pszBuffer = new TCHAR[chValue]; 

    chValue = ExpandEnvironmentStrings(TEXT("PATH='%PATH%'"), pszBuffer, chValue); 

    _tprintf(TEXT("%s\r\n"), pszBuffer); 

    delete[] pszBuffer; 

     

    (3)使用SetEnvironmentVariable函数添加一个变量,删除一个变量,或者修改一个变 

    量的值: 

    BOOL SetEnvironmentVariable( 

       PCTSTR pszName, 

       PCTSTR pszValue); 

     

    此函数将pszName所标识的一个变量设为pszValue参数所标识的值。如果已经存在具有指定名称的一个变量,SetEnvironmentVariable函数会修改它的值。如果指定的变量不存在,就添加这个变量。如果pszValueNULL,变量会从环境块中删除.

  • 相关阅读:
    centos7.6 使用yum安装mysql5.7
    解决hadoop本地库问题
    docker-compose 启动警告
    docker 安装zabbix5.0 界面乱码问题解决
    docker 部署zabbix问题
    zookeeper 超时问题
    hbase regionserver异常宕机
    (转载)hadoop 滚动升级
    hadoop Requested data length 86483783 is longer than maximum configured RPC length
    zkfc 异常退出问题,报错Received stat error from Zookeeper. code:CONNECTIONLOSS
  • 原文地址:https://www.cnblogs.com/forlina/p/2131105.html
Copyright © 2011-2022 走看看