熱點推薦:
您现在的位置: 電腦知識網 >> 操作系統 >> Windows優化 >> 正文

動態漢化Windows技術的一些簡要分析

2013-11-12 16:46:43  來源: Windows優化 

  四通利方(RichWin)中文之星(CStar)是大家廣為熟知的漢化Windows產品陷阱技術即動態修改Windows代碼一直是其對外宣稱的過人技術本文從Windows的模塊調用機制與重定位概念著手介紹了陷阱技術的實現並給出了采用陷阱技術動態修改Windows代碼的示例源程序
  
  發現了什麼?
  筆者多年來一直從事Windows下的軟件開發工作經歷了Windows 直至Windows NT的成長過程也遍歷了長青窗口長城窗口DBWinCStarRichWin等多個Windows漢化產品從現在看來影響最大也最為成功的當推四通利方的RichWin;此外中文之星CStar與RichWin師出一門其核心技術自然也差不多其對外宣傳采用獨特的陷阱 技術即動態修改Windows代碼一直是筆者感興趣的地方
  
  EXEHDR是Microsoft Visual C++開發工具中很有用的一個程序它可以檢查NE(NewExe cutable)格式文件用它來分析RichWin的WSENGINEDLL或CStar的CHINESEDLL就會發現與眾不同的兩點(以CStar 為例):
  
  C:\CSTAR>exehdr chinesedll /v type offset target BASE  a seg  offset  PTR  e imp GDIGETCHARABCWIDTHS PTR  b imp GDIENUMFONTFAMILIES PTR   imp DISPLAY ( EXTTEXTOUT ) PTR   imp KEYBOARD ( TOASCII ) PTR  ba imp KEYBOARD ( ANSITOOEM ) PTR  c imp KEYBOARD ( OEMTOANSI ) PTR  d imp KEYBOARD( ANSITOOEMBUFF ) PTR  f imp USER  ( LSTRCMP ) PTR  e imp KEYBOARD( OEMTOANSIBUFF ) PTR   imp USER  ( ANSIUPPER ) PTR   imp USER  ( ANSILOWER ) PTR  aa imp GDI   ( CREATEFONT ) PTR  e imp USER  ( ISCHARALPHA ) PTR  b imp GDI   ( CREATEFONTINDIRECT ) PTR  d imp USER  ( ISCHARALPHANUMERIC ) PTR  c imp USER  ( GETSYSTEMMETRICS ) PTR   imp USER  ( ISCHARUPPER ) PTR  f imp USER  ( ISCHARLOWER ) PTR   imp USER  ( ANSIUPPERBUFF ) PTR   imp USER  ( ANSILOWERBUFF ) PTR  c imp GDI   ( DELETEOBJECT ) PTR  c imp GDI   ( ENUMFONTS ) PTR  ab imp KERNELISDBCSLEADBYTE PTR  d imp GDI   ( GETOBJECT ) PTR  d imp KERNEL ( OPENFILE ) PTR   imp GDI   ( GETTEXTEXTENT ) PTR  e imp GDI   ( GETTEXTFACE ) PTR  f imp GDI  ( GETCHARWIDTH ) PTR   imp GDI  ( EXTTEXTOUT ) PTR   imp USER  ( LSTRCMPI ) PTR  f imp USER  ( ANSINEXT ) PTR   imp USER  ( ANSIPREV ) PTR   imp USER  ( GETMESSAGE ) PTR   imp USER  ( PEEKMESSAGE ) relocations
  (括號內為筆者加上的對應Windows API函數)
  第一在數據段中發現了重定位信息
  
  第二這些重定位信息提示的函數全都與文字顯示輸出和鍵盤字符串有關也就是說漢化Windows必須修改這些函數
  
  在這非常特殊的地方隱藏著什麼呢?毋庸置疑這與眾不同的兩點對打開陷阱技術之門而言不是金鑰匙也是敲門磚
  
  Windows的模塊調用機制與重定位概念
  為了深入探究陷阱技術我們先來介紹Windows的模塊調用機制
  
  Windows的運行分實模式標准模式和增強模式三種雖然這幾種模式各不相同但其核心模塊的調用關系卻是完全一致的見圖一
  
  主要的三個模塊有如下的關系:
  
  ·KERNEL是Windows系統內核它不依賴其它模塊
  
  ·GDI是Windows圖形設備接口模塊它依賴於KERNEL模塊
  
  ·USER是Windows用戶接口服務模塊它依賴於KERNELGDI模塊及設備驅動程序等所有模塊
  
  這三個模塊實際上就是Windows的三個動態鏈接庫KERNEL有三種系統存在形式:Kern elexe(實模式)Krnlexe(標准模式)Krnlexe(增強模式);GDI模塊是Gdiex e;USER模塊是Userexe雖然文件名都以EXE為擴展名但它們實際都是動態鏈接庫
  
  同時幾乎所有的API函數都隱藏在這三個模塊中用EXEHDR對這三個模塊分析就可列出一大堆大家所熟悉的Windows API函數
  
  以GDI模塊為例運行結果如下:
  
  C:\WINDOWS\SYSTEM>exehdr gdiexe Exports: rd seg offset name e EXTTEXTOUT exported shared data e CREATEFONT exported shared data
  至此讀者已能從Windows紛繁復雜的系統中理出一些頭續來下面再引入一個重要概念——重定位
  一個Windows執行程序對調用API函數或對其它動態庫的調用在程序裝入內存前都是一些不能定位的動態鏈接;當程序調入內存時這些遠調用都需要重新定位重新定位的依據就是重定位表在Windows執行程序(包括動態庫)的每個段後面通常都跟有這樣一個重定位表重定位包含調用函數所在模塊函數序列號以及定位在模塊中的位置
  
  例如用EXEHDR /v 分析CHINESEDLL得到:
  
   type offset target PTR imp GDI 
  就表明在本段的H偏移處調用了GDI的第號函數如果在H處是:FFFF 表示本段內僅此一處調用了GDI函數;否則表明了本段內還有一處調用此函數調用的位置就是H處所指向的內容實際上重定位表只含有引用位置的鏈表的鏈頭那麼GDI 是一個什麼函數呢?用EXEHDR對GDIEXE作一分析就可得出在GDI的出口(Export)函數中號是ExtTextOut
  這樣我們在EXEHDR這一簡單而非常有用的工具幫助下已經在Windows的浩瀚海洋中暢游了一會下面讓我們繼續深入下去
  
  動態漢化Windows原理
  我們知道傳統的漢化Windows的方法是要直接修改Windows的顯示輸入打印等模塊代碼或用DDK直接開發中文設備驅動模塊這樣不僅工作量大而且系統的完備性很難保證性能上也有很多限制(早期的長青窗口就是如此)所以只有從內核上修改Windows核心代碼才是最徹底的辦法
  
  從Windows的模塊調用機制我們可以看到Windows實際上是由包括在KERNELGDIUS ER等幾個模塊中的眾多函數支撐的那麼修改其中涉及語言文字處理的函數使之能適應中文需要不就能達到漢化目的了嗎?
  
  因而我們可以得出這樣的結論:在自己的模塊中重新編寫涉及文字顯示輸入的多個函數然後將Windows中對這些函數的引用改向到自己的這些模塊中來修改哪些函數才能完成漢化這需要深入分析Windows的內部結構但CHINESEDLL已明確無誤地告訴了我們在其數據段的重定位表中列出的引用函數正是CStar修改了的Windows函數!為了驗證這一思路 我們利用RichWin作一核實
  
  用EXEHDR分析GDIEXE得出ExtTextOut函數在GDI的第一代碼段H偏移處(不同版本的Windows其所在代碼段和偏移可能不一樣)然後用HelpWalk(也是Microsoft Visual C+ +開發工具中的一個)檢查GDI的CodeH處前個字節是 B FF 經過運行Ri chWin for Internet後再查看同樣的地方已改為 EA F D其實反匯編就知道個字節就是 Jmp DF:而句柄為xDF的模塊用HelpWalk能觀察正是RichWin 的WSENGINEDLL的第一代碼段( 模塊名為TEXTMAN)而偏移H處 B B D B E C E正是一個函數起始的地方這實際上就是RichWin所重改寫的ExtTextOut函數退出Ri chWin後再用HelpWalk觀察GDI的Code代碼段一切又恢復正常!這與前面的分析結論完全吻合!那麼下一個關鍵點就是如何動態修改Windows的函數代碼也就是漢化Windows的核心——陷阱技術
  
  陷阱技術
  討論陷阱技術還要回到前面的兩個發現發現之二已能解釋為修改的Windows函數而發現之一卻仍是一個迷
  
  數據段存放的是變量及常量等內容如果這裡面包含有重定位信息那麼必定要在變量說明中將函數指針賦給一個FARPROC類型的變量於是在變量說明中寫下:
  
  FARPROC FarProcFunc=ExtTextOut;
  
  果然在自己程序的數據段中也有了重定位信息這樣當程序調入內存時變量FarPro cFunc已是函數ExtTextOut的地址了
  
  要直接修改代碼段的內容還遇到一個難題就是代碼段是不可改寫的這時需要用到一個未公開的Windows函數AllocCStoDSAlias取得與代碼段有相同基址的可寫數據段別名 其函數聲明為:
  
  WORD FAR PASCAL AllocCStoDSAlias(WORD code_sel);
  
  參數是代碼段的句柄返回值是可寫數據段別名句柄
  
  Windows中函數地址是高字節是其模塊的內存句柄低字節是函數在模塊內的偏移將得到的可寫數據段別名句柄鎖定再將函數偏移處的個字節保留下來然後將其改為轉向替代函數(用 EA Jmp):
  
  *(lpStr+wOffset) =xEA;
  
  四通利方(RichWin)中文之星(CStar)是大家廣為熟知的漢化Windows產品陷阱技術即動態修改Windows代碼一直是其對外宣稱的過人技術本文從Windows的模塊調用機制與重定位概念著手介紹了陷阱技術的實現並給出了采用陷阱技術動態修改Windows代碼的示例源程序
  
  //源程序 relocatec#include <WINDOW
From:http://tw.wingwit.com/Article/os/youhua/201311/10862.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.