当前位置: 首页 > news >正文

关于旅游的网站建设目的惠州网站建设效果

关于旅游的网站建设目的,惠州网站建设效果,产品广告设计图片,中山商城网站建设一种User Mode下访问物理内存及Kernel Space的实现 一#xff0e;背景 WinCE发展到6.0之后#xff0c;内存结构和管理方法进行了完善。对应用程序影响比较大的有Virtual Memory Layout的变化#xff0c;如每个进程的虚拟内存空间扩展为2GB。对驱动程序影响比较大的有Pointe…一种User Mode下访问物理内存及Kernel Space的实现 一背景 WinCE发展到6.0之后内存结构和管理方法进行了完善。对应用程序影响比较大的有Virtual Memory Layout的变化如每个进程的虚拟内存空间扩展为2GB。对驱动程序影响比较大的有Pointer和Share Memory这一点在Driver与OS接口部分对指针和内存的保护方法中可以看到。对OAL影响比较大的有系统Boot Process的改变。 另外6.0上废除了Full Kernel Mode的不合理设计将Kernel Mode和User Mode进行了细分。由此带来了本文中要讨论的问题就是如何在User Mode下操作Kernel Mode下的内存空间。 大家一定想到了简单的在User Mode下访问Kernel Mode下才有权限访问的内存肯定是行不通可以间接的通过Kernel下的Driver或者其它与Kernel中的代码进行通信的方法来访问。 本文先讨论一下第一种方法实现中要解决的问题最后会将主要代码实现粘贴出来。 二需要解决的几个问题 前面已经提到主要的实现思路需要解决的问题是如何加载该驱动以及如何保证Driver运行在Kernel Mode下以及如何将Driver和Exe组合到一起。 1用户模式下Driver的加载 为了方便实现User Mode下Driver的动态加载将这支在User Mode和Kernel Mode下做转换的Driver做成流驱动。 User Mode下加载Driver只需两个步骤首先将Driver拷贝到对象存储下的Windows目录下然后调用Device Manager的API ActivateDevice()来实现动态的加载。 函数ActivateDevice()的使用非常简单其声明如下 This function loads a device driver. For additional functionality, use the ActivateDeviceEx function. HANDLE ActivateDevice(   LPCWSTR lpszDevKey,   DWORD dwClientInfo ); Parameters lpszDevKey [in] Pointer to a string that identifies the location under the HKEY_LOCAL_MACHINE registry subtree where the Driver registry subkey for the device resides. A driver registry subkey contains the dynamic-link library (DLL) name, device prefix, friendly name, and other device information. dwClientInfo [in] Data to store in the Active registry subkey for the device in the ClientInfo registry entry. The registry path to the Active registry subkey for the device is passed in as the context parameter to the devices XXX_Init (Device Manager) function. After the value in dwClientInfo is stored in the registry under HKEY_LOCAL_MACHINE/Drivers/Active, the Device Manager calls XXX_Init. Devload.h defines DEVLOAD_CLIENTINFO_VALNAME and DEVLOAD_CLIENTINFO_VALTYPE to facilitate access to the ClientInfo key. 可以看到第一个参数用来指定Driver的注册表路径而第二个参数用来写入到Active Key下如果不需要写入的话可以置为NULL。  2如何保证加载的Driver处于Kernel Mode下 6.0下引入了Group的概念通过注册表可以去定义一个Group一个简单的Group定义如下 [HKEY_LOCAL_MACHINE/Drivers/ProcGroup_0002]     ProcNameservicesd.exe     ProcVolPrefix$services     ProcTimeoutdword:20000   [HKEY_LOCAL_MACHINE/Drivers/ProcGroup_0003]     ProcNameudevice.exe     ProcVolPrefix$udevice 其实简单点理解Group就是将Driver的加载方式进行细分方便不同的Driver使用不同的系统组件进行加载。 Driver的注册表项可以用来指定加载自己的Group如下 [HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Ethman] PrefixETM Dllethman.dll Indexdword:1 ; WZCSVC must be started before ethman Orderdword:2A ; Flags12 is DEVFLAGS_LOADLIBRARY and DEVFLAGS_LOAD_AS_USERPROC Flagsdword:12 UserProcGroupdword:3 ; // default to group 3   [HKEY_LOCAL_MACHINE/Drivers/BuiltIn/SIP] PrefixSIP Dllsoftkb.DLL Orderdword:1 Indexdword:0 ;Flags10 is DEVFLAGS_LOAD_AS_USERPROC Flagsdword:10 UserProcGroupdword:3 ; // default to group 3 对于指定通过某个Group进行加载的Driver系统中进行加载的时候会引入Reflect机制。该机制主要用来对检察注册表项中的IoLen和IoBase值当检察到Driver中访问了不在IoLen和IoBase指定区域的物理内存时将会出现系统异常。 对于那些没有指定使用Group进行加载的驱动WinCE6.0中将其加载到Kernel Mode下。也就是说它们具有了访问整个4GB空间的权限。 要保证User Mode下加载的Driver处于Kernel Mode只需要在注册表中不去指定User Group就可以了。     3如何将Driver DLL和Exe 做成一个文件 之所以将Driver和EXE组合成一个文件是为了用户使用的方便。想象一下如果不把两者做成一个文件的话一个简单的访问物理内存的应用程序就变成了两个文件那是多么不美观的事情。 其实实现将Driver DLL和EXE做成一个文件有两个方法。方法一由于DLL和EXE都是PE结构的可以使用网上的加壳工具将其组合成一个PE文件而在运行的时候自动去壳即可。方法二将DLL中的信息提取出来放到EXE的Data Section然后在运行的时候将这些数据重新组合成一个DLL。 这里我采用了第二种方法来实现组合Driver和EXE文件。 三代码实现 1将Driver注册表的操作简化 操作过CE下注册表的兄弟们都知道微软设计的注册表非常简单可是操作API实在是不那么友好。 我这里使用了PB6.0源文件PUBLIC/WCESHELLFE/OAK/CTLPNL/CPLMAIN/cplmacro.h中的类CReg来实现对Driver注册表项的读写动作。 该注册表类主要封装了注册表的Open/Read/Write API为用户提供了一种更加友好的注册表操作接口。 该类的定义和实现如下 class CReg { private:      HKEY m_hKey;      int      m_Index;      LPBYTE   m_lpbValue; // last value read, if any   public:      BOOL Create(HKEY hkRoot, LPCTSTR pszKey) {          DWORD dwDisp;          return ERROR_SUCCESSRegCreateKeyEx(hkRoot, pszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, m_hKey, dwDisp);      }        BOOL Open(HKEY hkRoot, LPCTSTR pszKey, REGSAM samKEY_READ) {          return ERROR_SUCCESSRegOpenKeyEx(hkRoot, pszKey, 0, sam, m_hKey);      }        CReg(HKEY hkRoot, LPCTSTR pszKey) {          m_hKey NULL;          m_Index 0;          m_lpbValue NULL;          Open(hkRoot, pszKey);      }        CReg() {          m_hKey NULL;          m_Index 0;          m_lpbValue NULL;      }        ~CReg() {          if(m_hKey) RegCloseKey(m_hKey);          MyFree(m_lpbValue);      }        void Reset() {          if(m_hKey) RegCloseKey(m_hKey);          MyFree(m_lpbValue);          m_hKey NULL;          m_Index 0;          m_lpbValue NULL;      }        operator HKEY() { return m_hKey; }        BOOL IsOK(void) { return m_hKey!NULL; }          BOOL EnumKey(LPTSTR psz, DWORD dwLen) {          if(!m_hKey) return FALSE;          return ERROR_SUCCESSRegEnumKeyEx(m_hKey, m_Index, psz, dwLen, NULL, NULL, NULL, NULL);      }        BOOL EnumValue(LPTSTR pszName, DWORD dwLenName, LPTSTR pszValue, DWORD dwLenValue) {          DWORD dwType;          if(!m_hKey) return FALSE;          dwLenValue * sizeof(TCHAR); // convert length in chars to bytes          return ERROR_SUCCESSRegEnumValue(m_hKey, m_Index, pszName, dwLenName, NULL, dwType, (LPBYTE)pszValue, dwLenValue);      }        BOOL ValueSZ(LPCTSTR szName, LPTSTR szValue, DWORD dwLen) {          if(!m_hKey) return FALSE;          dwLen * sizeof(TCHAR); // convert length in chars to bytes          return ERROR_SUCCESSRegQueryValueEx(m_hKey, szName, NULL, NULL, (LPBYTE)szValue, dwLen);      }        DWORD ValueBinary(LPCTSTR szName, LPBYTE lpbValue, DWORD dwLen) {          if(!m_hKey) return FALSE;          DWORD dwLenWant dwLen;          if(ERROR_SUCCESSRegQueryValueEx(m_hKey, szName, NULL, NULL, lpbValue, dwLen))               return dwLen;          else               return 0;      }        LPCTSTR ValueSZ(LPCTSTR szName);        LPBYTE ValueBinary(LPCTSTR szName) {          return (LPBYTE)ValueSZ(szName);      }        DWORD ValueDW(LPCTSTR szName, DWORD dwDefault0) {          if(!m_hKey) return FALSE;          DWORD dwValue dwDefault;          DWORD dwLen sizeof(DWORD);          RegQueryValueEx(m_hKey, szName, NULL, NULL, (LPBYTE)dwValue, dwLen);          return dwValue;      }        BOOL SetSZ(LPCTSTR szName, LPCTSTR szValue, DWORD dwLen) {          //Prefix          if(!m_hKey) return FALSE;          //          return ERROR_SUCCESSRegSetValueEx(m_hKey, szName, 0, REG_SZ, (LPBYTE)szValue, sizeof(TCHAR)*dwLen);      }        BOOL SetSZ(LPCTSTR szName, LPCTSTR szValue) {          return SetSZ(szName, szValue, 1lstrlen(szValue));      }        BOOL SetDW(LPCTSTR szName, DWORD dwValue) {          //Prefix          if(!m_hKey) return FALSE;          //          return ERROR_SUCCESSRegSetValueEx(m_hKey, szName, 0, REG_DWORD, (LPBYTE)dwValue, sizeof(DWORD));      }        BOOL SetBinary(LPCTSTR szName, LPBYTE lpbValue, DWORD dwLen) {          //Prefix          if(!m_hKey) return FALSE;          //          return ERROR_SUCCESSRegSetValueEx(m_hKey, szName, 0, REG_BINARY, lpbValue, dwLen);      }        BOOL SetMultiSZ(LPCTSTR szName, LPCTSTR lpszValue, DWORD dwLen) {          return ERROR_SUCCESSRegSetValueEx(m_hKey, szName, 0, REG_MULTI_SZ, (LPBYTE)lpszValue, sizeof(TCHAR)*dwLen);      }        BOOL DeleteValue(LPCTSTR szName) {          //Prefix          if(!m_hKey) return FALSE;          //          return ERROR_SUCCESSRegDeleteValue(m_hKey, szName);      }        BOOL DeleteKey(LPCTSTR szName) {          if(!m_hKey) return FALSE;          return ERROR_SUCCESSRegDeleteKey(m_hKey, szName);      } }; 具体的使用方法可参照后面代码中LoadMemDrv()的实现。 2Driver和DLL合并与解压 合并方法很简单。首先我将DLL中的每个字节的数据提取出来组合成一个数组然后在AP中引用该数组。 解压的时候直接将该数组组合成Driver的DLL就行了如下 // 从静态变量区提取MEM_DRV_NAME驱动的内容并将其组合成为一个Driver的dll {      HANDLE   hTempFile INVALID_HANDLE_VALUE;      DWORD    dwBytesReturned 0;      TCHAR    szFileName[MAX_PATH/2] {0,};        wsprintf(szFileName, L%s%s, TEXT(//), MEM_DRV_NAME);        hTempFile CreateFile(          szFileName,          GENERIC_READ|GENERIC_WRITE,          FILE_SHARE_WRITE|FILE_SHARE_READ,          NULL,          CREATE_ALWAYS,          FILE_ATTRIBUTE_NORMAL,          NULL          );        if (INVALID_HANDLE_VALUE hTempFile)      {          LogMessage(TEXT([ERR] Faild to create file. File name %s), szFileName);      }      else      {                      // DllFile就是DLL变量数组的名字          // 这里将DLL的内容写入到前面创建的文件LMyMemoryDrv.dll中          if (!WriteFile(hTempFile, DllFile, sizeof(DllFile), dwBytesReturned, NULL))          {               LogMessage(TEXT([ERR] Faild to write file.  Error code 0x%x), GetLastError());          }          else          {                                LogMessage(TEXT(Create driver %s successfully), szFileName);          }            CloseHandle(hTempFile);                   DeleteFile(MEM_DRV_DST_PATH);            //if (!CopyFile(szFileName, L//me.dat, 0))          if (!CopyFile(szFileName, MEM_DRV_DST_PATH, FALSE))          {               LogMessage(L[ERR] Copy memory driver from %s to %s failed, Error code 0x%x!, szFileName, MEM_DRV_DST_PATH, GetLastError());          }      }        } 3Driver的实现 由于该Driver的功能仅仅是在User Mode和Kernel Mode下的内存之间做转换所以只需要简单的实现一下DeviceIoControl就可以了其它的流接口除了Open和Init直接为空就行了。 如下 /* * make use of MEM_IOControl to control memory address space conversion * Para: *    pInBuf:       physical or virtual memory address *    nInBufSize:   4 *    pOutBuf:      user buffer used to store data *    nOutBufSize:  size of data the user wanted in bytes [note********************] */ DWORD MEM_IOControl(DWORD Handle, DWORD dwIoControlCode, PBYTE pInBuf,                        DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned) {      DWORD bRetVal ERROR_SUCCESS;      PBYTE pMemBuffer NULL;           NKDbgPrintfW(LMEM_IOControl(). Handle 0x%x, Code 0x%x, pInBuf 0x%8x, InSize 0x%x, OutSize 0x%x/r/n, Handle, dwIoControlCode, *(DWORD *)pInBuf, nInBufSize, nOutBufSize);          switch(dwIoControlCode) {      case IOCTL_MEM_GET_PHYSICAL_RAM:          NKDbgPrintfW(TEXT(IOCTL_MEM_GET_PHYSICAL_RAM/r/n));          break;      case IOCTL_MEM_GET_VIRTUAL_RAM:          NKDbgPrintfW(TEXT(IOCTL_MEM_GET_VIRTUAL_RAM/r/n));          break;      default:          NKDbgPrintfW(TEXT(**UNKNOWN**/r/n));          break;     }               switch(dwIoControlCode) {      case IOCTL_MEM_GET_PHYSICAL_RAM:          {                           do               {                                     if (pInBuf NULL || nInBufSize ! sizeof(DWORD) || pOutBuf NULL || nOutBufSize 0)                    {                                               NKDbgPrintfW((_T(MEM_IOControl: IOCTL_MEM_GET_PHYSICAL_RAM - invalid paramter/n/r)));                        bRetVal ERROR_INVALID_PARAMETER;                        break;                    }                                       pMemBuffer (PBYTE)VirtualAlloc(NULL, nOutBufSize, MEM_RESERVE, PAGE_NOACCESS);                                       if (NULL ! pMemBuffer)                    {                                               if (!VirtualCopy((void *)pMemBuffer, (void *)((*(DWORD *)pInBuf)8), nOutBufSize, PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL))                        {                             NKDbgPrintfW((_T([MEMDRV] MEM_IOControl() : pMemBuffer VirtualCopy() Failed /n/r)));                             bRetVal ERROR_INVALID_PARAMETER;                        }                        else                        {                                                         __try                             {                                     NKDbgPrintfW(LPhysical Add: 0x%8x, Virtual Add: 0x%8x/r/n, *(DWORD *)pInBuf, *(DWORD*)pMemBuffer);                                  memcpy(pOutBuf, pMemBuffer, nOutBufSize);                             }                             __except(EXCEPTION_EXECUTE_HANDLER)                             {                                  NKDbgPrintfW((L[ERR] Throw out exception in MEMDRV: MEM_IOControl()));                                  bRetVal ERROR_INVALID_PARAMETER;                             }                        }                                               VirtualFree(pMemBuffer, 0, MEM_RELEASE);                    }                       else                    {                        NKDbgPrintfW((_T([MEMDRV] MEM_IOControl() : pMemBuffer VirtualCopy() Failed /n/r)));                        bRetVal ERROR_INVALID_PARAMETER;                                         }               }               while(0);                                 }          break;      case IOCTL_MEM_GET_VIRTUAL_RAM:          {                           NKDbgPrintfW(TEXT(IOCTL_MEM_GET_VIRTUAL_RAM/r/n));               __try               {                       // copy data from pInBuf to pOutBuf                    memcpy(pOutBuf, pInBuf, nOutBufSize);                  }               __except(EXCEPTION_EXECUTE_HANDLER)               {                    NKDbgPrintfW((L[ERR] Throw out exception in MEMDRV: MEM_IOControl()));                    bRetVal ERROR_INVALID_PARAMETER;               }          }          break;      default:          NKDbgPrintfW(TEXT(**UNKNOWN**/r/n));          bRetVal ERROR_INVALID_PARAMETER;          break;     }           return (ERROR_SUCCESS bRetVal); } 4Driver的加载     Driver的加载包括两个过程。首先将Driver相关的注册表项写入到注册表中然后调用API ActivateDevice()来实现动态的加载。 代码如下 /*   [HKEY_LOCAL_MACHINE/Drivers/BuiltIn/MEM] DllMyMemoryDrv.dll PrefixMEM Indexdword:1 Orderdword:0 FriendlyNameMEM driver   */ #define MEM_DRV_NAME             LMEM1: bool  LoadMemDrv(void) {      BOOL bRetVal false;        // Step1: modify the registry      class CReg MemDrvReg;        bRetVal MemDrvReg.Create(HKEY_LOCAL_MACHINE, MEM_DRV_PATH);      bRetVal MemDrvReg.SetSZ(LDll, LMyMemoryDrv.dll);//, sizeof(LMyMemoryDrv.dll)/sizeof(TCHAR));      MemDrvReg.SetSZ(LPrefix, LMEM);//, sizeof(LMEM)/sizeof(TCHAR));      MemDrvReg.SetDW(LOrder, 0);      MemDrvReg.SetDW(LIndex, 1);      MemDrvReg.SetDW(LIndex, 1);      MemDrvReg.SetSZ(LFriendlyName, LMEM driver);//, sizeof(LMEM driver)/sizeof(TCHAR));        // Step2: load driver unsing device manager      hActiveMemDrv INVALID_HANDLE_VALUE;        hActiveMemDrv ActivateDevice(MEM_DRV_PATH, 0);      if (INVALID_HANDLE_VALUE hActiveMemDrv)      {          LogMessage(L[ERR]Load driver %s failed, MEM_DRV_FULL_PATH);          goto EXIT;      }        // Step3: Open stream driver          hFile INVALID_HANDLE_VALUE;      hFile CreateFile(MEM_DRV_NAME,          GENERIC_READ|GENERIC_WRITE,          0,          NULL,          OPEN_EXISTING,          FILE_ATTRIBUTE_NORMAL,          NULL);           if (INVALID_HANDLE_VALUE hFile)      {          LogMessage(L[ERR] Open stream driver %s failed. Error code 0x%8x, MEM_DRV_NAME, GetLastError());          goto EXIT;      }        bIsDrvLoad true;      bRetVal TRUE;   EXIT:         return (bRetVal TRUE); } 附 具体的实现代码可以到我的资源中下载。
http://www.yutouwan.com/news/459686/

