青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-60  評(píng)論-262  文章-1  trackbacks-0
 
     摘要:   閱讀全文
posted @ 2008-09-05 16:32 free2000fly 閱讀(4642) | 評(píng)論 (32)編輯 收藏
     摘要:   閱讀全文
posted @ 2008-07-30 09:23 free2000fly 閱讀(1529) | 評(píng)論 (0)編輯 收藏
     摘要:   閱讀全文
posted @ 2008-07-24 17:24 free2000fly 閱讀(607) | 評(píng)論 (0)編輯 收藏
之所以有此一問, 是因?yàn)椴煌姹镜?Windows, 甚至同一版本的不同 SP, 其內(nèi)核數(shù)據(jù)結(jié)構(gòu)是不同的, 而開發(fā)驅(qū)動(dòng)程序經(jīng)常要直接操縱這些內(nèi)核數(shù)據(jù)結(jié)構(gòu), 就必須得到 Windows 版本的詳細(xì)信息.

如何在內(nèi)核里取得 windows 詳細(xì)版本號(hào)始終是困擾驅(qū)動(dòng)開發(fā)人的一個(gè)不大不小的問題, 因?yàn)?PsGetVersion 函數(shù)的最后一個(gè)參數(shù)根本就不起作用, 得不到 SP 版本號(hào), 而 RtlGetVersion 函數(shù)是在 Windows XP 才提供的, 不具通用性.

因此, 我寫了一個(gè)函數(shù), 將這兩個(gè)函數(shù)封裝在一起, 讓其首先試圖調(diào)用 RtlGetVersion 函數(shù), 如果失敗了, 表明這肯定是 Windows 2000 及以下系統(tǒng), 目前我們一般只支持到 Windows 2000, 至于 undocumented 內(nèi)核數(shù)據(jù)結(jié)構(gòu), Windows 2000 下的都是一樣的, 所以就不做 sp 版本判斷了.

typedef enum WIN_VER_DETAIL {
    WINDOWS_VERSION_NONE,       //  0
    WINDOWS_VERSION_2K,
    WINDOWS_VERSION_XP,
    WINDOWS_VERSION_2K3,
    WINDOWS_VERSION_2K3_SP1_SP2,
    WINDOWS_VERSION_VISTA,
} WIN_VER_DETAIL;

typedef NTSTATUS (NTAPI * PFN_RtlGetVersion)(OUT PRTL_OSVERSIONINFOW lpVersionInformation);

EXTERN_C WIN_VER_DETAIL GetWindowsVersion()
{
    UNICODE_STRING ustrFuncName = { 0 };
    RTL_OSVERSIONINFOEXW osverinfo = { sizeof(osverinfo) };
    PFN_RtlGetVersion pfnRtlGetVersion = NULL;

    RtlInitUnicodeString(&ustrFuncName, L"RtlGetVersion");
    pfnRtlGetVersion = MmGetSystemRoutineAddress(&ustrFuncName);

    if (pfnRtlGetVersion)
    {
        kdprintf("[xxxxxxxx] Using \"RtlGetVersion\"\n");
        pfnRtlGetVersion((PRTL_OSVERSIONINFOW)&osverinfo);
    }
    else
    {
        kdprintf("[xxxxxxxx] Using \"PsGetVersion\"\n");
        PsGetVersion(&osverinfo.dwMajorVersion, &osverinfo.dwMinorVersion, &osverinfo.dwBuildNumber, NULL);
    }

    kdprintf("[xxxxxxxx] OSVersion NT %d.%d:%d sp%d.%d\n",
        osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber,
        osverinfo.wServicePackMajor, osverinfo.wServicePackMinor);

    if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0) {
        return WINDOWS_VERSION_2K;
    } else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1) {
        return WINDOWS_VERSION_XP;
    } else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2) {
        if (osverinfo.wServicePackMajor==0) {
            return WINDOWS_VERSION_2K3;
        } else {
            return WINDOWS_VERSION_2K3_SP1_SP2;
        }
    } else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0) {
        return WINDOWS_VERSION_VISTA;
    }

    return WINDOWS_VERSION_NONE;
}


posted @ 2008-07-23 01:40 free2000fly 閱讀(3803) | 評(píng)論 (0)編輯 收藏

作者: churui 2005-11-05 12:22

