//拦截 CreateProcessW
function NewCreateProcessW(lpApplicationName: PChar; lpCommandLine: PChar;
      lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
      bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
      lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
      var lpProcessInformation: TProcessInformation): BOOL; stdcall;
type
  TNewCreateProcessW=function (lpApplicationName: PChar; lpCommandLine: PChar;
      lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
      bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
      lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
      var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
  result:=False;
  Exit;做了个hook CreateProcessW的dll,现在能拦截得到,但我想不直接返回False,而是想经过判断后是不是为我想要运行的程序(如QQ.EXE)再给出决定要result True/False.
拦截的时候大多是explorer.exe执行的.我想用内存映射的方法,把lpApplicationName映射,然后我的my.exe读取、监视其有没有发生变化,经过处理后再返回个True/False给那个函数!让它执行成功创建或放弃!
我不会用内存映射,请大家指教!(我在 result:=False;前加上一句showmessage(strpas(lpApplicationName));就会出错,为啥呢?
或有没有什么其它好方法,像360监控到有程序运行,那样!该怎么写!

解决方案 »

  1.   

    hook CreateProcessW时如何通过“内存映射”方法分辨出捕获到的将要运行的程序名称?
      

  2.   

    lpApplicationName就是捕获的程序名!
      

  3.   

    给你转一篇:
    当 Win95与 Winows Nt向内存中装载文件时,使用了特殊的全局内存区。在该区域内,应用程序的虚拟内存地址和文件中的相应位置一一对应。由于所有进程共享了一个用于存储映象文件的全局内存区域,因而当两个进程装载相同模块(应用程序或 DLL文件)时,它们实际可以在内存中共享其执行代码。 笔者通过调用一个带有特殊参数的 CreateFileMapping函数,来间接达到程序间共享内存的目的。下面简要解释一下该函数。 HANDLE CreateFileMapping( HANDLE hFile, //文件句柄  LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // 可选安全属性 DWORD flProtect, // 映象文件保护方式  DWORD dwMaximumSizeHigh, // 映象文件区域的底值  DWORD dwMaximumSizeLow, // 映象文件区域的顶值  LPCTSTR lpName // 映象文件的名字 );  如果 hFile是 0xFFFFFFFF,在调用程序中必须指定 dwMaximumSizeHigh 和 dwMaximumSizeLow参数的值以确定映象文件的大小。通过这样的参数指定,该函数就创建了一个由操作系统页文件支持的特殊逻辑映象文件,而不是由实际操作系统的文件支持的逻辑映象文件。这个逻辑映象文件可以通过复制、继承或者按名字来达到共享。至于其它参数的详细说明,请参看在线帮助。 在建立了映象文件之后,我们可以通过调用另外一个 API函数 MapViewOfFile来访问它的内存,该函数会返回一个指向共享内存块的特定指针。 LPVOID MapViewOfFile( HANDLE hFileMappingObject, // 映象文件句柄  DWORD dwDesiredAccess, // 访问方式  DWORD dwFileOffsetHigh, // 映象文件区域的底值  DWORD dwFileOffsetLow, // 映象文件区域的顶值 DWORD dwNumberOfBytesToMap // 映射字节数 ); 如果 dwNumberOfBytesToMap 是 0,映射整个文件。 以下举例说明: private hMapFile: THandle; MapFilePointer: Pointer; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin hMapFile := CreateFileMapping ( $FFFFFFFF, // 特殊内存映射句柄 nil, page_ReadWrite, 0,10000,  'DdhDemoMappedFile'); // 文件名 if hMapFile <> 0 then MapFilePointer := MapViewOfFile ( hMapFile, // 上面映象文件的句柄 File_Map_All_Access,  0, 0, 0) // 访问整个映象文件 else ShowMessage ('hMapFile = 0'); if MapFilePointer = nil then ShowMessage ('MapFilePointer = nil'); end;   procedure TForm1.BtnWriteClick(Sender: TObject); begin StrCopy (PChar (MapFilePointer), PChar (EditWrite.Text));//把内容写入共享内存 end;   procedure TForm1.BtnReadClick(Sender: TObject); var S: string; begin S := PChar (MapFilePointer);//从共享内存读出内容 EditRead.Text := S; end; 用这种方法,不但可以在不同的程序之间共享数据,还可以在同一程序的不同实例间共享数据。
      

  4.   

    谢谢! 
    SQLDebug_Fan;
    看了你的回答,我已经搞定了!