win32程序概念之控制代碼表,以及核心物件

2022-03-20 20:36:06 字數 3439 閱讀 7850

我們知道.我們使用createprocess 的時候會返回乙個程序控制代碼.以及執行緒控制代碼. 其實在呼叫createprocess的時候.核心中會新建乙個eprocess結構來儲存我們的程序資訊.

例如如下圖:

但是有乙個問題.怎麼給三環使用.難道直接返回eprocess?

其實不是這樣的. 第一eprocess在高兩g. 三環程式是不可以訪問的.所以返回的位址是高兩g所以不能使用. 但是為了解決這一問題. 

windows建立了乙個**. 返回這個**的索引. 而我們使用的就是這個索引.

核心物件就是我們上面所說的eprocess. 有很多核心物件.具體可以看下closehandle. 這個api表示他可以關閉什麼核心物件.

可以操作事件  檔案 互斥體 執行緒. 等等....

在windows程式中.我們操作的都是核心物件. 我們可以通過openprocess api來開啟乙個已有程序的核心物件.

如下圖:

每個程序裡面的控制代碼表都是私有的. 例如第一張表. 控制代碼索引位1. 對應核心物件為a. 那麼將索引傳給b程序是沒用用的.

b程序只有使用api開啟之後才能獲得 a核心物件.

其中中間的紫色表代表引用計數. 也就是說這個核心物件引用一次 這個值則會+1

而closehandle作用就是 使核心物件的引用計數-1 如果都關閉了.那麼此時核心物件沒有人使用. 也沒有執向了.所以就會銷毀這個核心物件了.也就是說.當核心物件的引用計數字為0了.那麼此時的核心物件

才是真正的銷毀.

而執行緒是特例:  當執行緒的核心物件引用計數為0的時候也不會關閉.  此時必須先關閉執行緒.在使用closehandle 是引用計數 -1才可以.

在windows程式中. a建立 b .或者帶有核心物件的 api在建立的時候. 都有乙個sd屬性.也就是安全屬性.這個屬性可以表示你建立的這個控制代碼是否可以繼承.

例如:createevent()建立事件. 先不用管api的作用.我們看下api的引數吧.

handle createeventa(

lpsecurity_attributes lpeventattributes, 安全屬性結構體 主要介紹他

bool bmanualreset,

bool binitialstate,

lpcstr lpname

);

第乙個就是安全屬性結構體.如果我們不指定.預設就是父程序的.

安全屬性結構體.

typedef struct

_security_attributes security_attributes, *psecurity_attributes, *lpsecurity_attributes;

如下圖所示:

如果我們的控制代碼可以被繼承. 那麼控制代碼表的第一項就填1.表示這個控制代碼可以被繼承.如果不能繼承.則為0

此時我們的子程序就可以繼承父程序的 所有可繼承的控制代碼表了.  注意.是所有可繼承.  可以是共享的了. 如下圖所示.

a程序建立的 b d是可以繼承的. 所以 子程序可以完全複製a程序 可繼承控制代碼表. 不允許繼承的為0 都賦值為0

在windows任務管理器中.有pid選項.我們可以選中檢視. 而且在windows中也常常聽到程序id的概念.

那麼程序id到底是個什麼東西.

其實程序id是全域性的控制代碼表的乙個索引.  上面所講的控制代碼表.都是自己私有的控制代碼表. pid是全域性控制代碼表裡面的.

這個控制代碼表裡面記錄了所有的正在執行程序的控制代碼.而且是唯一的. 如果程序死亡那麼這個pid可能會執向別的控制代碼.  但也是唯一的.如下圖所示.

而這個全域性控制代碼表才是真正有意義的.為什麼這樣說.

我們可以做個測試.

1.使用openprocess開啟程序控制代碼.

2.使用terminlateprocess結束程序.

openprocess(訪問許可權,控制代碼是否可以繼承,程序pid)

terminlateprocess(程序控制代碼,自定義的退出碼) 結束程序.

使用上面的兩個api可以測試一下我們已有的程序是否可以被關閉. 如果測試過後你會發現.

只有pid獲得控制代碼才是有用了.也就是說全域性控制代碼表. 而上面所講的都是子程序的控制代碼表.

1. getmodulefilename()  獲取當前模組路徑 例如:  c:\\1.exe

2.getcurretdirectory()     獲取當前的工作目錄 例如:  c:\text\abc

3.openprocess()  根據程序pid開啟程序.獲取程序控制代碼.

4.findwindow()    根據類名以及檔名.返回視窗控制代碼.

5.getwindowsthreadprocessid()  根據視窗控制代碼.獲取程序pid

6.enumprocesses 遍歷所有程序.返回程序pid    具體參考msdn 有提供的例子.

7.getcommandline() 獲取命令列引數

8.createtoolhelp32snapshot() 建立程序快照. 如果懂逆向的就知道.fs暫存器中的teb peb結構中有儲存當前模組的或者程序的鍊錶.這個是儲存當前這一時刻的快照.

我們可以進行遍歷. 具體參考msdn或者本部落格. 

我們在編寫windows程式的時候.會包含windows.h 但是有的函式可能就沒有. 比如上面我們說的第八個函式. 快照函式.

此時我們要查詢msdn. 我們可以搜尋一下網頁的.

我們可以在下邊看到所需要的標頭檔案 是 tlhelp32.h 此時我們包含一下即可.

遇到的問題2.

有的時候我們標頭檔案也包含了也去使用了.但是呼叫api的時候出錯了.為什麼?

原因是 有的api在高版本中才有.低版本中使用的時候是沒有匯出的.此時使用就會出錯.提示沒有這個api.

解決方法: 如果學過win32的 說的這個方法你們就理解了.如果沒學過也沒關係.一般這個問題很少遇見. 博主也才預見過一次.

可以使用 loadlibary載入所需要的dll. 然後使用 getprocaddress獲取函式位址. 使用函式指標來使用這個函式.

Win32之程序建立過程

程序提供程式所需要的資源,如 資料 等等 程序扮演的角色僅僅是為當前程式提供資源,或者 這就是程序所提供的,當時程式執行的狀態和程序沒有關係,程序可以看做空間的概念 例子 程序相當於乙個房子,房子裡面的東西,這些東西就是程序提供的 房子裡面走來走去的人,和使用東西的人,就是執行緒 你看到的這些東西就...

win32中對「控制代碼」的理解

1 win32中的控制代碼在數值上表示乙個32位的數,用來標識應用程式 程序中不同物件以及同類物件中的不同例項,而所謂例項就是指被例項化的物件,例項化的過程就是通過類建立物件的過程。例項化物件的目地是為物件開闢記憶體空間。所以控制代碼是指向一片記憶體空間的。乙個視窗,按鈕,圖示,滾動條,輸出裝置,控...

win32建立子程序方法

看到網上有乙個示例,我查了先關函式,做了一些注釋,自己學習下 include include include using namespace std pragma comment lib,ws2 32 int main 該結構用於指定新程序的主視窗特性 si.cb sizeof si process...