一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

Visual Studio插件GDIWatch實現淺析

  GDIWatch 是Virgo Software 開發的一個for Visual Studio的插件,支持2005/2008/2010,它的功能主要是在一個類似watch的窗口上顯示被調試程序的GDI對象的當前狀態,比如HBRUSH的顏色,大小,圖片等等,并且它還能在調試過程中高亮顯示有變化的項目,方便程序員跟蹤調試畫圖函數。

  下載地址: http://www.gdiwatch.com/GDIWatch.msi

  (小聲說一下,crack在文中提供了) 

  這是官方的截圖:

  順便再貼一個 GDIWatch 在 VS2010上使用的效果圖:

  感覺還不賴,使用起來也挺方便的,就是拽個變量到它上面就可以了。

  GDIWatch 不是免費軟件,作者給了15天的試用期,如果需要繼續使用就要到官網 www.gdiwatch.com 聯系作者獲取注冊碼。

  P.S. 話說前天我在公司正好想上他的網站看看價錢如何,結果發現他的主頁不知出現神馬問題沒法顯示了,囧啊。

  P.P.S. 印象中貌似是要100多美刀的樣子。

  P.P.P.S. 在15天后我偶爾還想繼續使用,但是中國國情告訴我,花100多美刀買個插件是稍微有點貴了的說,而且目前在公司還沒用上VS2010,所以便可恥地嘗試crack,沒想到很好crack的說,稍微改動一下居然就搞定了,主要是該作者的防范意識不夠啊,犯了很多防破解的大忌,給了人家很多線索,有需要的童鞋請猛擊此處下載,適用于1.5.1.254版本,替換原版之前請自行備份以防萬一!

  好了, 言歸正傳,我當初之所以找到這個軟件是因為前陣子一直在寫畫圖的代碼,本來是想說在網上找個VC6的插件的(沒辦法,公司還是在用),先是在 CodeProject 上找到一篇某位國人很久以前發表的文章,可是他居然不是開源的(這不坑爹嗎),而且遠沒有 GDIWatch 那么方便好用(不給力啊),最奇怪的是CodeProject 居然讓他把文章給發表上去了(我勒個去),真是無奈。

  不過該作者倒是簡單提到了一下他實現的方法:

  The steps to do watch Image is :
  (1)get the selection text by ISelectionText interface
  (2)get the value of selection text by IDebugger interface
  (3)Read the memeory or bitmap data from the debugged process memory space
  (4)show it

  最后只找到這個支持VS2005+的 GDIWatch,于是開始尋思這玩意怎么實現,我想如果不是很復雜的話說不定可以在閑暇時間做一個for VC6的版本出來的說。

  我首先思考的是要實現這樣的插件最重要是要解決哪些問題:

  1、最最重要的是,必須能夠跨進程“訪問”被調試進程的GDI objects,這是當然的;

  2、必須能跟VS協調運作,響應調試動作并及時更新GUI,要像VS自己的watch那么好用;

  3、必須有界面能顯示GDI objects,這......必須的;

  當然要完善這個插件的話,還需要盡量滿足下列條件:

  1、避免使用undocumented trick,保證兼容性;

  2、如GDIWatch那樣支持拖放變量名到GUI上;

  3、高亮有變化的內容,方便跟蹤;

  在定下上面這些條件后,下一步就是逐個解決問題了。

  首先,要獲取GDI對象的屬性,基本是要走這條路:

DWORD GetObjectType(__in  HGDIOBJ h);

HGDIOBJ GetCurrentObject(__in  HDC hdc,__in  UINT uObjectType);

int GetObject(__in   HGDIOBJ hgdiobj, __in   int cbBuffer, __out  LPVOID lpvObject);

  然而,GDI對象是基于進程的,GDIWatch作為一個插件,也就是VS的一個DLL,它如果要拿被調試進程的GDI對象句柄來直接用必然是不行的,

  GDI objects 也不在 DuiplicateHandle 這個API支持的 object handle 的范疇之內。

  當然了,GDI對象畢竟也是數據,在用戶模式不能做到的,在內核模式肯定有奇淫巧計可以做到,比如說訪問GDI對象表:

http://topic.csdn.NET/t/20031009/14/2337150.html

http://hi.baidu.com/qzccan/blog/item/154b542375171440ac34de08.html

  說起來有一款軟件很可能就是這么實現的,叫做 GDIView,它可以查看指定進程當前打開的所有GDI objects并顯示其屬性:

  不過這些都屬于tricks,不是標準的做法,而且我也不熟悉具體實現方法,所以只能放棄。

  其實,畢竟目標進程是在被調試的狀態下,這還是給了插件解決這個問題的環境,或者說至少有一些條件可以被利用。

  調試器是可以有辦法讀寫被調試進程的內存的,可以在被調試進程的運行空間插入一段代碼讓它執行,只要上面提到的 GetObjectType 等API是在被調試進程的領域執行的,那么句柄就是有效的,自然能得到所需的結果。

  要讀寫內存,必然是這條路:

