网上有很多关于ring3下清零结束进程的c代码,不完整,所以用Delphi重写,提供给喜欢Delphi的朋友。
unit Clear0;

interface

uses
windows,SysUtils,TLHelp32;


const
STATUS_SUCCESS                            = $00000000;
STATUS_ACCESS_VIOLATION                   = $C0000005;
STATUS_UNSUCCESSFUL                       = $C0000001;
SystemSessionProcessesInformation         = 53;




type
NTSTATUS                 = DWORD;
PVOID                    = Pointer;
PPVOID                   =  PPointer;
SYSTEM_INFORMATION_CLASS = ULONG;
ULONG_PTR = PULONG;


PLARGE_INTEGER = ^_LARGE_INTEGER;
    _LARGE_INTEGER = record
    LowPart: ULONG;
    HighPart: ULONG;
    end;


    PUnicodeString = ^TUnicodeString;
    TUnicodeString = packed record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
    end;

   PIoStatusBlock=^TIoStatusBlock;
   TIoStatusBlock=packed record
   Status:NTSTATUS;
   Information:Cardinal;                         //ULONG_PTR
    end;
  IO_STATUS_BLOCK=TIoStatusBlock;
  PIO_STATUS_BLOCK=^IO_STATUS_BLOCK;

  PObjectAttributes=^TObjectAttributes;
  TObjectAttributes=packed record
  Length:Cardinal;
  RootDirectory:THandle;
  ObjectName:PUnicodeString;
  Attributes:Cardinal;
  SecurityDescriptor:Pointer;
  SecurityQualityOfService:Pointer;
   end;
  OBJECT_ATTRIBUTES=^TObjectAttributes;
  POBJECT_ATTRIBUTES=^OBJECT_ATTRIBUTES;

 PClientId=^TClientId;
 TClientId=packed record
  UniqueProcess:Cardinal;
  UniqueThread:Cardinal;
 end;
 CLIENT_ID=TClientId;
 PCLIENT_ID=^CLIENT_ID;



 PROCESS_BASIC_INFORMATION=^TPROCESS_BASIC_INFORMATION;
 TPROCESS_BASIC_INFORMATION =packed record
   ExitStatus:NTSTATUS;
   PebBaseAddress:ULONG;
   AffinityMask:ULONG;
   BasePriority:ULONG;
   UniqueProcessId:ULONG;
   InheritedFromUniqueProcessId:ULONG;
  end;


 PSYSTEM_HANDLE_INFORMATION=^TSYSTEM_HANDLE_INFORMATION;
 TSYSTEM_HANDLE_INFORMATION=packed record
 ProcessID:ULONG;         //进程的标识ID
 ObjectTypeNumber:UCHAR;         //对象类型
 Flags:UCHAR;              //0x01 = PROTECT_FROM_CLOSE,0x02 = INHERIT
 Handle:WORD;              //对象句柄的数值
 PObject:PVOID   ;             //对象句柄所指的内核对象地址
 GrantedAccess:ACCESS_MASK;       //创建句柄时所准许的对象的访问权
  end;




function ZwQuerySystemInformation(SystemInformationClass: SYSTEM_INFORMATION_CLASS; SystemInformation: PVOID; SystemInformationLength: ULONG; lpReturnLength: PULONG): NTSTATUS;stdcall; external 'ntdll.dll';
function ZwOpenProcess(ProcessHandle:PHandle;DesiredAccess:ACCESS_MASK;ObjectAttributes:PObjectAttributes;ClientId:PClientId):NTSTATUS; stdcall; external 'ntdll.dll';
function ZwDuplicateObject(SourceProcessHandle:THANDLE; SourceHandle:THANDLE; TargetProcessHandle:THANDLE; TargetHandle: PHANDLE; DesiredAccess: ACCESS_MASK; Attributes: ULONG; Options: ULONG): NTSTATUS; stdcall;external 'ntdll.dll';
function ZwQueryInformationProcess(ProcessHandle:THANDLE; ProcessInformationClass: ULONG; ProcessInformation: PVOID; ProcessInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;external 'ntdll.dll';
function ZwAllocateVirtualMemory(ProcessHandle:THANDLE; BaseAddress: PPVOID; ZeroBits: ULONG; RegionSize: PULONG; AllocationType: ULONG; Protect: ULONG): NTSTATUS; stdcall;external 'ntdll.dll';
function ZwProtectVirtualMemory(ProcessHandle:THANDLE; BaseAddress: PPVOID; ProtectSize: PULONG; NewProtect: ULONG; OldProtect: PULONG): NTSTATUS; stdcall;external 'ntdll.dll';
function ZwWriteVirtualMemory(ProcessHandle:THANDLE;BaseAddress:PVOID;Buffer:PVOID;BufferLength:ULONG;ReturnLength: PULONG):NTSTATUS;stdcall;external 'ntdll.dll';
function ZwFreeVirtualMemory(rocessHandle:THANDLE;BaseAddress:PPVOID;FreeSize:PULONG;FreeType:ULONG):NTSTATUS;stdcall;external 'ntdll.dll';
function ZwClose(Handle: THandle): NTSTATUS; stdcall;external 'ntdll.dll';


//要用到函数
function EnablePrivilege(hToken: Cardinal; PrivName: string; bEnable: Boolean): Boolean;
function GetPidByName (szName:pchar):DWORD;
function KillProcess (dwProcessId:ULONG):BOOL;


implementation

function EnablePrivilege(hToken: Cardinal; PrivName: string; bEnable: Boolean): Boolean;
var
tp: TOKEN_PRIVILEGES;
Dummy: Cardinal;
begin
result:=false;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken)) then
begin
tp.PrivilegeCount := 1;
LookupPrivilegeValue(nil, PAnsichar(PrivName), tp.Privileges[0].Luid);
if bEnable then
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
tp.Privileges[0].Attributes := 0;
Dummy:=0;
AdjustTokenPrivileges(hToken, False, TP, SizeOf(TP), nil, Dummy);
Result := GetLastError = ERROR_SUCCESS;
CloseHandle(hToken);
end;
end;




