青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Xiao.Zhu C++

Xiao.Zhu C++

  C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  29 隨筆 :: 14 文章 :: 17 評(píng)論 :: 0 Trackbacks
截獲API是個(gè)很有用的東西,比如你想分析一下別人的程序是怎樣工作的。這里我介紹一下一種我自己試驗(yàn)通過(guò)的方法。  
    首先,我們必須設(shè)法把自己的代碼放到目標(biāo)程序的進(jìn)程空間里去。Windows Hook可以幫我們實(shí)現(xiàn)這一點(diǎn)。SetWindowsHookEx的聲明如下:  
HHOOK SetWindowsHookEx(  
int idHook, // hook type  
HOOKPROC lpfn, // hook procedure  
HINSTANCE hMod, // handle to application instance  
DWORD dwThreadId // thread identifier  
);  
    具體的參數(shù)含義可以翻閱msdn,沒(méi)有msdn可謂寸步難行。  
    這里Hook本身的功能并不重要,我們使用它的目的僅僅只是為了能夠讓W(xué)indows把我們的代碼植入別的進(jìn)程里去。hook Type我們?nèi)芜x一種即可,只要保證是目標(biāo)程序肯定會(huì)調(diào)用到就行,這里我用的是WH_CALLWNDPROC。lpfn和hMod分別指向我們的鉤子代碼及其所在的dll,dwThreadId設(shè)為0,表示對(duì)所有系統(tǒng)內(nèi)的線程都掛上這樣一個(gè)hook,這樣我們才能把代碼放到別的進(jìn)程里去。  

    之后,我們的代碼就已經(jīng)進(jìn)入了系統(tǒng)內(nèi)的所有進(jìn)程空間了。必須注意的是,我們只需要截獲我們所關(guān)心的目標(biāo)程序的調(diào)用,因此還必須區(qū)分一下進(jìn)程號(hào)。我們自己的鉤子函數(shù)中,第一次運(yùn)行將進(jìn)行最重要的API重定向的工作。也就是通過(guò)將所需要截獲的API的開(kāi)頭幾個(gè)字節(jié)改為一個(gè)跳轉(zhuǎn)指令,使其跳轉(zhuǎn)到我們的API中來(lái)。這是最關(guān)鍵的部分。這里我想截三個(gè)調(diào)用,ws2_32.dll中的send和recv、user32.dll中的GetMessageA。  

DWORD dwCurrentPID = 0;  
HHOOK hOldHook = NULL;  
DWORD pSend = 0;  
DWORD pRecv = 0;  
GETMESSAGE pGetMessage = NULL;  

BYTE btNewBytes[8] = { 0x0B8, 0x0, 0x0, 0x40, 0x0, 0x0FF, 0x0E0, 0 };  
DWORD dwOldBytes[3][2];  

HANDLE hDebug = INVALID_HANDLE_value;  

LRESULT CALLBACK CallWndProc( int nCode, WPARAM wParam, LPARAM lParam )  
{  
DWORD dwSize;  
DWORD dwPIDWatched;  
HMODULE hLib;  

if( dwCurrentPID == 0 )  
{  
dwCurrentPID = GetCurrentProcessId();  
HWND hwndMainHook;  
hwndMainHook = ::FindWindow( 0, "MainHook" );  
dwPIDWatched = ::SendMessage( hwndMainHook, (WM_USER+100), 0, 0 );  
hOldHook = (HHOOK)::SendMessage( hwndMainHook, (WM_USER+101), 0, 0 );  

if( dwCurrentPID == dwPIDWatched )  
{  
hLib = LoadLibrary( "ws2_32.dll" );  
pSend = (DWORD)GetProcAddress( hLib, "send" );  
pRecv = (DWORD)GetProcAddress( hLib, "recv" );  

::ReadProcessMemory( INVALID_HANDLE_value, (void *)pSend, (void *)dwOldBytes[0], sizeof(DWORD)*2, &dwSize );  
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_send;  
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pSend, (void *)btNewBytes, sizeof(DWORD)*2, &dwSize );  

::ReadProcessMemory( INVALID_HANDLE_value, (void *)pRecv, (void *)dwOldBytes[1], sizeof(DWORD)*2, &dwSize );  
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_recv;  
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pRecv, (void *)btNewBytes, sizeof(DWORD)*2, &dwSize );  

hLib = LoadLibrary( "user32.dll" );  
pGetMessage = (GETMESSAGE)GetProcAddress( hLib, "GetMessageA" );  
::ReadProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)dwOldBytes[2], sizeof(DWORD)*2, &dwSize );  
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_GetMessage;  
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)btNewBytes, sizeof(DWORD)*2, &dwSize );  

hDebug = ::CreateFile( "C:\\Trace.log", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );  
}  
}  

if( hOldHook != NULL )  
{  
return CallNextHookEx( hOldHook, nCode, wParam, lParam );  
}  