某日,遇到一個(gè)奇怪的程序(你也許并不關(guān)心它的名字,我們就姑且稱它為程序A)。這個(gè)程序是十分霸道的,在與我的程序(你也肯定不會(huì)關(guān)心它的名字,所以我們稱為程序B)同時(shí)執(zhí)行的時(shí)候,總能從程序B(這里也就是進(jìn)程B了)的數(shù)據(jù)段中讀取到一些內(nèi)容。這一點(diǎn)讓我非常不爽,于是我決定給B加入自我保護(hù)的功能,讓A不能輕易的讀取。聽起來有點(diǎn)象“磁心大戰(zhàn)”?呵呵,總之交鋒就是這樣開始的,初衷也非常簡單,而爭奪的過程倒是幾經(jīng)波折。

       在戰(zhàn)斗開始之前,還需要說明的是,這里的AB都是GUI程序,而且B總是先于A執(zhí)行。

       考慮一下A讀取B的數(shù)據(jù)段,我能想到的也就是三種方法:
1.
讀取映象文件  
2.
使用ReadProcessMemory   
3.
注入進(jìn)程B,然后直接讀取。

對(duì)于第一種方法,只要B加一個(gè)簡單的殼,A就無計(jì)可施。所以比較實(shí)用的還是后兩種方法。經(jīng)過觀察,發(fā)現(xiàn)A在執(zhí)行過程中給進(jìn)程B注入了一個(gè)DLL所以我判斷A可能使用的是第三種方法。

       AB注入DLL,一般來說也就是三種方法。但是不管哪種方法,我認(rèn)為最終總要調(diào)用ntdll!LdrLoadDll。于是,最原始的辦法就是在進(jìn)程Bhook LdrLoadDll這個(gè)API,攔截可疑的DLL。實(shí)現(xiàn)的過程并不復(fù)雜,可惜沒有效果。也就是說,A在注入DLL的過程中,根本沒有被B攔截到。

       我使用IceSword,監(jiān)視A的啟動(dòng)過程。發(fā)現(xiàn)A在啟動(dòng)時(shí)會(huì)在每個(gè)進(jìn)程(當(dāng)然,除了一些特殊的系統(tǒng)進(jìn)程如Idlecsrss等等)中創(chuàng)建一個(gè)遠(yuǎn)線程。因此,我希望能把創(chuàng)建遠(yuǎn)線程攔截下來。考慮到一般創(chuàng)建遠(yuǎn)線程之前總要先用kernel32!OpenProcess得到進(jìn)程句柄,我就試圖在ring3使用hook api攔截所有的OpenProcess。可惜我的努力又失敗了。本來hook OpenProcess工作的挺好,但是只要A一啟動(dòng),對(duì)OpenProcesshook馬上失效。考慮到前面hook ntdll!LdrLoadDll也沒有奏效,我認(rèn)為A一定采取了某些防止hook api的手段。

       在這種情況下,我打算到ring0去解決問題。由于之前我只有win32的開發(fā)經(jīng)驗(yàn),而driver幾乎沒有做過,拿著羅云彬老大翻譯的Kmd教程中文版惡補(bǔ)兩天,又在driverdevelop找了一些源碼和資料,終于拼湊出了一個(gè)勉強(qiáng)能運(yùn)行的driver。功能倒也簡單,就是通過修改SSDTSystem Service Dispatch Table)。使得ntdll!NtOpenProcess執(zhí)行到核心態(tài)的時(shí)候,能夠被我攔截下來。

       這次還是失敗了,而且失敗的情況也和ring3如出一轍:本來ntdll!NtOpenProcess能夠被攔截下來的,一旦A啟動(dòng)后,所有的攔截立刻失效。讓我啼笑皆非的是,我做了另外一個(gè)簡單的程序C,唯一的作用就是使用kernel32!OpenProcess去打開B,結(jié)果當(dāng)A啟動(dòng)后,連這個(gè)C也能成功的打開B了。使用IceSword一看,原來A啟動(dòng)后,SSDT會(huì)被自動(dòng)改回最初的內(nèi)容,真讓我無語。

       driverdevelop上向等bmyyyudzhaock等幾位大蝦請(qǐng)教了好幾次,得出了以下的結(jié)論:ntdll中導(dǎo)出了NtOpenProcessZwOpenProcess,而兩者實(shí)際上是一回事。ntosknrl中也導(dǎo)出了NtOpenProcessZwOpenProces,而兩者完全不同:ntosknrl!NtOpenProcess實(shí)際上就是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,不知道它是干什么的。如果修改SSDT,其實(shí)很容易被別人發(fā)現(xiàn)并且破掉(把入口換回NtOpenProcess就可以了)。那么有沒有其他方法?看有的資料上說可以換int 2 e的中斷處理函數(shù),xp中既然用sysenter/syscall,看來這一招也不靈。最終,bmyyyud大蝦提示我,可以改正常ntosknrl!NtOpenProcess的入口代碼。(非入口~~~~)

       修改ntosknrl!NtOpenProcess的入口代碼比修改SSDT難度要大一些。首先ntosknrl!NtOpenProcess的代碼所在頁面具有只讀屬性,在修改頁面前需要先修改CR0寄存器的第16個(gè)bit,否則一定是藍(lán)屏沒商量,對(duì)于我這樣的新手來說,這還真有點(diǎn)讓人無所適從。其次,為了修改入口代碼,最方便的方法是使用微軟的detours,可惜detours中引用了很多ring3API,無法直接使用。只好拿來detours的源碼,把不必要的細(xì)枝末節(jié)都剪裁掉,把所有使用到ring3 API的部分都盡量去掉或者ring0API代替。只留下最關(guān)鍵的部分,試著run了一把,沒想到居然能運(yùn)行。

       這樣做完之后,發(fā)現(xiàn)A程序調(diào)用ntosknrl!NtOpenProcess并且被我攔截了,頗感欣慰……沒想到見鬼的是,在A程序調(diào)用ntosknrl!NtOpenProcess失敗的情況下,它仍然給B創(chuàng)建了一個(gè)遠(yuǎn)線程。這個(gè)時(shí)候zhaock大蝦告訴我,即使不調(diào)用NtOpenProcess也可以調(diào)用PsLookupProcessByProcessIdObOpenObjectByPointer來達(dá)到同樣的目的。看來還需要攔截ntosknrl!NtCreateThread,保險(xiǎn)起見,把ntosknrl!NtReadVirtualMemory也攔截下來。一切做完后,試運(yùn)行,終于把A徹底攔住了,它再也沒能用B中讀出一個(gè)字節(jié)….. 忽然想到huyg師兄曾經(jīng)說的“資料不是最重要的,蠻干才是最重要的”……(不敢茍同~~~~)