function GetPidByName (szName:pchar):DWORD;
var
hProcessSnap:THANDLE;
pe32:TProcessEntry32;
dwRet:DWORD;
begin
   hProcessSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
   if (hProcessSnap = INVALID_HANDLE_VALUE) then
   begin
   Result:=0;
   Exit;
   end;

   pe32.dwSize:=sizeof(pe32);
   dwRet:=0;
   if Process32First(hProcessSnap,pe32) then
   begin
    repeat
      if  UpperCase(strpas(szName))=UpperCase(pe32.szExeFile) then
      begin
       dwRet:=pe32.th32ProcessID;
       break;
      end;
    until (Process32Next(hProcessSnap,pe32)=FALSE);
   end;
 CloseHandle(hProcessSnap);
 Result:=dwRet;
end;


function KillProcess (dwProcessId:ULONG):BOOL;
label send;
var
ph, h_dup:THANDLE;
client_id:TClientId;
csrss_id:THANDLE;
h_info:PSYSTEM_HANDLE_INFORMATION ;
pbi:TPROCESS_BASIC_INFORMATION ;
attr:TObjectAttributes;
buf:PVOID;
bytesIO,NumOfHandle:ULONG;
i:integer;
pAddress0,pAddress1 :pvoid;
sz,oldp:ULONG;
begin
  csrss_id:=THANDLE(GetPidByName ('csrss.exe'));
  client_id.UniqueProcess:= csrss_id;
  client_id.UniqueThread:=0;

  attr.Length:=24;
  attr.RootDirectory:=0;
  attr.ObjectName:= nil;
  attr.Attributes:= 0;
  attr.SecurityDescriptor:= nil;
  attr.SecurityQualityOfService:= nil;

  //打开CSRSS.EXE,获得其句柄
  ZwOpenProcess(@ph,PROCESS_ALL_ACCESS,@attr,@client_id);
  bytesIO:=$400000;
  buf:=0;
  ZwAllocateVirtualMemory(GetCurrentProcess(), @buf, 0, @bytesIO, MEM_COMMIT, PAGE_READWRITE);
  ZwQuerySystemInformation(16,buf,$400000,@bytesIO);
  NumOfHandle:=ULONG(buf);
  h_info:=PSYSTEM_HANDLE_INFORMATION(DWORD(buf)+4);
  i:=0;
  while (i< NumOfHandle) do
  begin
  if( (h_info.ProcessID=ULONG(csrss_id)) and (h_info.ObjectTypeNumber=5) ) then
   begin
    if (ZwDuplicateObject(ph,THANDLE(h_info.Handle),THANDLE(-1),@h_dup,0,0,DUPLICATE_SAME_ACCESS)=STATUS_SUCCESS) then

    ZwQueryInformationProcess(h_dup, 0, @pbi, sizeof(pbi), @bytesIO);

   //找到该进程的内存位置 ,开始清0
    if ( pbi.UniqueProcessId = dwProcessId )  then
    begin
    MessageBox(0, '要结束的进程目标已确定!', '提示', MB_OK);
    i:=$1000;
    while(i<$80000000) do
    begin
    pAddress0 := PVOID(i);
    pAddress1:=pAddress0;
    sz:=$1000;
    if (ZwProtectVirtualMemory (h_dup, @pAddress1, @sz, PAGE_EXECUTE_READWRITE, @oldp) = STATUS_SUCCESS)then
    ZwWriteVirtualMemory(h_dup, pAddress0, buf, $1000, @oldp);
    i:=i+$1000;
    end;
     MessageBox(0, '任务已完成!','提示', 0);
     ZwClose(h_dup);
     goto send;
    end;
 end;
  inc(i);
  h_info:=PSYSTEM_HANDLE_INFORMATION(DWORD(h_info)+sizeof(TSYSTEM_HANDLE_INFORMATION));
  end;
send:
  bytesIO:= 0;
 ZwFreeVirtualMemory(GetCurrentProcess(), @buf, @bytesIO, MEM_RELEASE);
end;

end.