欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
打造屬于自己的任務(wù)管理器(邀請碼已發(fā))
打造屬于自己的任務(wù)管理器

【文章標題】: 打造屬于自己的任務(wù)管理器
【文章作者】: SniperChan
【作者郵箱】: SniperChan@126.com
【編寫(xiě)語(yǔ)言】: VC
【使用工具】: VS.NET 2008 SP1
【操作平臺】: XP SP3
【作者聲明】: 軟件可以任意修改和傳播
  
想想自己在看雪也混了有一些日子了,再看看自己的ID還是個(gè)臨時(shí)會(huì )員,所以想寫(xiě)一些技術(shù)性的文章來(lái)申請個(gè)邀請碼.本人無(wú)才,破解剛接觸難以寫(xiě)出一篇能收買(mǎi)版主的文章.破文就寫(xiě)不來(lái)了,不過(guò)自己也學(xué)過(guò)編程一段時(shí)間了,那就寫(xiě)一些關(guān)于編程的吧,希望以下這段亂碼能博君一笑.
  
任務(wù)管理器是在windows系統用得最頻繁的一個(gè)軟件之一吧.你是否會(huì )覺(jué)得任務(wù)管理器的功能過(guò)于簡(jiǎn)單,不能滿(mǎn)足你的需要呢?那好,就讓我們一起來(lái)動(dòng)手打造一個(gè)更強大的任務(wù)管理器.
  
我就覺(jué)得任務(wù)管理器的網(wǎng)絡(luò )項的功能不夠,如果能顯示實(shí)時(shí)的上傳,下載速度就好了.這樣我們就可以隨時(shí)關(guān)注自己的網(wǎng)絡(luò )狀態(tài).雖然顯示實(shí)時(shí)速度的軟件很多,但是每次查看的時(shí)候都要找出來(lái)打開(kāi),不夠方便,加在任務(wù)管理器就方便調出來(lái)查看了,并且它本身已經(jīng)有了曲線(xiàn)顯示了.好,開(kāi)始吧!

最終效果圖:


思路:
      怎么樣才能在任務(wù)管理器中插入兩列速度呢?我認為有下面兩種方法:
      1.PEDIY技術(shù),對原來(lái)的任務(wù)管理器進(jìn)行修改擴充,增加一定的代碼以增加原程序的功能.
      2.通過(guò)DLL注入的方法,把已編寫(xiě)好的DLL注入到原程序中已實(shí)現想要的功能.

對于第一種方法,修改了原來(lái)的程序,不方便切換為沒(méi)修改時(shí)的狀態(tài).第二種就可以很方便的進(jìn)行加載和卸載DLL,并且對原程序不需要做任何修改,不會(huì )破壞到原來(lái)的程序.下面就討論第二種方法.

步驟:
    一,遠程注入DLL;
    二,編寫(xiě)DLL實(shí)現相關(guān)功能;

一,遠程注入DLL在微軟的Windows中,每個(gè)進(jìn)程都能獲得自身的私有地址空間.當使用指針引用內存時(shí),指針值將引用自身進(jìn)程地址空間中的一個(gè)內存地址.進(jìn)程不能創(chuàng )建一個(gè)引用屬于其他進(jìn)程的內存指針.
進(jìn)程不能創(chuàng )建一個(gè)引用屬于其他進(jìn)程的內存指針,否則就會(huì )出現內存的錯誤,該錯誤不會(huì )影響到其他進(jìn)程所使用的內存.那如何才能將自己編寫(xiě)的DLL放到任務(wù)管理器的進(jìn)程空間中呢?通過(guò)遠程注入!遠程注入技術(shù)需要滿(mǎn)足一個(gè)條件就是要求目標進(jìn)程中的一個(gè)線(xiàn)程調用LoadLibrary函數來(lái)加載所需要的DLL.由于除了自己進(jìn)程的線(xiàn)程中之外,我們不能簡(jiǎn)單的控制其他進(jìn)程中的線(xiàn)程,因此該解決方法要求我們在目標進(jìn)程中創(chuàng )建一個(gè)新線(xiàn)程,這樣我們就可以控制它執行任何代碼.Windows提供了一個(gè)
CreateRomoteThread的函數可以簡(jiǎn)單地在另一個(gè)進(jìn)程中創(chuàng )建線(xiàn)程.

