• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            [原創]shadow ssdt學習筆記(一)

            Posted on 2009-10-24 22:24 S.l.e!ep.¢% 閱讀(933) 評論(0)  編輯 收藏 引用 所屬分類: RootKit

            [原創]shadow ssdt學習筆記(一)

            文章作者:zhuwg
            信息來源:邪惡八進制信息安全團隊(www.eviloctal.com

            1。取得shadow ssdt真實地址
            系統只提供了KeServiceDescriptorTable導出
            KeServiceDescriptorTableShadow是個未導出結構

            定義
            復制內容到剪貼板
            代碼:
            typedef struct _SYSTEM_SERVICE_TABLE
            {
            ? ?PNTPROC ServiceTable; // array of entry points
            ? ?PDWORD CounterTable; // array of usage counters
            ? ?DWORD ServiceLimit;??// number of table entries
            ? ?PBYTE??ArgumentTable; // array of byte counts
            }
            SYSTEM_SERVICE_TABLE,
            *PSYSTEM_SERVICE_TABLE,
            **PPSYSTEM_SERVICE_TABLE;
            //-----------------------------------------------------------------------------------------------------------
            typedef struct _SERVICE_DESCRIPTOR_TABLE
            {
            ? ?SYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe ( native api )
            ??SYSTEM_SERVICE_TABLE win32k;??// win32k.sys (gdi/user support)
            ? ?SYSTEM_SERVICE_TABLE Table3;??// not used
            ? ?SYSTEM_SERVICE_TABLE Table4;??// not used
            }
            SYSTEM_DESCRIPTOR_TABLE,
            *PSYSTEM_DESCRIPTOR_TABLE,
            **PPSYSTEM_DESCRIPTOR_TABLE;
            其實 KeServiceDescriptorTableShadow包含4個子結構,其中第一個就是ntoskrnl.exe ( native api ),和KeServiceDescriptorTable指向一樣 我們真正需要獲得的是第二個win32k.sys (gdi/user support),第三個和第四個一般不使用

            定位方法
            1。硬編碼
            復制內容到剪貼板
            代碼:
            //for xp
            if(gKernelVersion==WINXP)
            KeServiceDescriptorTableShadow=KeServiceDescriptorTable-0x40;
            //for 2k
            if(gKernelVersion==WIN2K)
            KeServiceDescriptorTableShadow=KeServiceDescriptorTable+0xE0;
            2。搜索KeAddSystemServiceTable
            反匯編代碼可以看出
            復制內容到剪貼板
            代碼:
            lkd> u KeAddSystemServiceTable l 40
            nt!KeAddSystemServiceTable:
            805ba589 8bff? ?? ?mov??edi,edi
            805ba58b 55? ?? ? push??ebp
            805ba58c 8bec? ?? ?mov??ebp,esp
            805ba58e 837d1803? ? cmp??dword ptr [ebp+18h],3
            805ba592 774e? ?? ?ja? ?nt!KeAddSystemServiceTable+0x6b (805ba5e2)
            805ba594 8b4518? ???mov??eax,dword ptr [ebp+18h]
            805ba597 c1e004? ???shl??eax,4
            805ba59a 83b880a6558000 cmp??dword ptr nt!KeServiceDescriptorTable (8055a680)[eax],0
            805ba5a1 753f? ?? ?jne??nt!KeAddSystemServiceTable+0x6b (805ba5e2)
            805ba5a3 8d8840a65580??lea??ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
            805ba5a9 833900? ???cmp??dword ptr [ecx],0
            805ba5ac 7534? ?? ?jne??nt!KeAddSystemServiceTable+0x6b (805ba5e2)
            805ba5ae 837d1801? ? cmp??dword ptr [ebp+18h],1
            805ba5b2 8b5508? ???mov??edx,dword ptr [ebp+8]
            805ba5b5 56? ?? ? push??esi
            805ba5b6 8b7510? ???mov??esi,dword ptr [ebp+10h]
            805ba5b9 57? ?? ? push??edi
            805ba5ba 8b7d14? ???mov??edi,dword ptr [ebp+14h]
            805ba5bd 8911? ?? ?mov??dword ptr [ecx],edx
            805ba5bf 8b4d0c? ???mov??ecx,dword ptr [ebp+0Ch]
            805ba5c2 898844a65580??mov??dword ptr nt!KeServiceDescriptorTableShadow+0x4 (8055a644)[eax],ecx
            805ba5c8 89b048a65580??mov??dword ptr nt!KeServiceDescriptorTableShadow+0x8 (8055a648)[eax],esi
            805ba5ce 89b84ca65580??mov??dword ptr nt!KeServiceDescriptorTableShadow+0xc (8055a64c)[eax],edi
            805ba5d4 0f855a3e0300??jne??nt!KeAddSystemServiceTable+0x4d (805ee434)
            805ba5da 5f? ?? ? pop??edi
            805ba5db b001? ?? ?mov??al,1
            805ba5dd 5e? ?? ? pop??esi
            805ba5de 5d? ?? ? pop??ebp
            805ba5df c21400? ???ret??14h
            805ba5e2 32c0? ?? ?xor??al,al
            805ba5e4 ebf8? ?? ?jmp??nt!KeAddSystemServiceTable+0x6d (805ba5de)
            805ba5e6 90? ?? ? nop
            805ba5e7 90? ?? ? nop
            805ba5e8 90? ?? ? nop
            805ba5e9 90? ?? ? nop
            805ba5ea 90? ?? ? nop
            搜索辦法很簡單
            就是找到
            805ba5a3 8d8840a65580??lea??ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
            的8d88 40a65580??lea??ecx, nt!KeServiceDescriptorTableShadow
            代碼如下
            復制內容到剪貼板
            代碼:
            void GetKeServiceDescriptorTableShadow()
            {
            ??PUCHAR cPtr, pOpcode;
            ??ULONG Length;
            ??
            ??for (cPtr = (PUCHAR)KeAddSystemServiceTable;
            ? ? cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
            ? ? cPtr += Length)
            ??{
            ? ? if (!MmIsAddressValid(cPtr)) break;

            ? ? Length = SizeOfCode(cPtr, &pOpcode);

            ? ? if (!Length || (Length == 1 && *pOpcode == 0xC3)) break;
            ? ?
            ? ? if (*(PUSHORT)pOpcode == 0x888D)
            ? ? {
            ? ?? ?KeServiceDescriptorTableShadow = *(PVOID *)(pOpcode + 2);
            ? ?? ?break;
            ? ? }
            ??}
            }
            3。從KTHREAD.ServiceTable里面搜索
            如果是GUI線程 那么就是指向ServiceDescriptorTableShadow
            其實個人更加傾向這個辦法 穩定安全可靠,上面那個代碼也許會受到以后系統代碼變化影響 但是這個肯定不會
            復制內容到剪貼板
            代碼:
            GetServiceDescriptorTableShadowAddress proc uses esi edi ebx

            local dwThreadId:DWORD

            ??xor ebx, ebx? ?? ???; = NULL. Assume ServiceDescriptorTableShadow will be not found

            ??mov eax, KeServiceDescriptorTable
            ??mov esi, [eax]

            ??; Find KTHREAD.ServiceTable field
            ??; For non-GUI threads this field == KeServiceDescriptorTable
            ??; and it points to ServiceDescriptorTable
            ??; For GUI threads
            ??; ServiceDescriptorTableShadow

            ??invoke KeGetCurrentThread
            ??mov edi, 200h-4
            ??.while edi
            ? ? .break .if dword ptr [eax][edi] == esi
            ? ? dec edi
            ??.endw

            ??.if edi != 0
            ? ? ; edi = offset to ServiceTable field in KTHREAD structure
            ? ? mov dwThreadId, 080h
            ? ? .while dwThreadId < 400h
            ? ?? ?push eax? ?? ?? ? ; reserve DWORD on stack
            ? ?? ?invoke PsLookupThreadByThreadId, dwThreadId, esp
            ? ?? ?pop ecx? ?? ?? ?? ?; -> ETHREAD/KTHREAD
            ? ?? ?.if eax == STATUS_SUCCESS
            ? ?? ???push dword ptr [ecx][edi]
            ? ?? ???fastcall ObfDereferenceObject, ecx
            ? ?? ???pop eax
            ? ?? ???.if eax != esi
            ? ?? ?? ? mov edx, MmSystemRangeStart
            ? ?? ?? ? mov edx, [edx]
            ? ?? ?? ? mov edx, [edx]
            ? ?? ?? ? .if eax > edx? ? ; some stupid error checking
            ? ?? ?? ?? ?mov ebx, eax
            ? ?? ?? ?? ?invoke DbgPrint, $CTA0("FindShadowTable: Found in thread with ID: %X\n"), dwThreadId
            ? ?? ?? ?? ?.break
            ? ?? ?? ? .endif
            ? ?? ???.endif
            ? ?? ?.endif
            ? ?? ?add dwThreadId, 4
            ? ? .endw
            ??.endif

            ??mov eax, ebx
            ??ret

            GetServiceDescriptorTableShadowAddress endp
            4.mj0011所說的搜索有效內存地址的辦法
            復制內容到剪貼板
            代碼:
            /*
            define structure for the system service table
            */
            struct SYS_SERVICE_TABLE {
            void **ServiceTable;
            unsigned long CounterTable;
            unsigned long ServiceLimit;
            void **ArgumentsTable;
            };

            SYSTEM_DESCRIPTOR_TABLE KeServiceDescriptorTableShadow;

            /*
            Define KeServiceDescriptorTable based on the SST structure
            */
            extern struct SYS_SERVICE_TABLE *KeServiceDescriptorTable;

            /*
            Declare function GetServiceDescriptorShadowTableAddress()
            */
            //struct SYS_SERVICE_TABLE * GetServiceDescriptorShadowTableAddress ();
            /*
            Declare the KeAddSystemServiceTable. This is just a
            handle to the call function, it will be used by the function
            above to obtain the correct address of the KeServiceDescriptorShadowTable
            */
            __declspec(dllimport) KeAddSystemServiceTable (ULONG, ULONG, ULONG, ULONG, ULONG);

            struct SYS_SERVICE_TABLE * GetServiceDescriptorShadowTableAddress ()
            {
            // First, obtain a pointer to KeAddSystemServiceTable
            unsigned char *check = (unsigned char*)KeAddSystemServiceTable;
            int i;
            //Initialize an instance of System Service Table, will be used to
            //obtain an address from KeAddSystemServiceTable
            struct SYS_SERVICE_TABLE *rc=0;
            // Make 100 attempts to match a valid address with that of KeServiceDescriptorTable
            for (i=0; i<=99; i++) {
            __try {
            // try to obtain an address from KeAddSystemServiceTable
            rc = *(struct SYS_SERVICE_TABLE**)check;
            // if this address is NOT valid OR it itself is the address of
            //KeServiceDescriptorTable OR its first entry is NOT equal
            //to the first entry of KeServiceDescriptorTable
            if (!MmIsAddressValid (rc) || (rc == KeServiceDescriptorTable)
            ??|| (memcmp (rc, KeServiceDescriptorTable, sizeof (*rc)) != 0)) {
            ??// Proceed with the next address
            ??check++;
            ??// don&#39;t forget to reset the old address
            ??rc = 0;
            }
            } __except (EXCEPTION_EXECUTE_HANDLER) { rc = 0; }
            // when the loop is completed, check if it produced a valid address
            if (rc)
            // because if it didn&#39;t, we failed to find the address of KeServiceDescriptorTableShadow
            break;
            }
            // otherwise, there is a valid address! So return it!
            return rc;
            }
            二。函數名定位
            這個似乎沒有多少好辦法,解析pdb可以是可以 但是很麻煩
            不過還好的是 同一個版本的系統 調用號一樣
            所以只需要3套 2k xp 2k3的調用號就可以完成hook
            pdb辦法
            SymInitialize初始化
            SymSetSearchPath “srv**symbols*http://msdl.microsoft.com/
            SymLoadModule
            SymGetSymFromName
            老v曾經發出1個獲取shadow地址和函數名稱的工具 使用他可以很方便的獲取
            具體代碼可以F5查看
            以上讀取pdb的方法測試使用的可以的
            但是實際使用很麻煩

            經過分析 我找到了1個比較好的定位辦法
            我們以SetWindowsHookExA為例子
            復制內容到剪貼板
            代碼:
            .text:77D311D1 ; HHOOK __stdcall SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId)
            .text:77D311D1? ?? ???public _SetWindowsHookExA@16
            .text:77D311D1 _SetWindowsHookExA@16 proc near
            .text:77D311D1
            .text:77D311D1 idHook? ???= dword ptr 8
            .text:77D311D1 lpfn? ?? ?= dword ptr 0Ch
            .text:77D311D1 hModule? ? = dword ptr 10h
            .text:77D311D1 dwThreadId? ?= dword ptr 14h
            .text:77D311D1
            .text:77D311D1? ?? ???mov??edi, edi
            .text:77D311D3? ?? ???push??ebp
            .text:77D311D4? ?? ???mov??ebp, esp
            .text:77D311D6? ?? ???push??2? ?? ? ; int
            .text:77D311D8? ?? ???push??[ebp+dwThreadId] ; int
            .text:77D311DB? ?? ???push??[ebp+hModule] ; hModule
            .text:77D311DE? ?? ???push??[ebp+lpfn]? ?; int
            .text:77D311E1? ?? ???push??[ebp+idHook]??; int
            .text:77D311E4? ?? ???call??_SetWindowsHookExAW@20 ; SetWindowsHookExAW(x,x,x,x,x)
            .text:77D311E9? ?? ???pop??ebp
            .text:77D311EA? ?? ???retn??10h
            .text:77D311EA _SetWindowsHookExA@16 endp

            .text:77D2DCFD ; int __stdcall SetWindowsHookExAW(int, int, HMODULE hModule, int, int)
            .text:77D2DCFD _SetWindowsHookExAW@20 proc near? ? ; CODE XREF: SetWindowsHookExW(x,x,x,x)+13p
            .text:77D2DCFD? ?? ?? ?? ?? ?? ???; SetWindowsHookExA(x,x,x,x)+13p
            .text:77D2DCFD
            .text:77D2DCFD Filename? ? = word ptr -20Ch
            .text:77D2DCFD var_4? ???= dword ptr -4
            .text:77D2DCFD arg_0? ???= dword ptr 8
            .text:77D2DCFD arg_4? ???= dword ptr 0Ch
            .text:77D2DCFD hModule? ? = dword ptr 10h
            .text:77D2DCFD arg_C? ???= dword ptr 14h
            .text:77D2DCFD arg_10? ???= dword ptr 18h
            .text:77D2DCFD
            .text:77D2DCFD? ?? ???mov??edi, edi
            .text:77D2DCFF? ?? ???push??ebp
            .text:77D2DD00? ?? ???mov??ebp, esp
            .text:77D2DD02? ?? ???sub??esp, 20Ch
            .text:77D2DD08? ?? ???mov??eax, ___security_cookie
            .text:77D2DD0D? ?? ???push??esi
            .text:77D2DD0E? ?? ???mov??esi, [ebp+hModule]
            .text:77D2DD11? ?? ???test??esi, esi
            .text:77D2DD13? ?? ???push??edi
            .text:77D2DD14? ?? ???mov??edi, [ebp+arg_4]
            .text:77D2DD17? ?? ???mov??[ebp+var_4], eax
            .text:77D2DD1A? ?? ???jz? ?short loc_77D2DD33
            .text:77D2DD1C? ?? ???push??104h? ?? ?; nSize
            .text:77D2DD21? ?? ???lea??eax, [ebp+Filename]
            .text:77D2DD27? ?? ???push??eax? ?? ?; lpFilename
            .text:77D2DD28? ?? ???push??esi? ?? ?; hModule
            .text:77D2DD29? ?? ???call??ds:__imp__GetModuleFileNameW@12 ; GetModuleFileNameW(x,x,x)
            .text:77D2DD2F? ?? ???test??eax, eax
            .text:77D2DD31? ?? ???jz? ?short loc_77D2DD52
            .text:77D2DD33
            .text:77D2DD33 loc_77D2DD33:? ?? ?? ?? ? ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+1Dj
            .text:77D2DD33? ?? ???push??[ebp+arg_10]
            .text:77D2DD36? ?? ???mov??eax, esi
            .text:77D2DD38? ?? ???push??edi
            .text:77D2DD39? ?? ???push??[ebp+arg_0]
            .text:77D2DD3C? ?? ???neg??eax
            .text:77D2DD3E? ?? ???push??[ebp+arg_C]
            .text:77D2DD41? ?? ???sbb??eax, eax
            .text:77D2DD43? ?? ???lea??ecx, [ebp+Filename]
            .text:77D2DD49? ?? ???and??eax, ecx
            .text:77D2DD4B? ?? ???push??eax
            .text:77D2DD4C? ?? ???push??esi
            .text:77D2DD4D? ?? ???call??__SetWindowsHookEx@24 ; _SetWindowsHookEx(x,x,x,x,x,x)
            .text:77D2DD52
            .text:77D2DD52 loc_77D2DD52:? ?? ?? ?? ? ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+34j
            .text:77D2DD52? ?? ???mov??ecx, [ebp+var_4]
            .text:77D2DD55? ?? ???pop??edi
            .text:77D2DD56? ?? ???pop??esi
            .text:77D2DD57? ?? ???call??@__security_check_cookie@4 ; __security_check_cookie(x)
            .text:77D2DD5C? ?? ???leave
            .text:77D2DD5D? ?? ???retn??14h
            .text:77D2DD5D _SetWindowsHookExAW@20 endp
            .text:77D2DD5D

            .text:77D2DD65 ; __stdcall _SetWindowsHookEx(x, x, x, x, x, x)
            .text:77D2DD65 __SetWindowsHookEx@24 proc near? ? ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+50p
            .text:77D2DD65
            .text:77D2DD65 var_10? ???= byte ptr -10h
            .text:77D2DD65 var_8? ???= dword ptr -8
            .text:77D2DD65 var_4? ???= dword ptr -4
            .text:77D2DD65 arg_0? ???= dword ptr 8
            .text:77D2DD65 arg_4? ???= dword ptr 0Ch
            .text:77D2DD65 arg_8? ???= dword ptr 10h
            .text:77D2DD65 arg_C? ???= dword ptr 14h
            .text:77D2DD65 arg_10? ???= dword ptr 18h
            .text:77D2DD65 arg_14? ???= dword ptr 1Ch
            .text:77D2DD65
            .text:77D2DD65? ?? ???mov??edi, edi
            .text:77D2DD67? ?? ???push??ebp
            .text:77D2DD68? ?? ???mov??ebp, esp
            .text:77D2DD6A? ?? ???sub??esp, 10h
            .text:77D2DD6D? ?? ???push??[ebp+arg_4]
            .text:77D2DD70? ?? ???and??[ebp+var_4], 0
            .text:77D2DD74? ?? ???lea??eax, [ebp+var_10]
            .text:77D2DD77? ?? ???push??eax
            .text:77D2DD78? ?? ???mov??[ebp+var_8], eax
            .text:77D2DD7B? ?? ???call??ds:__imp__RtlInitUnicodeString@8 ; RtlInitUnicodeString(x,x)
            .text:77D2DD81? ?? ???push??[ebp+arg_14]
            .text:77D2DD84? ?? ???push??[ebp+arg_10]
            .text:77D2DD87? ?? ???push??[ebp+arg_C]
            .text:77D2DD8A? ?? ???push??[ebp+arg_8]
            .text:77D2DD8D? ?? ???push??[ebp+var_8]
            .text:77D2DD90? ?? ???push??[ebp+arg_0]
            .text:77D2DD93? ?? ???call??_NtUserSetWindowsHookEx@24 ; NtUserSetWindowsHookEx(x,x,x,x,x,x)
            .text:77D2DD98? ?? ???leave
            .text:77D2DD99? ?? ???retn??18h
            .text:77D2DD99 __SetWindowsHookEx@24 endp
            .text:77D2DD99

            .text:77D2DDA1 ; __stdcall NtUserSetWindowsHookEx(x, x, x, x, x, x)
            .text:77D2DDA1 _NtUserSetWindowsHookEx@24 proc near??; CODE XREF: _SetWindowsHookEx(x,x,x,x,x,x)+2Ep
            .text:77D2DDA1? ?? ???mov??eax, 1225h
            .text:77D2DDA6? ?? ???mov??edx, 7FFE0300h
            .text:77D2DDAB? ?? ???call??dword ptr [edx]
            .text:77D2DDAD? ?? ???retn??18h
            .text:77D2DDAD _NtUserSetWindowsHookEx@24 endp
            我們看這里 .text:77D2DDA1? ?? ???mov??eax, 1225h
            里面有和ssdt一樣的調用號 但是有個問題 NtUserSetWindowsHookEx在user32里面沒有導出,我們需要多次搜索才行
            復制內容到剪貼板
            代碼:
            HHOOK STDCALL??NtUserSetWindowsHookEx (HINSTANCE Mod, PUNICODE_STRING UnsafeModuleName, DWORD ThreadId, int HookId, HOOKPROC HookProc, BOOL Ansi)
            這個就是原型 不過搜索起來確實是比較麻煩的,不知道還有無其他好辦法了
            国产精品久久毛片完整版| 亚洲午夜久久久久妓女影院| 久久亚洲中文字幕精品一区| 久久精品这里只有精99品| 国产精品免费久久| 国产女人aaa级久久久级| 久久综合欧美成人| 久久精品国产精品亚洲艾草网美妙| 伊人丁香狠狠色综合久久| 精品久久综合1区2区3区激情| 亚洲国产精品久久久久久| 亚洲狠狠综合久久| 欧美伊人久久大香线蕉综合69 | 久久99精品久久久大学生| 一日本道伊人久久综合影| 中文字幕无码免费久久| 97久久精品无码一区二区| 精品亚洲综合久久中文字幕| 久久福利片| 久久国产欧美日韩精品| 精品久久久久久综合日本| 久久精品这里只有精99品| 亚洲国产精品无码久久一线| 久久青青草原综合伊人| 手机看片久久高清国产日韩| 东方aⅴ免费观看久久av| 91精品国产综合久久久久久| 狠狠综合久久综合中文88 | 久久精品人人槡人妻人人玩AV| 国产精品久久久久久| 一本色道久久88综合日韩精品| 久久久国产精品亚洲一区| 久久精品国产精品亚洲下载 | 精品久久久久久中文字幕人妻最新| 久久亚洲高清观看| 日韩欧美亚洲综合久久 | 久久一本综合| 久久线看观看精品香蕉国产| 亚洲午夜久久久| 久久91精品综合国产首页| 国产精品久久久久久|