相关文章:

  • 做调查问卷网站设计招聘网站
  • 为了同学都能访问网站如何做wordpress建手机站教程
  • 网站开发需要用到什么技术wordpress meta_key
  • h5免费制作网站模板犀浦网站建设
  • 南宁做网站建设网页升级紧急通知页面
  • 英语网站online织梦门户网站
  • 东莞做网站还赚钱吗百度云网盘资源搜索引擎入口
  • 如何做网站网站代理八戒设计网
  • 自适应型网站建设报价h5如何做多页面网站
  • 网站后台管理模板psd广州网络运营课程培训班
  • 建设网站需要的资质证书网站制作自己接单
  • 做考勤的网站品牌网站建设只詢大蝌蚪
  • 门户网站建设的背景有哪些网站做的比较好
  • 注册网站给谁交钱历史网站怎么做
  • 网站定制 天津最新新闻消息事件
  • 网站维护哪些网络服务器是指什么
  • 外包公司做网站图片哪里整的在百度上做购物网站
  • 怎样在局域网做网站seo优化销售
  • 网站推广和宣传的方法莱芜口镇规划
  • 温州建网站公司哪家好贵州省水利建设项目公示网站
  • 智能写作网站网站策划书10个点怎么写
  • 网站如何做美工四川网站建设设计公司
  • 保定建设厅网站代码素材网站哪个好
  • 定制企业网站开发公司wordpress定时备份
  • 微信支付 企业网站建站素材网站模板
  • html写手机网站吗做个企业网网站怎么做
  • 昆明网站建设公司排名天津建设工程信息网专家登录
  • 常熟市住房和城乡建设部网站语文建设编辑部官方网站
  • 专业网站优化电话上海网站制作网站
  • 如何查网站点击量战鼓的h5网站如何做