return 0;  
}  

    上面的鉤子函數(shù),只有第一次運(yùn)行時(shí)有用,就是把三個(gè)函數(shù)的首8字節(jié)修改一下(實(shí)際上只需要7個(gè))。btNewBytes中的指令實(shí)際就是  
mov eax, 0x400000  
jmp eax  
這里的0x400000就是新的函數(shù)的地址,比如new_recv/new_send/new_GetMessage,此時(shí),偷梁換柱已經(jīng)完成。再看看我們的函數(shù)中都干了些什么。以GetMessageA為例:  

BOOL _stdcall new_GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax )  
{  
DWORD dwSize;  
char szTemp[256];  
BOOL r = false;  

//Watch here before it’s executed.  
sprintf( szTemp, "Before GetMessage : HWND 0x%8.8X, msgMin 0x%8.8X, msgMax 0x%8.8x \r\n", hWnd, wMsgFilterMin, wMsgFilterMax );  
::WriteFile( hDebug, szTemp, strlen(szTemp), &dwSize, 0 );  
//Watch over  

// restore it at first  
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)dwOldBytes[2], sizeof(DWORD)*2, &dwSize );  

// execute it  
r = pGetMessage( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax );  

// hook it again  
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_GetMessage;  
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)btNewBytes, sizeof(DWORD)*2, &dwSize );  

//Watch here after it’s executed  
sprintf( szTemp, "Result of GetMessage is %d.\r\n", r );  
::WriteFile( hDebug, szTemp, strlen( szTemp ), &dwSize, 0 );  
if( r )  
{  
sprintf( szTemp, "Msg : HWND 0x%8.8X, MSG 0x%8.8x, wParam 0x%8.8X, lParam 0x%8.8X\r\nTime 0x%8.8X, X %d, Y %d\r\n",  
lpMsg->hwnd, lpMsg->message,  
lpMsg->wParam, lpMsg->lParam, lpMsg->time,  
lpMsg->pt.x, lpMsg->pt.y );  
::WriteFile( hDebug, szTemp, strlen( szTemp ), &dwSize, 0 );  
}  
strcpy( szTemp, "\r\n" );  
::WriteFile( hDebug, szTemp, strlen( szTemp ), &dwSize, 0 );  

//Watch over  

return r;  
}  

    先將截獲下來(lái)的參數(shù),寫入到一個(gè)log文件中,以便分析。然后恢復(fù)原先保留下來(lái)的GetMessageA的首8字節(jié),然后執(zhí)行真正的GetMessageA調(diào)用,完畢后再將執(zhí)行結(jié)果也寫入log文件,然后將GetMessageA的執(zhí)行結(jié)果返回給調(diào)用者。  