posted @ 2008-07-21 15:37 free2000fly 閱讀(1802) | 評(píng)論 (1)編輯 收藏
用 VC6 和 VC71 裝載的 ATL 開發(fā)軟件的人都知道, 當(dāng)我們定義了一個(gè)自銷毀窗口時(shí), 一般在 ATL 窗口類的

virtual void OnFinalMessage(HWND ){...}

函數(shù)內(nèi)加一句

delete this;

然后就返回了. 但是氣人的是, 每次當(dāng)我們返回后, 總有一個(gè)地方斷言失敗,

ATLASSERT(pThis->m_pCurrentMsg == &msg);

Google 了許久, 沒有滿意的解決方案, 包括微軟的方案

http://support.microsoft.com/kb/202110

也不好, 自己想盡辦法還是 "山重水復(fù)疑無路", 后來突然靈光突現(xiàn), 徹底解決, 就一個(gè)函數(shù)調(diào)用而已: IsWindow(...). 現(xiàn)在, 終極解決方案是這樣的:
搜索 atlwin.h 文件內(nèi)的 "ATLASSERT(pThis->m_pCurrentMsg == &msg);" 字符串 (在文件內(nèi)有 3 處), 將其原始內(nèi)容
    LRESULT lRes;
    BOOL bRet 
= pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
    
// restore saved value for the current message
    ATLASSERT(pThis->m_pCurrentMsg == &msg);
    pThis
->m_pCurrentMsg = pOldMsg;
改成
    LRESULT lRes;
    BOOL bRet 
= pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
    
if(FALSE == ::IsWindow(pThis->m_hWnd)) {
        return
 lRes; // 在 CDialogImplBaseT 類里是 return FALSE;  特此說明
    }
    
// restore saved value for the current message
    ATLASSERT(pThis->m_pCurrentMsg == &msg);
    pThis
->m_pCurrentMsg = pOldMsg;
其中紅色的代碼為我們的修正代碼. 萬事大吉. 再也不會(huì)出現(xiàn)斷言失敗了.

道理是這樣的: 如果 pThis 對(duì)象被刪除了的話, 那么 pThis 本身和其成員變量 m_hWnd 都將是一個(gè)無效值, 那么后續(xù)的操作將毫無意義. 因此直接返回, 不用廢話.

真是簡單的思路直指問題的核心啊.

posted @ 2008-07-02 15:44 free2000fly 閱讀(2317) | 評(píng)論 (4)編輯 收藏

原始鏈接: https://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3223434&SiteID=1

Hi Guys,

My goal is to run a program before user even log on to system in vista. Here are couple of links i have already went through. These codes are working fine when ever we are dealing with WinSta0\\default desktop when user is log on but my requirements are different.

http://www.codeproject.com/KB/vista-security/VistaSessions.aspx?fid=406624&sort=Position&noise=3&view=Quick&mpp=50&df=1

http://www.uvnc.com/vista/