代碼:
     HANDLE CreateRomoteThread(                    HANDLE hProcess                                        //目標進(jìn)程句柄             PSECURITY_ATTRIBUTES psa,                      //指向SECURITY_ATTRIBUTES型態(tài)的結構的指針。在Windows 98中忽略該參數。在Windows NT中,它被設為NULL,表示使用缺省值。             DWORD dwStackSize,                                  //線(xiàn)程堆棧大小,一般=0,在任何情況下,Windows根據需要動(dòng)態(tài)延長(cháng)堆棧的大小。             PTHREAD_START_ROUTINE pfnstartAddr,    //指向線(xiàn)程函數的指針,形式:@函數名,函數名稱(chēng)沒(méi)有限制,但是必須以下列形式聲明:DWORD WINAPI ThreadProc (LPVOID pParam) ,格式不正確將無(wú)法調用成功。              PVOID pvParam,                                          //向線(xiàn)程函數傳遞的參數,是一個(gè)指向結構的指針,不需傳遞參數時(shí),為NULL。             DWORD fdwCreate,                                     //線(xiàn)程標志             PDWORD pdwThreadId                                //保存新線(xiàn)程的id。             );
返回值:
  函數成功,返回線(xiàn)程句柄;函數失敗返回false。

現在已經(jīng)知道了如何在另一個(gè)進(jìn)程中創(chuàng )建線(xiàn)程了,但是如何讓該線(xiàn)程來(lái)加載DLL呢?答案很簡(jiǎn)單:讓線(xiàn)程去調用LoadLibrary函數:

代碼:
HANDLE LoadLibrary(PCTSTR pszLibFile)
pszLibFile:指定要載入的動(dòng)態(tài)鏈接庫的名稱(chēng)

返回值:
    成功則返回庫模塊的句柄,零表示失敗;

歸結起來(lái)就應該是如下顯示的一行代碼:

代碼:
HANDLE hThreadd = CreateRemoteThread(hProcessRemote,NULL,0,LoadLibrary,"E:\\MyLib.dll",0,NULL);
MyLib.dll就是下面要編寫(xiě)的DLL.

可是還它不能達到預期的目的,里面還存在兩個(gè)問(wèn)題.
1.如果目標程序并沒(méi)有使用到LoadLibrary函數,生成的exe的導入表就沒(méi)有該函數,如果直接這樣使用一些不可以預測的東西,可能會(huì )導致訪(fǎng)問(wèn)為例等錯誤.為強制使用LoadLibrary函數,必須通過(guò)調用GetProcAddress得到該函數的確切內存位置.

LoadLibrary函數在Kernel32.dll中,函數應該變成如下:

代碼:
PTHREAD_START_ROUTINE pfnThreadRtn =(PTHREAD_START_ROUTINE )GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibrary");HANDLE hThread = CreateRemoteThread(hProcessRemote,NULL,0,pfnThreadRtn ,"E:\\MyLib.dll",0,NULL);
2.由于字符串"E:\\MyLib.dll"是在調用者的進(jìn)程空間里,當LoadLibrary時(shí)并不能使用其他進(jìn)程空間的內存地址,將會(huì )出現上述的訪(fǎng)問(wèn)違例.所以還要將DLL的路徑名字字符串放進(jìn)遠程的地址空間中.當調用CreateRemoteThread時(shí),需要將所放置字符串的地址(相對遠程進(jìn)程)傳遞給它.同樣Windows提供了一個(gè)函數,即VirtualAllocEx,他允許一個(gè)進(jìn)程分配另一個(gè)進(jìn)程的地址空間中的內存:
代碼:
  LPVOID VirtualAllocEx(   HANDLE hProcess, //申請內存所在的進(jìn)程句柄?! PVOID lpAddress, //保留頁(yè)面的內存地址;一般用NULL自動(dòng)分配 ?! IZE_T dwSize, //欲分配的內存大小,字節單位;注意實(shí)際分 配的內存大小是頁(yè)內存大小的整數倍  DWORD flAllocationType, //可取下列值MEM_PHYSICAL ,MEM_RESERVE,MEM_RESET ,MEM_TOP_DOWN,MEM_WRITE_WATCH  DWORD flProtect //可取下列值PAGE_READONLY,PAGE_EXECUTE,PAGE_EXECUTE_READ ,PAGE_EXECUTE_READWRITE,PAGE_GUARD,PAGE_NOACCESS,PAGE_NOCACHE  ); 
另外一個(gè)函數允許釋放該內存:
代碼:
BOOL VirtualFreeEx(  HANDLE hProcess, // 要釋放內存所在進(jìn)程的句柄  LPVOID lpAddress, // 區域地址  DWORD dwSize, // 區域大小,字節  DWORD dwFreeType //類(lèi)型  );
分配好了內存,現在需要從進(jìn)程的地址空間復制到遠程進(jìn)程的地址空間中去.

代碼:
BOOL ReadProcessMemory(   HANDLE hProcess,// 遠程進(jìn)程句柄  LPCVOID lpBaseAddress, //遠程進(jìn)程中內存地址  LPVOID lpBuffer, //本地進(jìn)程中內存地址. 函數將讀取的內容寫(xiě)入此處  DWORD nSize,// 要傳送的字節數  LPDWORD lpNumberOfBytesRead //實(shí)際傳送的字節數. 函數返回時(shí)報告實(shí)際寫(xiě)入多少  );  BOOL WriteProcessMemory(   HANDLE hProcess,   LPVOID lpBaseAddress,   LPVOID lpBuffer,   DWORD nSize,   LPDWORD lpNumberOfBytesWritten   ); 
到此已經(jīng)解決了需要了解工作,下面來(lái)總結一下操作步驟:
1)使用VirtualAllocEx函數分配遠程的地址空間中的內存.
2)使用WriteProcessMemory函數將DLL的路徑名復制到步驟1)所分配的內測中.
3)使用GetProcAddress函數得到LoadLibrary函數的實(shí)際地址(在Kernel32.dll中).
4)使用CreateRemoteThread函數在遠程進(jìn)程中創(chuàng )建一個(gè)線(xiàn)程,調用正確的LoadLibrary函數,將步驟1)所分配的內存地址傳遞給他.