整個(gè)截獲的過(guò)程就是這樣。你可以把其中的寫log部分改成你自己想要的操作。這里有個(gè)不足的地方是,截獲動(dòng)作是不能夠并發(fā)進(jìn)行的,如果目標(biāo)進(jìn)程是多線程的,就會(huì)有問(wèn)題。解決辦法是,可以在每次new_GetMessage中加入一個(gè)CriticalSection的鎖和解鎖,以使調(diào)用變?yōu)榇羞M(jìn)行,但這個(gè)我沒(méi)有試驗(yàn)過(guò)。
posted on 2007-04-28 16:00 Xiao.Zhu 閱讀(829) 評(píng)論(0)  編輯 收藏 引用

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美日韩在线播放| 久久综合九色综合欧美狠狠| 国产一区二区在线免费观看| 国产精品女主播一区二区三区| 欧美午夜精品理论片a级大开眼界| 国产精品国产三级国产普通话99| 国产精品福利网| 伊人久久久大香线蕉综合直播| 伊人狠狠色丁香综合尤物| 亚洲国产精品欧美一二99| 亚洲毛片视频| 欧美亚洲在线| 欧美刺激性大交免费视频| 亚洲九九爱视频| 亚洲在线成人| 免费成人黄色片| 国产精品qvod| 在线观看一区二区视频| 一区二区三区视频在线看| 欧美中文字幕在线观看| 亚洲大黄网站| 亚洲午夜精品久久久久久浪潮 | 玖玖玖国产精品| 欧美激情中文字幕在线| 亚洲无毛电影| 国产精品性做久久久久久| 国产精品日韩高清| 国产香蕉97碰碰久久人人| 日韩一区二区精品在线观看| 欧美一区免费| 亚洲人成欧美中文字幕| 性视频1819p久久| 欧美日韩高清在线观看| 一区国产精品| 欧美影院成年免费版| 亚洲国产一区二区三区高清| 卡一卡二国产精品| 亚洲欧美另类综合偷拍| 欧美日韩精品免费看| 激情校园亚洲| 久久精品国产亚洲精品| 日韩午夜精品| 欧美极品aⅴ影院| 在线观看视频日韩| 久久蜜桃香蕉精品一区二区三区| 在线一区观看| 欧美日韩性生活视频| 亚洲精品美女91| 女人天堂亚洲aⅴ在线观看| 欧美一区二区三区精品电影| 国产欧美日韩综合一区在线观看 | 欧美伊人久久久久久久久影院| 欧美日韩另类视频| 亚洲免费av观看| 亚洲电影av| 欧美成人激情视频免费观看| 精品福利电影| 农村妇女精品| 欧美国产成人在线| 日韩一级欧洲| 99精品欧美一区二区三区| 欧美日韩的一区二区| 亚洲午夜av| 亚洲淫片在线视频| 国产精品视频九色porn| 欧美一级黄色录像| 欧美一区二区三区四区在线| 激情综合久久| 亚洲第一精品久久忘忧草社区| 免费高清在线一区| aa国产精品| 一区二区欧美国产| 国产精品日韩一区二区三区| 久久成人免费电影| 久久这里只有| 中文高清一区| 欧美在线精品免播放器视频| 在线观看91精品国产麻豆| 欧美激情四色| 欧美日韩一区二区视频在线观看| 亚洲欧美视频一区| 亚洲综合日韩| 国产精品黄色| 一区二区三区日韩在线观看 | 久久综合影音| 欧美激情bt| 亚洲小视频在线观看| 国产日产高清欧美一区二区三区| 性色一区二区| 亚洲电影第三页| 西瓜成人精品人成网站| 在线观看日韩www视频免费| 欧美日韩一区二| 午夜精品影院在线观看| 欧美激情精品久久久久| 久久九九精品99国产精品| 亚洲人成在线观看| 国产欧美另类| 欧美日韩国产区| 免费在线一区二区| 欧美日韩免费| 亚洲影院在线| 日韩视频精品| 欧美激情区在线播放| 久久精品视频免费| 亚洲夜晚福利在线观看| 日韩视频一区二区三区| 狠狠爱综合网| 国产精品自在线| 国产精品国产三级国产普通话99| 男人插女人欧美| 免费不卡视频| 久久嫩草精品久久久精品| 午夜国产不卡在线观看视频| 亚洲一区二区三区免费视频| 中国女人久久久| 一区二区不卡在线视频 午夜欧美不卡在 | 久久男人资源视频| 久久婷婷久久| 欧美精品情趣视频| 欧美日韩免费看| 国产亚洲精品久| 激情伊人五月天久久综合| 韩国免费一区| 亚洲精选视频免费看| 亚洲免费观看高清在线观看| 日韩午夜在线| 欧美在线亚洲| 亚洲高清久久久| 在线视频一区二区| 欧美一区亚洲二区| 欧美美女喷水视频| 韩国一区二区三区美女美女秀| 亚洲日本中文字幕区| 性做久久久久久久免费看| 欧美成人免费观看| 在线亚洲一区| 欧美日韩国产区| 欧美视频久久| 久久激情婷婷| 国产精品成人一区二区三区夜夜夜| 国产一区二区电影在线观看 | 国产区亚洲区欧美区| 亚洲视频中文| 麻豆精品在线播放| 久久久久国色av免费看影院 | 久久久久久久综合日本| 欧美日韩麻豆| 91久久在线| 亚洲精品久久久久久久久| 欧美激情综合色| 99国产精品久久| 99国产精品99久久久久久| 欧美精品久久久久久久免费观看| 日韩视频一区二区在线观看| 欧美激情一区二区三区全黄| 免费在线播放第一区高清av| 99国内精品久久久久久久软件| 亚洲经典在线| 国产欧美va欧美va香蕉在| 久久精品国产亚洲5555| 久久艳片www.17c.com| 亚洲免费观看在线观看| 在线一区亚洲| 亚洲激情女人| 久久国产精品久久久久久电车| 91久久精品www人人做人人爽| 亚洲精品无人区| 国产偷国产偷精品高清尤物| 欧美成人免费观看| 国产精品视频1区| 麻豆精品视频在线观看视频| 国产精品手机在线| 亚洲精品专区| 亚洲国产欧美在线人成| 午夜精品久久久久久| 亚洲精品在线观| 久久综合影视| 免费亚洲一区| 影音先锋日韩资源| 欧美自拍丝袜亚洲| 欧美专区在线播放| 国产欧美一区二区三区久久| 一本色道久久综合亚洲精品不| 91久久精品国产91性色tv| 久久9热精品视频| 久久中文久久字幕| 激情欧美丁香| 老司机精品久久| 亚洲激情av| 制服诱惑一区二区| 国产精品免费电影| 一区二区黄色| 国产精品一区二区久久久久| 在线视频欧美精品| 久久精品日韩一区二区三区| 国产有码一区二区| 欧美不卡一区| 亚洲影视在线| 欧美成人黑人xx视频免费观看|