http://www.codeproject.com/KB/vista-security/VistaSessionsC_.aspx

Steps that wosks fine
-------------------------------

  1. Get the Active Console SessionId using WTSGetActiveConsoleSessionId
  2. Since I need to launch the application under a system account, I use the token from Winlogon, since Winlogon runs under the system account. So I obtain the process ID of Winlogon and Duplicate the token.
  3. Then I make sure I sent the startupinfo parameter lpDesktop to winsta0\Default since I need to launch my process there.
  4. Then I use CreateProcessAsUser with Winlogon's duplicate token to launch my process into session 1.
  5. That's all. I am done.
I got this working on Vista but I would like to launch a progrma to the WinSta0\\Winlogon desktop. Anyone have any ideas? When I change the desktop to WinSta0\\Winlogon the application does not appear on the logon screen. However, when I run the program on XP it works.

Vista must have the Winlogon Desktop permissions set differently, I added "SeTcbPrivilege" but that did no good. Also, if I look at taskmgr I see the program started along with CreateProcessAsUser not returning any errors. It appears to work, just cannot see the application on the WinSta0\\Winlogon desktop. Anyone have any ideas?

 

==================================================================================================

It works! with vista !!

1. WTSGetActiveConsoleSessionId();
2. WTSQueryUserToken() for winlogon.exe winlogon pid
3. DuplicateTokenEx ()
4. AdjustTokenPrivileges ()
5. CreateProcessAsUser () lpDesktop to Winsta0\Winlogon

Fire the executable via taskscheduler (schtasks.exe) with SYSTEM priveleges.


Muhahahaha , and then if you dont see youre app in the winlogon desktop, try hitting ALT+TAB .... in the winlogon desktop.

I hope microsoft keeps this entry point for showing things on the secure desktop, cause we use it to show the unattended installation progress, I think the secure desktop should stay accessible in future releases.

(btw, I did not test it with FUS Fast User Switching, It worked with a domain account setting, this means Fast User Switching is not enabled).


Much appreciated,

 mon11.

 

==================================================================================================

Fast User Switching is enabled for domain accounts in Vista by default, so that's not necessarily true.

==================================================================================================

AndyCadley,
You are right, I tested it, it works also with FUS.

 

 其他連接:

[1]  http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx

[2]  http://blogs.technet.com/askperf/archive/2007/07/24/sessions-desktops-and-windows-stations.aspx

posted @ 2008-06-28 08:22 free2000fly 閱讀(2251) | 評(píng)論 (0)編輯 收藏
http://blog.tinybrowser.net/archives/926

posted @ 2008-06-21 22:24 free2000fly 閱讀(3720) | 評(píng)論 (11)編輯 收藏
今天終于完成了往 vista 內(nèi)所有 ring 3 進(jìn)程的注入. 包括 csrss.exe 進(jìn)程.

主要的中心思想就是,
    1. 提升本進(jìn)程訪問令牌, 使其有調(diào)試權(quán)限.
    2. 獲得本進(jìn)程的當(dāng)前線程的內(nèi)核對(duì)象的安全描述符, 將其復(fù)制出來備用.
    3. 準(zhǔn)備遠(yuǎn)程線程的執(zhí)行代碼以及執(zhí)行參數(shù). 其中包括 loadlibrarya 和 RtlExitUserThread 調(diào)用, 例子嘛, 本來前一篇文章里有, 再次貼在這里方便各位看官.
#define LoadLibraryA_ADDR       0xDDDDDDDD 
#define RtlExitUserThread_ADDR  0xEEEEEEEE 

static __declspec(naked) DWORD WINAPI ThreadDummy(LPVOID lpParam) 
{
    __asm { 
        push    dword ptr [esp
+4]           ; // 將傳進(jìn)來的線程函數(shù)的參數(shù)壓棧 
        mov     eax, LoadLibraryA_ADDR      ; // LoadLibraryA 或 FreeLibrary 函數(shù)的地址 
        call    eax                         ; // 調(diào)用 LoadLibraryA 函數(shù)
        push    eax                         ; // 將 RtlExitUserThread 函數(shù)的參數(shù)壓棧
        mov     eax, RtlExitUserThread_ADDR ; // RtlExitUserThread 函數(shù)的地址 
        call    eax                         ; // 調(diào)用 RtlExitUserThread 函數(shù)
        ret     4                           ; // 返回 
    } 
}

    4. 以第 2 步獲取的安全描述符以及第 3 步準(zhǔn)備的代碼和數(shù)據(jù)作為參數(shù)調(diào)用 RtlCreateUserThread 函數(shù), 在目標(biāo)進(jìn)程創(chuàng)建遠(yuǎn)線程. 等待執(zhí)行完畢.
    5. 清理第 2 步和第 3 步分配的內(nèi)存. 整個(gè)過程完畢.