這時(shí),DLL已經(jīng)注入到了遠程進(jìn)程的地址空間中,DLL的DllMain函數接收到一個(gè)DLL_PROCESS_ATTACH通知,并且可以執行所需要執行的代碼了.

具體代碼如下:
代碼:
BOOL Inject(DWORD dwProcessId/*進(jìn)程ID*/, PCWSTR pszLibFile/*DLL路徑和名稱(chēng)*/){  BOOL bOk = FALSE;   HANDLE hProcess = NULL, hThread = NULL;  PWSTR pszLibFileRemote = NULL;  __try {    // 獲取目標進(jìn)程的句柄    hProcess = OpenProcess(      PROCESS_QUERY_INFORMATION |   // Required by Alpha      PROCESS_CREATE_THREAD     |   // For CreateRemoteThread      PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx      PROCESS_VM_WRITE,             // For WriteProcessMemory      FALSE, dwProcessId);    if (hProcess == NULL) __leave;    // 計算DLL路徑的長(cháng)度    int cch = 1 + lstrlenW(pszLibFile);    int cb  = cch * sizeof(wchar_t);    //在遠程進(jìn)程為DLL的名字和路徑分配內存    pszLibFileRemote = (PWSTR)       VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);    if (pszLibFileRemote == NULL) __leave;    //把路徑復制的遠程進(jìn)程的內存中    if (!WriteProcessMemory(hProcess, pszLibFileRemote,       (PVOID) pszLibFile, cb, NULL)) __leave;    //獲取LoadLibraryW 在Kernel32.dll中的實(shí)際內存地址    PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)      GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");    if (pfnThreadRtn == NULL) __leave;    //創(chuàng  )建遠程線(xiàn)程    hThread = CreateRemoteThread(hProcess, NULL, 0,       pfnThreadRtn, pszLibFileRemote, 0, NULL);    if (hThread == NULL) __leave;    // 等待線(xiàn)程結束    WaitForSingleObject(hThread, INFINITE);    bOk = TRUE;   }  __finally {     // 釋放內存    if (pszLibFileRemote != NULL)       VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);    if (hThread  != NULL)       CloseHandle(hThread);    if (hProcess != NULL)       CloseHandle(hProcess);  }  return(bOk);}


二,編寫(xiě)DLL實(shí)現相關(guān)功能
    好了,DLL就注入到了目標進(jìn)程了,下面就開(kāi)始編寫(xiě)DLL來(lái)實(shí)現想要的功能了.


我想要在任務(wù)管理器的這一個(gè)控件后面加上兩列,該如何做呢?


要想在這個(gè)控件中添加兩列就必須要知道這個(gè)控件的句柄,通過(guò)EnumChildWindows函數可以枚舉父窗口的所有子窗口.這個(gè)控件也在其中.

代碼:
BOOL EnumChildWindows(HWND hWndParent,WNDENUMPROC lpEnumFunc, LPARAM lParam);  HWND hWndParent, //父窗口句柄  WNDENUMPROC lpEnumFunc, // 回調函數的地址  LPARAM lParam//你自已定義的參數
通過(guò)這個(gè)函數可以看出,也必須要知道父窗體的句柄,很簡(jiǎn)單,通過(guò)FindWindow就可以得到任務(wù)管理器的句柄了.

代碼:
HANDLE hwndTaskManager = FindWindow( (LPCTSTR)32770, L"Windows 任務(wù)管理器");
FindWindow第一個(gè)參數是類(lèi)名,第二個(gè)參數是窗體的標題.第一個(gè)參數32770是什么,從何而來(lái)的?通過(guò)vs自帶的一個(gè)工具SPY++可以查看到:


看到了吧,32770就是任務(wù)管理器的類(lèi)名,也是一般對話(huà)框的類(lèi)名.

前面說(shuō)到,既然是枚舉所有控件,我怎么知道那個(gè)控件的句柄才是我要找的控件句柄呢?也是通過(guò)SPY++可以找到該控件的ID:


控件ID:   00000A28 ;


EnumChildWindows第二個(gè)參數是回調的函數,所以寫(xiě)一個(gè)_EnumChildProc函數來(lái)比較該控件是否是想要的控件,最后一個(gè)參數是一個(gè)自定義參數,所以我們需要定義一個(gè)結構來(lái)保存獲取到句柄和需要查找的控件ID,傳遞給EnumChildProc;

代碼:
struct StructFindTaskManagerDlgItem{    DWORD  itemID;//控件ID  HWND  hwnd;//該控件的句柄};BOOL CALLBACK _EnumChildProc( HWND hwnd, LPARAM lParam ){  StructFindTaskManagerDlgItem* pParam = (StructFindTaskManagerDlgItem*)lParam;  if ( (DWORD)GetDlgCtrlID( hwnd ) == pParam->itemID )//判斷是否為需要的控件  {    pParam->hwnd = hwnd;    return FALSE;  }  return TRUE;}HWND FindTaskManagerDlgItem( DWORD itemID ){  StructFindTaskManagerDlgItem param;  param.itemID = (DWORD)itemID;  param.hwnd = NULL;  EnumChildWindows(  hwndTaskManager, _EnumChildProc, (LPARAM)&param );  return param.hwnd;}
控件的句柄找到了,下一步就是在該控件中插入兩個(gè)列頭具體代碼如下:
代碼:
//獲取listview的數量int GetListColmnCount(HWND hList){  int count=0;  WCHAR caption[MAX_PATH];  LVCOLUMN lvc;  lvc.mask=LVCF_TEXT;  lvc.cchTextMax=MAX_PATH;  lvc.pszText=caption;  for (int i=0;i<50;i++)  {    ZeroMemory(caption,sizeof(caption));    SendMessage(hList,LVM_GETCOLUMN,i,(long)&lvc);    if (caption[0]==0&&caption[1]==0)    {      count=i;      break;    }    }  return count;  }//向listview插入兩列void InsertColToNetworkList(HWND hNetworkList)//hNetworkList即為該控件的句柄{  int n=GetListColmnCount(hNetworkList);//獲取列數,加載所有列的后面  // 添加列  LV_COLUMN colmn;     // 列  ZeroMemory(&colmn, sizeof(LV_COLUMN));  colmn.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; // 風(fēng)格  colmn.fmt=LVCFMT_RIGHT;  colmn.cx = 0x60;//寬度  colmn.pszText = L"下載";//列名  SendMessage(hNetworkList, LVM_INSERTCOLUMN, n, (LPARAM)&colmn);    colmn.pszText = L"上傳";//列名  SendMessage(hNetworkList, LVM_INSERTCOLUMN, n+1, (LPARAM)&colmn);}
列已經(jīng)建好了,接下來(lái)要做的就是計算出當前的速度了.
GetIfTable()可以從操作系統維護的MIB庫中讀出本機各個(gè)接口的當前信息,如接口數目、類(lèi)型、速率、物理地址、接收/發(fā)送字節數、錯語(yǔ)字節數等.

代碼:
DWORD GetIfTable(  __out    PMIB_IFTABLE pIfTable,//指向PMIB_IFTABLE 的指針  __inout  PULONG pdwSize,//pIfTable的大小  __in     BOOL bOrder//是否排序);typedef struct _MIB_IFTABLE {  DWORD     dwNumEntries;  MIB_IFROW table[ANY_SIZE];}MIB_IFTABLE, *PMIB_IFTABLE;typedef struct _MIB_IFROW {  WCHAR wszName[MAX_INTERFACE_NAME_LEN];  DWORD dwIndex;//端口索引號   DWORD dwType;//端口類(lèi)型  DWORD dwMtu;//最大傳輸包字節數  DWORD dwSpeed;//端口速度  DWORD dwPhysAddrLen;//物理地址長(cháng)度  BYTE  bPhysAddr[MAXLEN_PHYSADDR];//物理地址  DWORD dwAdminStatus;//管理狀態(tài)  DWORD dwOperStatus;//操作狀態(tài)  DWORD dwLastChange;//上次狀態(tài)更新時(shí)間   DWORD dwInOctets;//輸入字節數  DWORD dwInUcastPkts;//輸入非廣播包數  DWORD dwInNUcastPkts;//輸入廣播包數  DWORD dwInDiscards;//輸入包丟棄數  DWORD dwInErrors;//輸入包錯誤數  DWORD dwInUnknownProtos;//輸入未知協(xié)議包數  DWORD dwOutOctets;//輸出字節數  DWORD dwOutUcastPkts;//輸出非廣播包數   DWORD dwOutNUcastPkts;//輸出廣播包數  DWORD dwOutDiscards;//輸出包丟棄數  DWORD dwOutErrors;//輸出包錯誤數  DWORD dwOutQLen;//輸出隊長(cháng)    DWORD dwDescrLen;//端口描述長(cháng)度  BYTE  bDescr[MAXLEN_IFDESCR]; //端口描述}MIB_IFROW, *PMIB_IFROW;
通過(guò)MIB_IFROW可以看出,里面已經(jīng)包含了我們需要的信息 dwInOctets,dwOutOctets就分別是下載和上傳的自己數了,他是累積量,我們可以通過(guò)計算可以獲得每秒的字節數

當前下載速率=(當次輸入的字節數-上次輸入的字節數)/1秒.   
當前上傳速率=(當次輸出的字節數-上次輸出的字節數)/1秒.    
具體代碼如下:
代碼:
int NetInformation() {   MIB_IFTABLE *pIfTable = NULL;   MIB_IFROW *pIfRow=NULL;   ULONG dwSize = 0;   DWORD dwRet;   dwRet = GetIfTable( pIfTable, &dwSize, TRUE ); //第一次調用獲取結構大小  if ( dwRet == ERROR_INSUFFICIENT_BUFFER )   {     pIfTable = ( MIB_IFTABLE * ) new char[dwSize];     if ( pIfTable != NULL )     {       dwRet = GetIfTable( pIfTable, &dwSize, TRUE ); //獲得相關(guān)信息      if ( dwRet == NO_ERROR )       {         pIfRow = (MIB_IFROW *) & pIfTable->table[1];        CurrentInBytes=pIfRow->dwInOctets;          //保存當次的輸入字節數        CurrentOutBytes=pIfRow->dwOutOctets;        //保存當次的輸出字節數      }       else       {         printf( "Some error occured!\n" );         return FALSE;       }     }     else     {       printf( "Memory allocate failue\n" );       return FALSE;     }   }   else   {     printf( "Some error occured!\n" );     return FALSE;   }   return TRUE; } 

下面是創(chuàng )建一個(gè)線(xiàn)程,每秒讀取一次,然后更新到界面上

代碼:
CreateThread(NULL,NULL,ThreadTimerProc,NULL,NULL,NULL);DWORD WINAPI  ThreadTimerProc(PVOID param){  NetInformation();  lastInBytes=CurrentInBytes;  lastOutBytes=CurrentOutBytes;  while(TRUE)  {    if(NetInformation())    {      float InBps=(float(CurrentInBytes-lastInBytes))/1024;      float OutBps=(float(CurrentOutBytes-lastOutBytes))/1024;      lastInBytes=CurrentInBytes;      lastOutBytes=CurrentOutBytes;      item.mask = LVIF_TEXT;      item.cchTextMax = MAX_PATH;      int iSubItem=GetListItemIndex(hwndNetworkList,L"下載");      if (iSubItem>0)      {        ZeroMemory(szBPS,sizeof(szBPS));        swprintf(szBPS,L"%0.2f KB/s",InBps);        //swprintf(szBPS,L"%ld KB/s",CurrentInBytes);          item.pszText=szBPS;        item.iSubItem =iSubItem;        ListView_SetItem(hwndNetworkList,(LPARAM)&item);        ZeroMemory(szBPS,sizeof(szBPS));        swprintf(szBPS,L"%0.2f KB/s",OutBps);        //swprintf(szBPS,L"%ld KB/s",CurrentOutBytes);        item.pszText=szBPS;        item.iSubItem =iSubItem+1;        ListView_SetItem(hwndNetworkList,(LPARAM)&item);      }    }    Sleep(1000);  }}

到此為止,整個(gè)程序已經(jīng)完成了90%了,還有些就是關(guān)于一些如何判斷DLL已經(jīng)加載了,如何卸載等請看源代碼,這里就不一一介紹了.這個(gè)程序還可以做得跟好,比如在每個(gè)進(jìn)程那個(gè)列表加上一個(gè)實(shí)時(shí)速度,這樣就可以看到每個(gè)進(jìn)程網(wǎng)絡(luò )情況等,有興趣的朋友可以自己添加完善.
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C/C++編程日記:制作一個(gè)簡(jiǎn)單的內存外掛
WINDOWS的鉤子函數知識與匯編實(shí)例 一
根據進(jìn)程ID枚舉所有窗口獲得窗口句柄
VC中線(xiàn)程的創(chuàng )建與消息傳遞
VC啟動(dòng)一個(gè)新線(xiàn)程的三種方法
Windows消息攔截技術(shù)的應用
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久