设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 服务器 > 系统 > 正文

APC Injection of Windows 7 x86 in R0

发布时间:2021-01-04 18:21 所属栏目:52 来源:网络整理
导读:APC Injection of Windows 7 x86 in R0 Introduction When running in kernel mode,it may be necessary to inject code into a User-land process. We can use the Asynchronous Procedure Calls(APCs) to accomplish this goal. An APC can "borrow" a pro

APC Injection of Windows 7 x86 in R0

Introduction

When running in kernel mode,it may be necessary to inject code into a User-land process. We can use the Asynchronous Procedure Calls(APCs) to accomplish this goal. An APC can "borrow" a process thread that is in an idle alertable state,and while it relies on structures whose offset change between versions of Microsoft Windows,it is one of the most reliable and easiest way to exit kernel mode and enter user mode.

In this article,I write some basic knowledge of APC and finished a sample of APC injection which can pop a calculator in windows 7 x86.

Base code is shamelessly stolen from Justgoon .For more information,you can click the link to see his original article : x64与x64下内核APC注入(有码)

https://bbs.pediy.com/thread-222438.htm

What is APCs

? According to the MSND: An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread. When an APC is queued to a thread,the system issues a software interrupt. The next time the thread is scheduled,it will run the APC function. An APC generated by the system is called a kernel-mode APC. An APC generated by an application is called a user-mode APC. A thread must be in an alertable state to run a user-mode APC.

? Each thread has its own APC queue. When a user-mode APC is queued,the thread to which it is queued is not directed to call the APC function unless it is in an alertable state. A thread enters an alertable state when it calls the SleepEx,SingnalObjectAndWait,MsgWaitForMultipleObjectsEx,WaitForMultipleObjetsEx,or WaitForSingleObjectEx function. If the wait is satisfied before the APC is queued,the thread is no longer in an alertable state so the APC function will not be executed. However,the APC is still queued,so the APC function will be executed when the thread calls another alertable wait function.

We can use the dt command in windbg to displays information about the APC‘s.

The _KAPC structure. This is the Kernel Object of the APC.

kd> dt _kapc
ntdll!_KAPC
   +0x000 Type             : //Type of ApcObject
   +0x001 SpareByte0       : 
   +0x002 Size             : 
   +0x003 SpareByte1       : 
   +0x004 SpareLong0       : 
   +0x008 Thread           : //_KTHREAD of current thread
   +0x00c ApcListEntry     : //APC queue of current thread
   +0x014 KernelRoutine    : 
   +0x018 RundownRoutine   : 
   +0x01c NormalRoutine    : 
   +0x020 NormalContext    : //
   +0x024 SystemArgument1  : 
   +0x028 SystemArgument2  : 
   +0x02c ApcStateIndex    : // Apc State
   +0x02d ApcMode          : // UserMode or KernelMode
   +0x02e Inserted         : // inserted into the queue?

APC queue information in the _KTHREAD

kd> dt _kthread
ntdll!_KTHREAD
    ...
   +0x040 ApcState         : _KAPC_STATE
   +0x040 ApcStateFill     : [23] UChar
    ...

In the _KAPC_STATE,the last filed determined if the user APC function be called.

kd> dt _KAPC_STATE
ntdll!_KAPC_STATE
   +0x000 ApcListHead      : [2] _LIST_ENTRY
   +0x010 Process          : Ptr32 _KPROCESS
   +0x014 KernelApcInProgress : UChar
   +0x015 KernelApcPending : UChar
   +0x016 UserApcPending   : UChar // work when set to 1

How to Insert a APC into a process

To insert a APC in the process from r0 to r3,essentially performs the following:

  • Step1: Find the suitable process and thread object which can be injected APC.
  • Step2: Get the target process handle by ObOpenObjectByPointer.
  • Step3: Invokes ZwAllocateVirtualMemory to commit a piece of memory in target process for storing the APC shellcode.
  • Step4: Set the UserApcPending to 1
  • Step5: Invokes KeInitializeApc to initialize a APC object
  • Step6: Invokes KeInsertQueueApc to insert APC to the target thread.

Code

Header.h

#include<ntifs.h>
#include<ntddk.h>


//Some type
#define POINTER ULONG

//EPROCESS OFFSET
#define OBJECTTABLE_OFFSET 0xf4
#define IMAGEFILENAME_OFFSET 0x16c
#define ACTIVEPROCESSLINKS_OFFSET 0xb8
#define THREADLISTHEAD_OFFSET 0x188

//ETHREAD OFFSET
#define THREADLISTENTRY_OFFSET 0x268

//KTHREAD OFFSET
#define TEB_OFFSET  0x88 
#define USERAPCPENDING_OFFSET  0x56

//
typedef enum _KAPC_ENVIRONMENT {
    OriginalApcEnvironment,AttachedApcEnvironment,CurrentApcEnvironment
} KAPC_ENVIRONMENT;
//
VOID DriverUnload(IN PDRIVER_OBJECT pDrvObj);

VOID ThreadFunc(IN PVOID pParam);
BOOLEAN InsertApc(POINTER tarEthread,POINTER addrAllocMem,PKEVENT pKevent);
BOOLEAN FindTargetEProcessAndEthread(POINTER* ptarEprocess,POINTER* ptarEthread);


void UserExec();
void UserExec_end(VOID);


/* Function prototypes for APCs */
VOID
KeInitializeApc(
PKAPC Apc,PKTHREAD Thread,CCHAR ApcStateIndex,PVOID KernelRoutine,PVOID RundownRoutine,PVOID NormalRoutine,KPROCESSOR_MODE ApcMode,PVOID NormalContext
);

INT
KeInsertQueueApc(
PKAPC Apc,PVOID SystemArgument1,PVOID SystemArgument2,UCHAR unknown
);
VOID KernelApcCallback(PKAPC Apc,PVOID *NormalRoutine,PVOID *NormalContext,PVOID* SystemArg1,PVOID* SystemArg2);

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读