總結(jié): 整個(gè) dll injection 的探索開發(fā)歷時(shí)月余, 開始看似順利, 后期艱難困苦. 特別是那個(gè)超級(jí)變態(tài)要求: 必須注入到 csrss.exe 進(jìn)程里去. 從普通的 SetWindowHookEx 和 known dll, 到 CreateRemoteThread, 最后到 NtCreateThread 以及 NtCreateThreadEx, 最后回歸到 RtlCreateUserThread 函數(shù). 中間夾雜了 DPC, APC, 以及在內(nèi)核修改 knowndlls\\kernel32.dll 可執(zhí)行映像 inline hook CreateThread 函數(shù)等等等等. 從應(yīng)用層到內(nèi)核, 再回歸應(yīng)用層, 搞了個(gè)遍.

現(xiàn)在我可以牛逼哄哄的說一句了, Injection DLL? Just so so!!!

順便 BS 一下 Rising, 這個(gè)寶貝殺軟竟然直接 kill 掉了所有遠(yuǎn)程線程函數(shù), 不對(duì)用戶做任何通知和給用戶選擇的機(jī)會(huì). 但我在內(nèi)核修改任何可執(zhí)行映像時(shí), 這個(gè)寶貝卻愉快的告訴我, 我的系統(tǒng)很安全. 再次 BS 一下.

一個(gè)小小的測(cè)試程序, 在這里下載

posted @ 2008-06-20 11:24 free2000fly 閱讀(3278) | 評(píng)論 (11)編輯 收藏

說明: 前段時(shí)間找關(guān)于向系統(tǒng)進(jìn)程注入鏈接庫的文章, 找到這篇, 加入收藏夾, 但后來這個(gè)連接死活打不開了. 就用 google 的 cache 功能將文章 A 在這里. 查閱方便.

For a while now, I've been searching for the optimal way to inject code into privileged Win32 processes like lsass.exe, csrss.exe, and winlogon.exe.

There are many functions such as the LSA and SAM exports that even users logged in with full administrative rights cannot execute
unless they do so under the context of one of these privileged processes.

There are a few tricks that I learned along the way.

First, it is necessary to adjust the token privileges of your program so that debugging (SE_PRIVILEGE_ENABLED) is allowed.

If you are injecting code into a lower privileged process, then this will not be needed.

Also, the target process will need to be opened with PROCESS_ALL_ACCESS rights.

Its all pretty easy on Windows 2000 and XP Service Pack 0 and 1.
On these systems, you can use the documented CreateRemoteThread() function, but first the code you want
to run in the security context of the remote process needs to exist in that process' virtual memory space.
You can put it there by using VirtualAllocEx() and WriteProcessMemory().

With XP SP2 and later (2003, Vista) some new security measures prevent the traditional CreateRemoteThread() function from working properly.
You should be able to open the process, allocate memory on its heap, and write data to the allocated region,
but when trying to invoke the remote thread, it will fail with ERROR_NOT_ENOUGH_MEMORY.

On Vista, I found that an author can substitute the CreateRemoteThread() call with NtCreateThreadEx() export from ntdll.dll
and it will allow for the thread to execute properly. This requires you to auto-detect the version of the operating system and
branch to this different call if on Vista.

Also, this is isn't really a universal solution, because NtCreateThreadEx() doesn't exist on pre-Vista sytsems.
So now we're stuck with using CreateRemoteThread() on 2000 and XP SP 0,1 and NtCreateThreadEx() on Vista.
This is already getting messy, and we still don't have a solution for XP SP2.

Also, the NtCreateThreadEx() function takes an undocumented structure, whose members can be initialized appropriately
by reversing other binaries that use the function, but it looks really ugly in source code since I don't really know what the members are for,
or why particular values are significant.

For XP SP2 I did a little debugging and found that inside CreateRemoteThread(), there is a call to ZwCreateThread() which is an export
from ntdll.dll. The call is made while specifying that the thread should start suspended, which it does properly,
however down the road still inside CreateRemoteThread() before ZwResumeThread() is called, there is a call to CsrClientCallServer()
which fails and eventually leads to the error message.

This behavior makes you wonder, if you can just call ZwCreateThread() directly, then the call to CsrClientCallServer() will be avoided
and the thread will execute. The problem is that ZwCreateThread() doesn't allow one to set the thread start address easily
(you have to configure the INITIAL_TEB members to set EIP to your start address using mostly undocumented structures and functions).

