我现在正在做一个考试系统,要求学生端的程序被启动后不能在“任务管理器中显示”,也不能在进程里显示!在98下我将它写成service就可以了!但在2000/NT下
怎么做?而且我的程序是MFC并且代界面,不能写成DLL,望高手指点一二!网络上大部分都是将自己的进程注入到已有进程里!有没有其他方法啊!

解决方案 »

  1.   

    为什么不能写成DLL?DLL里面也可以有窗口吧。
      

  2.   

    在WIN2K/NT下可以实现真正的进程隐身,我已经实现了,不是利用DLL,也不
    用远程线程,但是需要写驱动,你用SOFTICE跟一下系统中进程枚举的实现,
    就知道怎么做了。
      

  3.   

    可以替换系统的DLL,导出系统函数,再加上自己的函数。
      

  4.   

    BOOL WINAPI Process32First(
    HANDLE hSnapshot      // 
    由 CreateToolhelp32Snapshot 返回
                                 的系统快照句柄;
        LPPROCESSENTRY32 lppe // 指向一个 PROCESSENTRY32 结构;
      );
      BOOL WINAPI Process32Next(
        HANDLE hSnapshot      // 由 CreateToolhelp32Snapshot 返回
                                 的系统快照句柄;
        LPPROCESSENTRY32 lppe // 指向一个 PROCESSENTRY32 结构;
      );
    hSnapshot 由 CreateToolhelp32Snapshot 返回的系统快照句柄;
    CreateToolhelp32Snapshot 原形如下:
      HANDLE WINAPI CreateToolhelp32Snapshot(
        DWORD dwFlags,      // 快照标志; 
        DWORD th32ProcessID // 进程ID;
      );
    现在需要的是进程的信息,所以将 dwFlags 
    指定为 TH32CS_SNAPPROCESS,
    th32ProcessID 忽略;PROCESSENTRY32 结构如下:
      typedef struct tagPROCESSENTRY32 { 
        DWORD dwSize;             // 结构大小;
        DWORD cntUsage;           // 此进程的引用计数;
        DWORD th32ProcessID;      // 进程ID;
        DWORD th32DefaultHeapID;  // 进程默认堆ID;
        DWORD th32ModuleID;       // 进程模块ID;
        DWORD cntThreads;         // 此进程开启的线程计数;
        DWORD th32ParentProcessID;// 父进程ID;
        LONG  pcPriClassBase;     // 线程优先权;
        DWORD dwFlags;            // 保留; 
        char szExeFile[MAX_PATH]; // 进程全名;
      } PROCESSENTRY32;---- 至此,所用到的主要函数已介绍完,实现读内存只要从下到上依次调用上述函数即可,具体参见原代码: 
    procedure TForm1.Button1Click(Sender: TObject);
    var
      FSnapshotHandle:THandle;
      FProcessEntry32:TProcessEntry32;
      Ret : BOOL;
      ProcessID : integer;
      ProcessHndle : THandle;
      lpBuffer:pByte;
      nSize: DWORD;
      lpNumberOfBytesRead: DWORD;
      i:integer;
      s:string;
    begin
      FSnapshotHandle:=CreateToolhelp32Snapshot(
    TH32CS_SNAPPROCESS,0);
        //创建系统快照
      FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
        //先初始化 FProcessEntry32 的大小
      Ret:=Process32First(FSnapshotHandle,FProcessEntry32);
      while Ret do
      begin
        s:=ExtractFileName(FProcessEntry32.szExeFile);
        if s='KERNEL32.DLL' then
        begin
          ProcessID:=FProcessEntry32.th32ProcessID;
          s:='';
          break;
        end;
        Ret:=Process32Next(FSnapshotHandle,FProcessEntry32);
      end;
       //循环枚举出系统开启的所有进程,找出“Kernel32.dll”
      CloseHandle(FSnapshotHandle);
      Memo1.Lines.Clear ;
      memo1.lines.add('Process ID '+IntToHex(
      FProcessEntry32.th32ProcessID,8));
      memo1.lines.Add('File name '+FProcessEntry32.szExeFile);
        ////输出进程的一些信息 
      nSize:=4;
      lpBuffer:=AllocMem(nSize);
      ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,ProcessID);
      memo1.Lines.Add ('Process Handle '+intTohex(ProcessHndle,8));
      for i:=$00800001 to $0080005f do
      begin
        ReadProcessMemory(
                         ProcessHndle,
                         Pointer(i),
                         lpBuffer,
                         nSize,
                         lpNumberOfBytesRead
                         );
        s:=s+intTohex(lpBuffer^,2)+' ';
          //读取内容
        if (i mod 16) =0 then
        begin
          Memo1.Lines.Add(s);
          s:='';
        end;
          //格式化输出
      end;
      FreeMem(lpBuffer,nSize);
      CloseHandle(ProcessHndle);
       //关闭句柄,释放内存
    end;
      

  5.   

    可以做成服务的,详细在《window2000技术内幕》里有几个函数可以,具体你要用找一下了