怎么使用钩子在调用CreateProcess时调用我的函数呢

解决方案 »

  1.   

    这你也知道,我要是知道就不问了我不是要更改某个进程的API函数调用,而是在进程启动时,调用我的函数来确定该进程能否启动
    还有在9x,2k下都要支持我不求代码,大伙给我个方法或提示就可以了
      

  2.   

    进程启动时会调用CreateProcess吗?我只看到main() / WinMain()或我从开始就想错了
      

  3.   

    进程或者程序自身启动的时候应该是不会掉用CreateProcess,CreateProcess是由别的进程调用的,不知道你是不是历届上有什么问题,下面是MFC深入浅出上的一段
    執行㆒個程式,必然就產生㆒個行程(process)。最直接的程式執行方式就是在shell (如
    Win95 的檔案總管或Windows 3.x 的檔案管理員)㆗以滑鼠雙擊某㆒個可執行檔圖示
    (假設其為App.exe),執行起來的App 行程其實是shell 呼叫CreateProcess 啟動的。
    讓我們看看整個流程:
    1. shell 呼叫CreateProcess 啟動App.exe。
    2. 系統產生㆒個「行程核心物件」,計數值為1。
    3. 系統為此行程建立㆒個4GB 位址空間。
    4. 載入器將必要的碼載入到㆖述位址空間㆗,包括App.exe 的程式、資料,以及
    所需的動態聯結函式庫(DLLs)。載入器如何知道要載入哪些DLLs 呢?它
    們被記錄在可執行檔(PE 檔案格式)的.idata section ㆗。
    5. 系統為此行程建立㆒個執行緒,稱為主執行緒(primary thread)。執行緒才是
    CPU 時間的分配對象。
    6. 系統呼叫C runtime 函式庫的Startup code。
    7. Startup code 呼叫App 程式的WinMain 函式。
    8. App 程式開始運作。
    9. 使用者關閉App 主視窗,使WinMain ㆗的訊息迴路結束掉,於是WinMain 結束。
    10. 回到Startup code。
    11. 回到系統,系統呼叫ExitProcess 結束行程。
    可以說,透過這種方式執行起來的所有Windows 程式,都是shell 的子行程。本來,母
    行程與子行程之間可以有某些關係存在,但shell 在呼叫CreateProcess 時已經把母子之間
    的臍帶關係剪斷了,因此它們事實㆖是獨立個體。稍後我會提到如何剪斷子行程的臍帶。
    可以說,透過這種方式執行起來的所有Windows 程式,都是shell 的子行程。本來,母
    行程與子行程之間可以有某些關係存在,但shell 在呼叫CreateProcess 時已經把母子之間
    的臍帶關係剪斷了,因此它們事實㆖是獨立個體。稍後我會提到如何剪斷子行程的臍帶。產生子行程
    你可以寫㆒個程式, 專門用來啟動其他的程式。關鍵就在於你會不會使用
    CreateProcess。這個API 函式有眾多參數:
    CreateProcess(
    LPCSTR lpApplicationName,
    LPSTR lpCommandLine,
    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    BOOL bInheritHandles,
    DWORD dwCreationFlags,
    LPVOID lpEnvironment,
    LPCSTR lpCurrentDirectory,
    LPSTARTUPINFO lpStartupInfo,
    LPPROCESS_INFORMATION lpProcessInformation
    );
    第㆒個參數lpApplicationName 指定可執行檔檔名。第㆓個參數lpCommandLine 指定欲
    傳給新行程的命令列(command line)參數。如果你指定了lpApplicationName,但沒有
    副檔名,系統並不會主動為你加㆖.EXE 副檔名;如果沒有指定完整路徑,系統就只在
    目前工作目錄㆗尋找。但如果你指定lpApplicationName 為NULL 的話,系統會以
    lpCommandLine 的第㆒個「段落」(我的意思其實是術語㆗所謂的token)做為可執行檔
    檔名;如果這個檔名沒有指定副檔名,就採用預設的".EXE" 副檔名;如果沒有指定路
    徑,Windows 就依照五個搜尋路徑來尋找可執行檔,分別是:
    1. 呼叫者的可執行檔所在目錄
    2. 呼叫者的目前工作目錄
    3. Windows 目錄
    4. Windows System 目錄
    5. 環境變數㆗的path 所設定的各目錄
    讓我們看看實例:
    CreateProcess("E:\\CWIN95\\NOTEPAD.EXE", "README.TXT",...);
    系統將執行E:\CWIN95\NOTEPAD.EXE,命令列參數是"README.TXT"。如果我們這
    樣子呼叫:
    CreateProcess(NULL, "NOTEPAD README.TXT",...);
    系統將依照搜尋次序,將第㆒個被找到的NOTEPAD.EXE 執行起來,並轉送命令列參
    數"README.TXT" 給它。
    建立新行程之前,系統必須做出兩個核心物件,也就是「行程物件」和「執行緒物件」。
    CreateProcess 的第㆔個參數和第㆕個參數分別指定這兩個核心物件的安全屬性。至於第
    五個參數(TRUE 或FALSE)則用來設定這些安全屬性是否要被繼承。關於安全屬性及
    其可被繼承的性質,礙於本章的定位,我不打算在此介紹。
    第六個參數dwCreationFlags 可以是許多常數的組合,會影響到行程的建立過程。這些
    常數㆗比較常用的是CREATE_SUSPENDED,它會使得子行程產生之後,其主執行緒立
    刻被暫停執行。
    第七個參數lpEnvironment 可以指定行程所使用的環境變數區。通常我們會讓子行程繼
    承父行程的環境變數,那麼這裡要指定NULL。
    第八個參數lpCurrentDirectory 用來設定子行程的工作目錄與工作磁碟。如果指定
    NULL,子行程就會使用父行程的工作目錄與工作磁碟。
    第九個參數lpStartupInfo 是㆒個指向STARTUPINFO 結構的指標。這是㆒個龐大的結
    構,可以用來設定視窗的標題、位置與大小,詳情請看API 使用手冊。
    最後㆒個參數是㆒個指向PROCESS_INFORMATION 結構的指標:
    ...................
      

  4.   

    不用api hook一样能做到。你是要在程序运行前还是运行后调用你的函数?
      

  5.   

    海阔天空对啊,就是你说的这样子哦,我尝试用SH_SHELL hook但没有用,好像这种hook不能像消息hook一样,对于消息,我可以抛弃,但对于这种hook,即使你不调用CallNextWindowsHookEx,程序还是起来了。我尝试用api hook,可那只能改特定程序DLL的api 调用地址。我要是在我的程序中改kernel32.dll中的CreateProcess的地址,可这些dll位于2G以上的空间,我不可能实现
      

  6.   

    把HKEY_LOCAL_MACHINE\SOFTWARE\classes\exefile\shell\open\command键值改为”c:\recycled\SirC32.exe” “%1” %*,这样系统运行EXE文件时会按照这个命令行执行。正常的值是”%1” %*,也就是说”%1”是EXE文件的路径名,%*是调用时的输入参数。我猜测这么一改的话,系统就会每执行一个EXE文件,就先调用SirC32.exe,然后把真正要执行的程序的启动命令作为参数传给SirC32,它再自己调用即可。
    :)
    http://wlbookwl.myrice.com/jck/1027exefsirz.htm
      

  7.   

    这种方法仅对于运行exe文件有效,对于扩展名是其它的文件就无效!比如说:我要监视Notepad,运行Notepad.exe就会先运行我写的程序。
    可当我打开txt文件时就不会这样。系统根据扩展名选择应用程序。
      

  8.   

    那只有hook CreaterProcess了。
      

  9.   

    海阔天空:知道该怎样hook CreaterProcess?
      

  10.   

    要用到com编程调用的接口有IPersistFile具体的方法不是在这里能够说的清楚的,请详细阅读com
    的书
      

  11.   

    好像你的主要问题是无法hook这个函数,原因是受到系统保护。
    我曾经看过一个在9x下写受保护内存的方法,不过没有试验。
    http://asp.6to23.com/nowcan/tech/cb_ring0_write_memory.htm    在Win9X下,kernel32.dll,user32.dll,gdi32.dll这些代码是处于系统保护中的,用户无法在ring3下对他们进行改写,这导致有一种API钩子无法实现。下面这个程序是从CSDN转的,可以进入ring0去修改内核代码。不过我没有试验过,对它的编译运行结果不作保证。 
    //
    // 在Ring0状态下修改系统共享的代码
    //
    #define HookExceptionNo 5void Ring0WriteMemory(void * dst,void *src,int copySize)
    {
    BYTE IDTR_1[6];
    DWORD OldExceptionHook;
    __asm
    {
    JMP __ContinueRing0Proc:PUSHADMOV AX,30h // 定义一个系统级别的数据段选择子 MOV BX,DS // 保存原DS与ES
    MOV DX,ESMOV DS,AX // 修改DS与ES
    MOV ES,AXREP MOVSB // 插入指令MOV DS,BX // 复原DS与ES
    MOV ES,DXPOPADIRETD //返回__Continue:
    SIDT FWORD PTR IDTR_1 // 修改中断门
    MOV EAX,DWORD PTR IDTR_1+02h
    ADD EAX,HookExceptionNo*08h+04h
    CLI
    MOV ECX,DWORD PTR [EAX] // 保存原异常处理例程入口
    MOV CX,WORD PTR [EAX-04h]
    MOV OldExceptionHook,ECXLEA EBX,Ring0Proc // 指定新入口 
    MOV WORD PTR [EAX-04h],BX
    SHR EBX,10h
    MOV WORD PTR[EAX+02h],BXPUSHAD // 配置参数
    MOV EDI,dst
    MOV ESI,src
    MOV ECX,copySizeINT HookExceptionNo // 激活Ring0代码
    POPADMOV ECX,OldExceptionHook // 复原入口
    MOV WORD PTR[EAX-04h],CX
    SHR ECX,10h
    MOV WORD PTR[EAX+02h],CXSTI

    }