However, this all can be avoided by using the RtlCreateUserThread() function instead,
which configures and calls all the undocumented functions for you, and eventually invokes ZwCreateThread() with the result.
Although RtlCreateUserThread() is undocumented also, its hardly as complex as the rest and is pretty simple to use.

At this point, we can successfully execute remote threads into privileged processes across all target platforms,
but as mentioned before, its pretty messy.

We're using three different, largely undocumented functions and auto-detecting which one to use based on the OS version.

The better solution is to create a secondary program that adds a service object (your injector program)
to the service control manager database on the target system. Since you're administrator, which is required anyway,
you'll be able to add these entries and start the service. This will enable the injector program
to run with different access rights than normal code, and the traditional CreateRemoteThread()
will work properly on Windows 2000, all of XP, and 2003/Vista.

The API functions for adding and controlling the service are documented by MSDN and remain consistent across all of the platforms.

So, what is learned is that we can use a number of different functions to inject code into privileged remote processes,
including RtlCreateUserThread() on XP SP2, and NtCreateThreadEx() on Vista, but the optimal way is to install a temporary service
and allow CreateRemoteThread() to be the single API that accomplishes the task for all platforms.


PS:

Basically the needed access rights are identical to XP: In both OSs you need admin rights for system wide injection. However, in Vista when UAC is enabled even admin users don't have admin rights by default. So you need to right click your exe and choose "run as administrator" (as LeVuHoang has already said). Alternatively you can add a manifest to your exe which will tell Vista that your app needs admin rights. If you do that, you don't need to do the "run as admin" step, anymore. However, the end user will still have to confirm the operation. If you don't like all this you need to inject from a service (see HookProcessTermination demo).

One other thing to look for is that the hook dll needs enough NTFS rights or else it might not be injected into all processes successfully. Vista is a bit more strict there than XP was.

void Inject(HWND hWnd, char* strDll)
{
    GetWindowThreadProcessId(hWnd, 
&pId);
    HANDLE hProcess 
= OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
    LPVOID lpRemoteAddress 
= VirtualAllocEx(hProcess, NULL, strlen(strDll), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, lpRemoteAddress, (LPVOID)strDll, strlen(strDll), NULL);
    CreateRemoteThread(hProcess, NULL, 
0,
        (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(
"Kernel32"), "LoadLibraryA"),
        lpRemoteAddress, 
0, NULL);


The API does not create threads in other sessions (this behavior is documented in MSDN).

One way to load a library into a process of another session is: Create a suspended thread (ntdll!RtlCreateUserThread) at kernel32!ExitThread, schedule an asynchronous procedure call (ntdll!NtQueueApcThread) at kernel32!LoadLibraryEx, resume the thread (kernel32!ResumeThread - this executes the pending APC), and wait for the end of the thread (kernel32!WaitForSingleObject). APCs do not return a value - therefore the return value of kernel32!LoadLibraryEx is lost. There is much more work required to use this method in the exact same manner as CreateRemoteThread(LoadLibrary) (includes reading the PEB’s loader structures).

Other hints:

    * Never ever use CreateRemoteThread on a target process that differs in 'bitness' (kernel32!IsWow64Process). On some Windows versions this freezes your calling thread.
    * Dynamically determine the kernel32’s image base (might not be loaded at all).

 


對(duì)于 RtlCreateUserThread 函數(shù)的線程函數(shù), 以下是個(gè)示例:

#define LoadLibraryA_ADDR       0xDDDDDDDD 
#define RtlExitUserThread_ADDR  0xEEEEEEEE 

static __declspec(naked) DWORD WINAPI ThreadDummy(LPVOID lpParam) 
{
    __asm { 
        push    dword ptr [esp+4]           ; // 將傳進(jìn)來的線程函數(shù)的參數(shù)壓棧 
        mov     eax, LoadLibraryA_ADDR      ; // LoadLibraryA 或 FreeLibrary 函數(shù)的地址 
        call    eax                         ; // 調(diào)用 LoadLibraryA 函數(shù)
        push    eax                         ; // 將 RtlExitUserThread 函數(shù)的參數(shù)壓棧
        mov     eax, RtlExitUserThread_ADDR ; // RtlExitUserThread 函數(shù)的地址 
        call    eax                         ; // 調(diào)用 RtlExitUserThread 函數(shù)
        ret     4                           ; // 返回 
    } 
}

static __declspec(naked) DWORD WINAPI ThreadDummy_end(LPVOID lpParam) 

    __asm { 
        ret     4                            ; 
    } 
}

PUCHAR FindDWordFromBuffer(PUCHAR lpBuffer, UINT cchMax, DWORD dwValue) 

    PUCHAR pResult 
= NULL; 
    UINT nIter 
= 0
    