HANDLE WINAPI OpenProcess(__in  DWORD dwDesiredAccess,  __in  BOOL bInheritHandle,  __in  DWORD dwProcessId);

BOOL WINAPI ReadProcessMemory(__in   HANDLE hProcess,  __in   LPCVOID lpBaseAddress,  __out  LPVOID lpBuffer,  __in   SIZE_T nSize,  __out  SIZE_T *lpNumberOfBytesRead);

LPVOID WINAPI VirtualAllocEx(__in HANDLE hProcess,  __in_opt LPVOID lpAddress,  __in SIZE_T dwSize,  __in DWORD flAllocationType,  __in DWORD flProtect);

BOOL WINAPI WriteProcessMemory(__in   HANDLE hProcess,  __in   LPVOID lpBaseAddress,  __in   LPCVOID lpBuffer,  __in   SIZE_T nSize,  __out  SIZE_T *lpNumberOfBytesWritten);

  接下來的事情大概是這樣:

  設計一段代碼,主要做的事情是接受指定的GDI句柄,然后通過 GetObjectType/GetCurrentObject/GetObject 等API去獲取 GDI object 的相關信息,然后將結果保存在某個buffer。

  假設這段代碼是一個C函數,那么代碼大致是:

typedef struct tagBrushInfo{    HBRUSH      hBrush;    LOGBRUSH    logBrush;}BrushInfo, *PBrushInfo;typedef struct tagPenInfo{    HPEN		hPen;    LOGPEN      logPen;}PenInfo, *PPenInfo;typedef struct tagDCInfo{    HDC         hDC;    BrushInfo   brushInfo;    PenInfo     penInfo;}DCInfo, *PDCInfo;LPVOID GetGDIObjectInfo(HGDIOBJ hGDIObjects){	LPVOID pInfo = NULL;    DWORD dwObjType = GetObjectType(hGDIObjects);    switch ( dwObjType )    {    case OBJ_DC:        {			PDCInfo pDCInfo = new DCInfo;            pDCInfo->hDC = (HDC)hGDIObjects;            // retrieve the brush info            pDCInfo->brushInfo.hBrush = (HBRUSH)GetCurrentObject(pDCInfo->hDC, OBJ_BRUSH);            if ( pDCInfo->brushInfo.hBrush )            {                GetObject(pDCInfo->brushInfo.hBrush, sizeof(LOGBRUSH), &pDCInfo->brushInfo.logBrush);            }            // retrieve the pen info            pDCInfo->penInfo.hPen = (HPEN)GetCurrentObject(pDCInfo->hDC, OBJ_PEN);            if ( pDCInfo->penInfo.hPen )            {                GetObject(pDCInfo->penInfo.hPen, sizeof(LOGPEN), &pDCInfo->penInfo.logPen);            }            pInfo = pDCInfo;        }        break;    case OBJ_BRUSH:        if ( hGDIObjects )        {			PBrushInfo pBrushInfo = new BrushInfo;            GetObject(hGDIObjects, sizeof(LOGBRUSH), &pBrushInfo->logBrush);			pInfo = pBrushInfo;        }        break;    }    return pInfo;}

NET技術Visual Studio插件GDIWatch實現淺析,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 亚洲精品在线观看91 | 女人张腿给男人桶视频免费版 | 在线观看www日本免费网站 | 青青视频国产在线播放 | 91久久精品日日躁夜夜躁欧美 | 国产精品第7页 | 激情欧美人xxxxx | 精品国产一区二区三区成人 | 51国产偷自视频区视频手机播器 | 91华人在线视频 | 91久久国产青草亚洲 | 国产成人精品视频2021 | 久久久精品国产 | 99久久免费国产特黄 | 一区二区三区四区免费视频 | 美女扒开屁股给男人看无遮挡 | 国产成人精品视频频 | 99亚洲精品视频 | 亚洲第一精品福利 | 欧美人与物另类 | 欧美三级欧美成人高清www | 一区二区三区在线免费看 | 91麻豆精品国产91久久久久久 | 天天狠狠色综合图片区 | aa级国产女人毛片水真多 | 69色视频| 色黄视频 | 国语自产精品视频 | 微拍秒拍福利一区二区 | 国产嫩草在线观看 | 久久99精品一级毛片 | 成人精品一区二区三区 | 午夜激情视频在线观看 | 91精品视频免费观看 | 成年美女黄网站色 | 欧美性一交激情视频在线 | 五月天激情婷婷婷久久 | 久久精品国产亚洲片 | 16女性下面扒开无遮挡免费 | 国产一区二区精品久久91 | 午夜视频国语 |