for (nIter=0; nIter<cchMax; nIter++
    { 
        
if ( *(DWORD *)(lpBuffer + nIter) == dwValue ) { 
            pResult 
= lpBuffer + nIter; 
            
break
        } 
    } 
    
return pResult; 


BOOL BuildRemoteThreadCode(OUT PUCHAR lpCode, UINT cchMax, BOOL bInject) 

    UINT nCodeLen 
= 0
    PUCHAR pIter 
= NULL; 
    DWORD dwFnAddr 
= 0
    
    
if (NULL==lpCode || 0==cchMax) { 
        
return FALSE; 
    } 
    
    nCodeLen 
= (PUCHAR) &ThreadDummy_end - (PUCHAR) &ThreadDummy; 
    
if (nCodeLen > cchMax) { 
        
return FALSE; 
    } 
    
    memcpy((
void *)lpCode, (void *&ThreadDummy, nCodeLen); 
    
    {
        pIter 
= FindDWordFromBuffer(lpCode, nCodeLen, LoadLibraryA_ADDR); 
        
if (NULL == pIter) { 
            
return FALSE; 
        } 
        
        
if (bInject) { 
            dwFnAddr 
= (DWORD) GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryA"); 
        } 
else { 
            dwFnAddr 
= (DWORD) GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "FreeLibrary"); 
        } 
        
        
if (0 == dwFnAddr) { 
            
return FALSE; 
        } 
        
*(DWORD *)pIter = dwFnAddr; 
    } 
    
    {
        pIter 
= FindDWordFromBuffer(lpCode, nCodeLen, RtlExitUserThread_ADDR); 
        
if (NULL == pIter) { 
            
return FALSE; 
        } 
        
        dwFnAddr 
= (DWORD) GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "RtlExitUserThread"); 
        
if (0 == dwFnAddr) { 
            
return FALSE; 
        } 
        
*(DWORD *)pIter = dwFnAddr; 
    } 
    
    
return TRUE; 
}

自己分配一塊足夠大的內(nèi)存, 以這塊內(nèi)存的指針作為參數(shù)調(diào)用 BuildRemoteThreadCode 函數(shù)后, 這塊內(nèi)存就可以寫到目標(biāo)進(jìn)程里面, 并作為 RtlCreateUserThread 函數(shù)的線程函數(shù)執(zhí)行了.

當(dāng)然, 線程函數(shù)的參數(shù), 還是得自己準(zhǔn)備了, 也就是一個(gè)字符串指針或一個(gè)模塊的 HMODULE. 相信大家都會(huì), 不用我廢話了.

posted @ 2008-06-18 17:31 free2000fly 閱讀(2411) | 評(píng)論 (0)編輯 收藏
僅列出標(biāo)題
共6頁: 1 2 3 4 5 6 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            免费国产自线拍一欧美视频| 亚洲影院免费| 中文精品在线| 米奇777在线欧美播放| 欧美激情精品久久久| 亚洲婷婷在线| 亚洲性人人天天夜夜摸| 一本大道久久a久久精品综合| 最新国产成人在线观看| 艳女tv在线观看国产一区| 亚洲色图制服丝袜| 欧美在线视频导航| 欧美激情91| 亚洲婷婷综合色高清在线| 99re66热这里只有精品3直播| 中日韩视频在线观看| 性色av一区二区三区| 欧美一激情一区二区三区| 性伦欧美刺激片在线观看| 久久久99精品免费观看不卡| 久久精品国产精品亚洲精品| 玖玖精品视频| 欧美一区二区三区久久精品茉莉花 | 香蕉亚洲视频| 亚洲精品久久久久久一区二区| 亚洲视频免费看| 亚洲福利在线看| 亚洲一区二区在线免费观看| 亚洲精品无人区| 性欧美videos另类喷潮| 一区二区三区精品视频在线观看| 欧美一区二区女人| 性欧美大战久久久久久久久| 欧美日韩国产欧| 亚洲第一黄网| 一色屋精品视频在线看| 亚洲欧美日韩在线播放| 亚洲一区欧美一区| 亚洲春色另类小说| 亚洲韩国精品一区| 久久精品99国产精品| 久久在线91| 国产一级久久| 亚洲成色777777女色窝| 小黄鸭精品密入口导航| 日韩性生活视频| 国产精品99久久久久久有的能看 | 亚洲综合视频网| 亚洲欧美99| 国产精品理论片| 在线观看国产成人av片| 国内揄拍国内精品少妇国语| 亚洲国内自拍| 国产精品亚洲综合一区在线观看| 欧美亚洲一级片| 亚洲天堂第二页| 欧美一区二区在线免费观看 | 欧美日韩成人网| 久久精品123| 国产中文一区| 亚洲精品视频在线播放| 亚洲国产成人精品久久| 99精品久久久| 欧美午夜性色大片在线观看| 国产亚洲激情在线| 久久婷婷蜜乳一本欲蜜臀| 亚洲欧洲一区二区三区在线观看| 欧美va亚洲va香蕉在线| 国产精品免费福利| 欧美在线www| 亚洲三级国产| 国产精品你懂的在线| 亚洲精品久久久久久久久久久久| 欧美精品观看| 一二三区精品福利视频| 久久精品一本久久99精品| 久久aⅴ国产欧美74aaa| 欧美体内谢she精2性欧美| 西西裸体人体做爰大胆久久久| 亚洲福利免费| 亚洲精品美女免费| 蜜月aⅴ免费一区二区三区| 日韩视频一区二区在线观看 | 伊伊综合在线| 美女啪啪无遮挡免费久久网站| 日韩一级免费| 国产一区二区三区黄视频| 9l视频自拍蝌蚪9l视频成人| 一本一道久久综合狠狠老精东影业 | 久久gogo国模裸体人体| 免费在线欧美黄色| 欧美aⅴ一区二区三区视频| 午夜精品在线视频| 欧美精品成人| 欧美成人蜜桃| 欧美国产日本| 欧美国产精品日韩| 免费成人性网站| 欧美99在线视频观看| 国产欧美精品一区二区色综合| 久久久久在线观看| 一区二区三区高清不卡| 亚洲无人区一区| 久久黄色影院| 国产精品日韩欧美一区二区三区| 欧美一级成年大片在线观看| 99re6这里只有精品视频在线观看| 亚洲图色在线| 欧美精品v日韩精品v国产精品 | 亚洲免费视频网站| 亚洲在线日韩| 亚洲伦伦在线| 亚洲黄色精品| 国产精品视频男人的天堂| 中文在线资源观看网站视频免费不卡| 老司机午夜精品视频| 牛夜精品久久久久久久99黑人| 午夜精品久久久久久久蜜桃app | 亚洲欧洲在线视频| 国产欧美日韩一区| 午夜国产精品视频| 欧美成人福利视频| 国产一区二区三区av电影| 91久久久精品| 欧美性大战久久久久| 欧美aaa级| 亚洲另类自拍| 久久精品免费| 久久久午夜电影| 亚洲国产精品精华液2区45| 亚洲一区欧美激情| 国产综合视频在线观看| 一区二区三区日韩| 国产午夜精品美女视频明星a级| 欧美二区在线观看| 日韩午夜高潮| 亚洲精品小视频| 在线亚洲一区二区| 欧美国产亚洲精品久久久8v| 欧美一区二区三区的| 久热这里只精品99re8久| 久久久久久香蕉网| 午夜视频久久久久久| 久久精品亚洲国产奇米99| 老司机精品视频一区二区三区| 亚洲免费中文字幕| 欧美粗暴jizz性欧美20| 日韩网站在线| 免费观看亚洲视频大全| 欧美三级电影大全| 久久一本综合频道| 伊人成人在线| 亚洲无吗在线| 欧美一级大片在线观看| 欧美777四色影视在线| 欧美国产欧美亚州国产日韩mv天天看完整| 欧美精品v日韩精品v国产精品| 亚洲激情在线观看视频免费| 黄色成人91| 麻豆freexxxx性91精品| 欧美在线观看一二区| 国产日韩欧美在线播放不卡| 亚洲人午夜精品免费| 亚洲午夜免费视频| 国产精品蜜臀在线观看| 亚洲美女在线观看| 久久久www| 国产精品午夜国产小视频| 欧美在线看片a免费观看| 欧美亚洲网站| 久久久噜噜噜久久中文字免| 亚洲欧美影院| 在线观看国产日韩| 久久久久久久91| 久久深夜福利免费观看| 国产精品影院在线观看| 亚洲激情欧美激情| 亚洲精品一区二区三区四区高清| 久久亚洲国产精品一区二区| 久久精品123| 韩日欧美一区| 免费成人性网站| 久久另类ts人妖一区二区| 亚洲美女av电影| 欧美久久99| 亚洲在线中文字幕| 亚洲一区二区成人| 娇妻被交换粗又大又硬视频欧美| 久久国产精品黑丝| 亚洲精品一区二区三区樱花| 亚洲欧洲另类| 国产精品视频不卡| 一区二区三区国产在线观看| 久久久精品动漫| 亚洲欧美另类国产| 一区二区三区欧美日韩| 极品少妇一区二区三区| 久久久久久久999精品视频| 一区二区三区日韩精品| 欧美大片一区二区|