看到http://bbs.pediy.com/showthread.php?t=83385说如何像dbgview那样的应用程序来接收驱动的dbgprint.........可以拦截int 2d来简单实现....碰巧刚写了点代码...帖上来吧...只是测试的代码..很不稳定....
下面的代码拦截了int 3/ int 1 int 2d
本意是设置CPU单补状态来分析异常的执行EIP的...
#include "ntddk.h"
#include <stdio.h>
#define MAKELONG(a, b) ((unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned short) (b))) << 16))
#define MAX_IDT_ENTRIES 0xFF
#define NT_INT_TIMER 0x3
unsigned long g_i_count = 0;
///////////////////////////////////////////////////
// IDT structures
///////////////////////////////////////////////////
#pragma pack(1)
// entry in the IDT, this is sometimes called
// an "interrupt gate"
typedef struct
{
unsigned short LowOffset;
unsigned short selector;
unsigned char unused_lo;
unsigned char segment_type:4; //0x0E is an interrupt gate
unsigned char system_segment_flag:1;
unsigned char DPL:2; // descriptor privilege level
unsigned char P:1; /* present */
unsigned short HiOffset;
} IDTENTRY;
/* sidt returns idt in this format */
typedef struct
{
unsigned short IDTLimit;
unsigned short LowIDTbase;
unsigned short HiIDTbase;
} IDTINFO;
#pragma pack() // naked functions have no prolog/epilog code - they are functionally like the
// target of a goto statement
typedef struct _KINT_STACK_INFO
{
ULONG ret_eip;
ULONG saved_cs;
ULONG saved_eflags;
ULONG saved_esp;
ULONG saved_ss;
ULONG saved_eax;
ULONG saved_ebx;
ULONG saved_ecx;
ULONG saved_edx;
ULONG saved_esi;
ULONG saved_edi;
ULONG saved_ebp;
ULONG saved_pid;
}KINT_STACK_INFO;
typedef struct _REG_INFO
{
ULONG saved_eax;
ULONG saved_ebx;
ULONG saved_ecx;
ULONG saved_edx;
ULONG saved_esi;
ULONG saved_edi;
ULONG saved_ebp;
ULONG saved_esp;
}REG_INFO;
KINT_STACK_INFO g_kstack_info = {0};
REG_INFO g_reg_info = {0}; #define MAX_BREAKPOINT 10
//breakpoint_info g_breakpoint_array[MAX_BREAKPOINT] = {0};
typedef struct _breakpoint_info
{
ULONG cur_breakpoint_count;
struct _breakpoint_array
{
ULONG u_address;
UCHAR byte_code[4]; // byte_code[0] 原始byte
}breakpoint_array[MAX_BREAKPOINT];
}breakpoint_info;
char save_byte[4] = {0};
breakpoint_info g_breakpoint_array = {0};
#define ENABLE_WRITE { \
__asm cli \
__asm mov eax,cr0 \
__asm and eax, not 0x10000 \
__asm mov cr0,eax \
}
#define DISANBLE_WRITE { \
__asm mov eax,cr0 \
__asm or eax,0x10000 \
__asm mov cr0,eax \
__asm sti \
}
BOOLEAN insert_breakpoint(PVOID u_address)
{
int i = 0, j= -1;
if(MmIsAddressValid(u_address) == FALSE)
{
return FALSE;
}
for( i; i<MAX_BREAKPOINT; i++)
{
if(g_breakpoint_array.breakpoint_array[i].byte_code[0] == 0)
{
j = i;
break;
}
}
if( j == -1) return FALSE; ENABLE_WRITE
__asm
{
mov ebx,u_address
mov al,0xcc
mov ah,byte ptr[ebx]
mov save_byte[0],ah
mov byte ptr[ebx],al
}
g_breakpoint_array.breakpoint_array[j].u_address = (ULONG)u_address;
g_breakpoint_array.breakpoint_array[j].byte_code[1] = *(UCHAR*)u_address;
g_breakpoint_array.breakpoint_array[j].byte_code[0] = 1;
g_breakpoint_array.cur_breakpoint_count++ ;
DISANBLE_WRITE
return TRUE;
}
int z = 0;
int tmp_addr;
BOOLEAN b_steping = FALSE; LIST_ENTRY hbpdata_list;
typedef struct _BP_DATA
{
KINT_STACK_INFO bp_context;
LIST_ENTRY ListEntry;
}BP_DATA, *PBP_DATA;
PBP_DATA gp_bpdata = NULL;
NTKERNELAPI ULONG NTAPI RtlWalkFrameChain(OUT PVOID *Callers,
IN ULONG Count,
IN ULONG Flags);
PVOID Callers[128];
ULONG nCount =0;
ULONG i; __declspec(naked) my_interrupt_hook()
{
nCount = RtlWalkFrameChain(Callers,16,0);
if(nCount>0)
{
for(i=0;i<nCount;i++)
{
DbgPrint("stack %x",Callers[i]);
}
}
RtlZeroMemory(&g_kstack_info,sizeof(KINT_STACK_INFO));
// g_pcur_tss = (struct _KTSS*)(*(ULONG*)(0xffdff000+0x40));
// DbgPrint("--%d\n",PsGetCurrentProcessId());
__asm
{
pushfd;
push eax
pushad // EAX,ECX,EDX,EBX,ESP,EBP,ESI和EDI
mov g_kstack_info.saved_eax,eax
mov g_kstack_info.saved_ecx,ecx
mov g_kstack_info.saved_ebx,ebx
mov g_kstack_info.saved_edx,edx
mov g_kstack_info.saved_esi,esi
mov g_kstack_info.saved_edi,edi
mov g_kstack_info.saved_ebp,ebp
mov g_kstack_info.saved_esp,esp
mov eax,[esp+8+32]
mov g_kstack_info.ret_eip, eax
xor eax,eax
mov eax,[esp+12+32]
mov g_kstack_info.saved_cs,eax
xor eax,eax
mov eax,[esp+16+32]
mov g_kstack_info.saved_eflags, eax
xor eax,eax
/* mov eax,[esp+20+32]
mov g_kstack_info.saved_esp, eax
xor eax,eax*/
mov eax,[esp+24+32]
mov g_kstack_info.saved_ss,eax
xor eax,eax
cmp g_kstack_info.saved_cs,0x1b
jz __RING3
mov eax,[esp+8+32]
dec eax
mov tmp_addr,eax
}
for(z = 0; z<MAX_BREAKPOINT; z++)
{
if((g_breakpoint_array.breakpoint_array[z].byte_code[0] == 1)&&
g_breakpoint_array.breakpoint_array[z].u_address == tmp_addr)
{
//DbgPrint("--%d\n",PsGetCurrentProcessId());
g_kstack_info.saved_pid = (ULONG)PsGetCurrentProcessId();
__asm xor eax,eax
__asm mov eax,tmp_addr
__asm mov [esp+8+32], eax
ENABLE_WRITE
*(UCHAR*)tmp_addr = save_byte[0];
DISANBLE_WRITE
g_breakpoint_array.breakpoint_array[z].byte_code[0] = 0;
g_breakpoint_array.breakpoint_array[z].u_address = 0;
break;
}
}
gp_bpdata = (PBP_DATA)ExAllocatePool(NonPagedPool,sizeof(BP_DATA));
if(gp_bpdata != NULL)
{
//strcpy(gp_dbdata->db_string,str_addr);
RtlCopyMemory(&gp_bpdata->bp_context,&g_kstack_info,sizeof(KINT_STACK_INFO));
InsertTailList(&hbpdata_list,&gp_bpdata->ListEntry);
}
DbgPrint("eip 0x%x cs 0x%x EFLAGS 0x%x %x %x\n",g_kstack_info.ret_eip,
g_kstack_info.saved_cs,
g_kstack_info.saved_eflags,
g_kstack_info.saved_esp,
g_kstack_info.saved_ss
);
DbgPrint(" eax= 0x%08x ",g_kstack_info.saved_eax);
// set TF __RING3:
if(b_steping == TRUE)
{
g_kstack_info.saved_eflags|=0x100;
__asm
{
mov eax,g_kstack_info.saved_eflags
mov [esp+16+32],eax
}
}
__asm
{
popad
pop eax
popfd;
iretd; }
}
//////////////////////////////////////////////////////////////
ULONG hit_addr = 0;
int tmp_count = 0;
ULONG tmp_mode = 0;
int int1_hit_count = 0;
ULONG jc_addr = 0;
ULONG to_addr = 0;
char* jorc[2]={"call","jmp"}; LIST_ENTRY hcalldata_list;
LIST_ENTRY heipinfo_list;
BOOLEAN call_or_address = FALSE; // false 表示只记录 call信息 否则只是记录EIP
BOOLEAN can_get_callinfo = FALSE; //表示应用程序能拿数据没
// who call/jmp to
typedef struct __CALL_INFO
{
ULONG who[150];
ULONG to[150];
ULONG used;
LIST_ENTRY ListEntry;
}CALL_INFO,*PCALL_INFO;
PCALL_INFO gp_callinfo = NULL;
typedef struct __EIP_INFO
{
ULONG eip_array[1000];
ULONG used;
LIST_ENTRY ListEntry;
}EIP_INFO,*PEIP_INFO;
PEIP_INFO gp_eipinfo = NULL;
ULONG tmp_efalgs = 0;
ULONG last_addr = 0;
ULONG not_record_addr = 0;
BOOLEAN no_dip_data = FALSE;
__declspec(naked) my_int_1()
{
//DWORD eax,ebx,ecx,edx,
// KeStallExecutionProcessor(100000);
// RtlZeroMemory(&g_kstack_info,sizeof(KINT_STACK_INFO));
// g_pcur_tss = (struct _KTSS*)(*(ULONG*)(0xffdff000+0x40));
// DbgPrint("--%d\n",PsGetCurrentProcessId());
__asm
{
pushfd;
push eax
pushad // EAX,ECX,EDX,EBX,ESP,EBP,ESI和EDI
mov eax,[esp+8+32]
mov hit_addr, eax
mov eax,[esp+12+32]
mov tmp_mode,eax
}
__asm mov eax,[esp+16+32]
__asm and eax,0x100
__asm mov tmp_efalgs,eax
if(!tmp_efalgs&0x100)
goto __RET;
int1_hit_count++;
if(call_or_address == FALSE)
{
if( gp_callinfo == NULL || gp_callinfo->used == 149) ///////////// 不排除以后做修改
{
gp_callinfo = (PCALL_INFO)ExAllocatePool(NonPagedPool,sizeof(CALL_INFO));
if(gp_callinfo != NULL)
{
gp_callinfo->used = 0;
InsertTailList(&hcalldata_list,&gp_callinfo->ListEntry);
}else goto __RET; /////////////////////////////////////////////// ????????????
}
if(*(UCHAR*)hit_addr == 0xe8 /* || *(UCHAR*)hit_addr == 0xe9*/) //// 屏蔽掉好
{
jc_addr = *(ULONG*)(hit_addr+1);
if(jc_addr&0x10000000)
{
to_addr=*(ULONG*)((UCHAR*)(hit_addr+1))+(ULONG)hit_addr-0xFFFFFFFB;
}
else
{
to_addr =*(ULONG*)((UCHAR*)(hit_addr+1))+(ULONG)hit_addr+5;
}
// DbgPrint("0x%x %s 0x%x %d", hit_addr,jorc[*(UCHAR*)hit_addr-0xe8],to_addr,gp_callinfo->used);
gp_callinfo->who[gp_callinfo->used] = hit_addr;
gp_callinfo->to[gp_callinfo->used] = to_addr;
(gp_callinfo->used)++;
}else if(*(USHORT*)hit_addr == 0x15ff) /////// ?? 0xff15
{
to_addr = *(ULONG*)(*(ULONG*)((UCHAR*)(hit_addr+2)));
// DbgPrint("--0x%x call 0x%x %d",hit_addr,to_addr,gp_callinfo->used);
gp_callinfo->who[gp_callinfo->used] = hit_addr;
gp_callinfo->to[gp_callinfo->used] = to_addr;
(gp_callinfo->used)++;
}
//DbgPrint("eip 0x%x ",hit_addr);
__asm mov eax,[esp+16+32]
__asm and eax,0x100
__asm mov tmp_efalgs,eax
//
if(gp_callinfo->used == 149 || tmp_efalgs ==0)
{
//DbgPrint("--%x\n",hit_addr);
can_get_callinfo = TRUE;
}
}else //只记录EIP的...
{
can_get_callinfo = TRUE; //////////换方式..满才插入列
if(gp_eipinfo == NULL || gp_eipinfo->used == 999) ///////////// 不排除以后做修改
{
gp_eipinfo = (PEIP_INFO)ExAllocatePool(NonPagedPool,sizeof(EIP_INFO));
if(gp_eipinfo != NULL)
{
//DbgPrint(" ----------------");
gp_eipinfo->used = 0;
//InsertTailList(&heipinfo_list,&gp_eipinfo->ListEntry);
}else
{
DbgPrint(" failed allocate memory");
goto __RET; /////////////////////////////////////////////// ????????????
}
}
if(hit_addr == last_addr) //// can_get_callinfo == FALSE??
{
//not_record_addr = hit_addr;
__asm
{
mov eax,[esp+16+32]
and eax,0xfffffeff
mov [esp+16+32],eax
}
DbgPrint("-uuuuuuuuu-%x\n",hit_addr);
//InsertTailList(&heipinfo_list,&gp_eipinfo->ListEntry);
// can_get_callinfo = FALSE; ///////////////////////////////////////////
}
{
gp_eipinfo->eip_array[gp_eipinfo->used] = hit_addr;
(gp_eipinfo->used)++;
}
last_addr = hit_addr;
__asm mov eax,[esp+16+32]
__asm and eax,0x100
__asm mov tmp_efalgs,eax
if(gp_eipinfo->used == 999 || tmp_efalgs ==0)
{
//DbgPrint("--uuuuuuuuuuuuuuuuu%x\n",hit_addr);
can_get_callinfo = TRUE;
InsertTailList(&heipinfo_list,&gp_eipinfo->ListEntry);
//DbgPrint("--%x\n",hit_addr);
}
}
__RET:
if(tmp_count == int1_hit_count || tmp_mode==0x1b)
{
DbgPrint("--uuuuuuuuuuuuuuuuu%x\n",hit_addr);
// InsertTailList(&heipinfo_list,&gp_eipinfo->ListEntry);
//如果不要 tmp_count++; 则记录了整个调用的过程直到返回RING3
__asm
{
mov eax,[esp+16+32]
and eax,0xfffffeff
mov [esp+16+32],eax
mov eax,0
mov dr6,eax
}
can_get_callinfo = TRUE;
}
__asm
{
popad
pop eax
popfd;
iretd; }
} char* str_addr = NULL;
ULONG str_len = 0;
ULONG str_max_len = 0;
ULONG is_print = 0;
PKEVENT pKEvent = NULL;
char tmp_dbgprint_string[256]={0};
KIRQL oldIrql;
KSPIN_LOCK StateLock;
LARGE_INTEGER timeout;
LIST_ENTRY hdbdata_list;
typedef struct _DB_DATA
{
char db_string[256];
LIST_ENTRY ListEntry;
} DB_DATA, *PDB_DATA;
PDB_DATA gp_dbdata = NULL;
__declspec(naked) my_int_2d()
{
// timeout.QuadPart = -3*1000*1000*10/1000;
// KeAcquireSpinLock(&StateLock, &oldIrql);
__asm
{
pushfd;
push eax
pushad // EAX,ECX,EDX,EBX,ESP,EBP,ESI和EDI
mov is_print,eax
mov eax,[esp+8+32]
inc eax
mov [esp+8+32],eax
mov str_addr,ecx
mov str_len,edx
}
if(str_len >250)
str_max_len = 250;
else str_max_len = str_len;
if(/*pKEvent&& */is_print==1)
{
gp_dbdata = (PDB_DATA)ExAllocatePool(NonPagedPool,sizeof(DB_DATA));
if(gp_dbdata != NULL)
{
strcpy(gp_dbdata->db_string,str_addr);
InsertTailList(&hdbdata_list,&gp_dbdata->ListEntry);
}
// strcpy(tmp_dbgprint_string,str_addr);
// KeSetEvent(pKEvent,IO_NO_INCREMENT, FALSE);
// KeWaitForSingleObject(pKEvent,Executive,KernelMode,FALSE,&timeout);
// RtlCopyMemory(tmp_dbgprint_string,str_addr,str_max_len);
}
// DbgPrint("----hi int 2d %x",xx);
__asm
{
// jmp g_old_isr[0x2d]
popad
pop eax
popfd;
iretd;
}
// KeReleaseSpinLock(&StateLock, oldIrql);
} typedef struct _INTTERUPT_STACK
{
ULONG InterruptReturnAddress;
ULONG SavedCS;
ULONG SavedFlags;
ULONG FunctionReturnAddress;
ULONG Argument;
}INTTERUPT_STACK; #define MAX_PROCESSOR 8
ULONG g_old_isr[256]={0};
typedef struct _IDT_ENTRY
{
ULONG g_old_isr[256];
}IDT_ENTRY,*PIDT_ENTRY;
IDT_ENTRY g_idtentry_array[MAX_PROCESSOR] = {0};
#define MAX_NUM_PROCESSER 8
extern VOID KeSetSystemAffinityThread(KAFFINITY Affinity);
IDTENTRY OldIdtEntry[MAX_NUM_PROCESSER]={ 0 };
IDTINFO idt_info[MAX_NUM_PROCESSER]={ 0 };
////////////////////////////////////////////////////////
VOID AddInterrupt(LONG dwIndex,ULONG vertor, PVOID fake_routine)
{
IDTINFO idt_info; // this structure is obtained by calling STORE IDT (sidt)
IDTENTRY* idt_entries; // and then this pointer is obtained from idt_info
int i = 0;
if(g_idtentry_array[dwIndex].g_old_isr[vertor] !=0)
{
return ;
}
// load idt_info
__asm sidt idt_info
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
g_idtentry_array[dwIndex].g_old_isr[vertor] = MAKELONG(idt_entries[vertor].LowOffset,idt_entries[vertor].HiOffset);
// remember we disable interrupts while we patch the table
__asm cli
idt_entries[vertor].LowOffset = (unsigned short)fake_routine;
idt_entries[vertor].HiOffset = (unsigned short)((unsigned long)fake_routine >> 16);
__asm sti
/* IDTENTRY* idt_entries;
IDTINFO idt_infoTmp;
__asm sidt idt_infoTmp;
idt_info[dwIndex]=idt_infoTmp;
idt_entries = (IDTENTRY*) MAKELONG(idt_info[dwIndex].LowIDTbase,idt_info[dwIndex].HiIDTbase); if ((idt_entries[vector].LowOffset != 0) || (idt_entries[vector].HiOffset != 0))
return;
memcpy(&OldIdtEntry[dwIndex], &idt_entries[vector], sizeof(IDTENTRY));
__asm cli
idt_entries[vector].LowOffset = (unsigned short)fake_routine;
idt_entries[vector].HiOffset = (unsigned short)((unsigned int)fake_routine>>16);
__asm sti
return;*/
} void RemoveInterrupt(LONG dwIndex,ULONG vertor)
{
IDTINFO idt_info; // this structure is obtained by calling STORE IDT (sidt)
IDTENTRY* idt_entries;
if(g_idtentry_array[dwIndex].g_old_isr[vertor] == 0)
{
return ;
}
__asm sidt idt_info
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
// restore the original interrupt handler
__asm cli
idt_entries[vertor].LowOffset = (unsigned short)g_idtentry_array[dwIndex].g_old_isr[vertor];
idt_entries[vertor].HiOffset = (unsigned short)((unsigned long)g_idtentry_array[dwIndex].g_old_isr[vertor] >> 16);
__asm sti
g_idtentry_array[dwIndex].g_old_isr[vertor] = 0; ////////////////////////////////////////////////////////////
/* IDTENTRY* idt_entries;
idt_entries = (IDTENTRY*) MAKELONG(idt_info[dwIndex].LowIDTbase,idt_info[dwIndex].HiIDTbase);
__asm cli
memcpy(&idt_entries[vector], &OldIdtEntry[dwIndex], sizeof(IDTENTRY));
__asm sti*/
} void install_idt_hook(int vertor, PVOID fake_routine)
{
/* KAFFINITY ActiveProcessors, CurrentAffinity;
LONG dwTmp=0;
ActiveProcessors=KeQueryActiveProcessors();
DbgPrint("KeActiveProcessors=%d",ActiveProcessors);
for (CurrentAffinity = 1; ActiveProcessors; CurrentAffinity <<= 1)
{
if (ActiveProcessors & CurrentAffinity)
{
ActiveProcessors &= ~CurrentAffinity;
KeSetSystemAffinityThread(CurrentAffinity);
AddInterrupt(dwTmp,vertor,fake_routine);
dwTmp++;
}
}*/
IDTINFO idt_info; // this structure is obtained by calling STORE IDT (sidt)
IDTENTRY* idt_entries; // and then this pointer is obtained from idt_info
int i = 0;
if(g_old_isr[vertor] !=0)
{
return ;
}
// load idt_info
__asm sidt idt_info
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
g_old_isr[vertor] = MAKELONG(idt_entries[vertor].LowOffset,idt_entries[vertor].HiOffset);
// remember we disable interrupts while we patch the table
__asm cli
idt_entries[vertor].LowOffset = (unsigned short)fake_routine;
idt_entries[vertor].HiOffset = (unsigned short)((unsigned long)fake_routine >> 16);
__asm sti
}
void unistall_idt_hook(int vertor)
{
/* KAFFINITY ActiveProcessors, CurrentAffinity;
LONG dwTmp=0;
ActiveProcessors=KeQueryActiveProcessors();
DbgPrint("KeActiveProcessors=%d",ActiveProcessors);
for (CurrentAffinity = 1; ActiveProcessors; CurrentAffinity <<= 1)
{
if (ActiveProcessors & CurrentAffinity)
{
ActiveProcessors &= ~CurrentAffinity;
KeSetSystemAffinityThread(CurrentAffinity);
RemoveInterrupt(dwTmp,vector);
dwTmp++;
}
} */
IDTINFO idt_info; // this structure is obtained by calling STORE IDT (sidt)
IDTENTRY* idt_entries; // and then this pointer is obtained from idt_info
if(g_old_isr[vertor] == 0)
{
return ;
}
// load idt_info
__asm sidt idt_info
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
// restore the original interrupt handler
__asm cli
idt_entries[vertor].LowOffset = (unsigned short)g_old_isr[vertor];
idt_entries[vertor].HiOffset = (unsigned short)((unsigned long)g_old_isr[vertor] >> 16);
__asm sti
g_old_isr[vertor] = 0; //////////////////////////////////////////////////////////// }
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
UNICODE_STRING usDosDeviceName;
// DbgPrint("Example_Unload Called \r\n");
RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\Sys_SKD");
IoDeleteSymbolicLink(&usDosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
if(pKEvent)
ObDereferenceObject(pKEvent);
// unistall_idt_hook(NT_INT_TIMER);
unistall_idt_hook(0x1);
unistall_idt_hook(0x2d);
unistall_idt_hook(0x3);
}
NTSTATUS SysCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
return NtStatus;
} NTSTATUS SysClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
return NtStatus;
}
#define IOCTL_GET_DBGPRINT_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_PASS_USER_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_UNPASS_USER_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_INSTALL_INT3 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_UNINSTALL_INT3 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_INSTALL_INT1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_INSERT_BREAKPOINT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_GET_BREAKPOINT_CONTEXT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_SET_STEPING CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_SET_STEPING_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_UNSET_STEPING CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_UNINSTALL_INT1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x812, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_GET_CALL_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x813, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_SET_GET_EIPINFO CTL_CODE(FILE_DEVICE_UNKNOWN, 0x814, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_GET_EIP_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x815, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_SET_GET_CALLINFO CTL_CODE(FILE_DEVICE_UNKNOWN, 0x816, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA) NTSTATUS handle_get_dbdata(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, ULONG* pdwDataWritten)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PCHAR pOutputBuffer = NULL;
int dwwrite = 0; if(Irp->MdlAddress)
{
pOutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
if(pOutputBuffer)
{
// DbgPrint("----get data");
// while(!IsListEmpty(&hdbdata_list))
if(!IsListEmpty(&hdbdata_list))
{
PLIST_ENTRY pEntry;
pEntry = RemoveHeadList(&hdbdata_list);
gp_dbdata = CONTAINING_RECORD(pEntry,
DB_DATA,
ListEntry);
//if(gp_tmp_dbdata)
//gp_tmp_dbdata = gp_dbdata;
//KdPrint(("%d\n",pData->number));
if(pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength >strlen(gp_dbdata->db_string))
strcpy(pOutputBuffer,gp_dbdata->db_string);
else strcpy(pOutputBuffer,"NULL");
ExFreePool(gp_dbdata);
dwwrite = strlen(gp_dbdata->db_string);
// RemoveHeadList(&hdbdata_list);
// KeSetEvent(pKEvent,IO_NO_INCREMENT, FALSE);
//break;
}
// strcpy(pOutputBuffer,tmp_dbgprint_string);
// RtlZeroMemory(tmp_dbgprint_string,256);
// DbgPrint("----get data");
// if(pKEvent)
// KeSetEvent(pKEvent,IO_NO_INCREMENT, FALSE);
}
//*pdwDataWritten == 0 表示失败....否则返回真实的..用户程序需要根据这个返回值判断自己提供的缓冲区是否足够
*pdwDataWritten = dwwrite;
return NtStatus;
}
NTSTATUS handle_pass_uevent(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, ULONG* pdwDataWritten)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
// 需要验证一下.
HANDLE hUserEvent = *(HANDLE*)Irp->AssociatedIrp.SystemBuffer;
NtStatus = ObReferenceObjectByHandle(hUserEvent,EVENT_MODIFY_STATE,*ExEventObjectType,KernelMode,
(PVOID*)&pKEvent, NULL);
if(NtStatus!=STATUS_SUCCESS)
{
DbgPrint("pass event wrong\n");
}
*pdwDataWritten = 0;
return NtStatus;
}
///////////////////////////
NTSTATUS get_bpcontext(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, ULONG* pdwDataWritten)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PCHAR pOutputBuffer = NULL;
int dwwrite = 0; if(Irp->MdlAddress)
{
pOutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
if(pOutputBuffer)
{
if(!IsListEmpty(&hbpdata_list))
{
PLIST_ENTRY pEntry;
pEntry = RemoveHeadList(&hbpdata_list);
gp_bpdata = CONTAINING_RECORD(pEntry,
BP_DATA,
ListEntry);
if(pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KINT_STACK_INFO))
{
RtlCopyMemory(pOutputBuffer,&gp_bpdata->bp_context,sizeof(KINT_STACK_INFO));
dwwrite = sizeof(KINT_STACK_INFO);
}
else dwwrite = 0;
ExFreePool(gp_bpdata);
gp_bpdata = NULL;
}
}
//*pdwDataWritten == 0 表示失败....否则返回真实的..用户程序需要根据这个返回值判断自己提供的缓冲区是否足够
*pdwDataWritten = dwwrite;
return NtStatus;
}
////////////////////
NTSTATUS get_call_info(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, ULONG* pdwDataWritten)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PCHAR pOutputBuffer = NULL;
int dwwrite = 0; if(Irp->MdlAddress)
{
pOutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
if(pOutputBuffer)
{
if(!IsListEmpty(&hcalldata_list)&&(can_get_callinfo == TRUE)) // 因为结构被多次用..除非慢满了..否则有数据也不取的..
{
PLIST_ENTRY pEntry;
pEntry = RemoveHeadList(&hcalldata_list);
gp_callinfo = CONTAINING_RECORD(pEntry,CALL_INFO,ListEntry);
if(pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(CALL_INFO))
{
RtlCopyMemory(pOutputBuffer,gp_callinfo,sizeof(CALL_INFO));
dwwrite = sizeof(CALL_INFO);
//can_get_callinfo = FALSE;
}
else dwwrite = 0;
ExFreePool(gp_callinfo);
}
}
//*pdwDataWritten == 0 表示失败....否则返回真实的..用户程序需要根据这个返回值判断自己提供的缓冲区是否足够
*pdwDataWritten = dwwrite;
return NtStatus;
}
/////////////////////
NTSTATUS get_eip_info(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, ULONG* pdwDataWritten)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PCHAR pOutputBuffer = NULL;
int dwwrite = 0; if(Irp->MdlAddress)
{
pOutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
//DbgPrint("------------------get data 0000000 --------------------");
if(pOutputBuffer)
{
if(!IsListEmpty(&heipinfo_list)&&(can_get_callinfo == TRUE)) // 因为结构被多次用..除非慢满了..否则有数据也不取的..
{
PLIST_ENTRY pEntry;
//DbgPrint("------------------get data --------------------");
pEntry = RemoveHeadList(&heipinfo_list);
gp_eipinfo = CONTAINING_RECORD(pEntry,EIP_INFO,ListEntry);
if(pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(EIP_INFO))
{
RtlCopyMemory(pOutputBuffer,gp_eipinfo,sizeof(EIP_INFO));
dwwrite = sizeof(EIP_INFO);
//can_get_callinfo = FALSE;
}
else dwwrite = 0;
ExFreePool(gp_eipinfo);
}
}
//*pdwDataWritten == 0 表示失败....否则返回真实的..用户程序需要根据这个返回值判断自己提供的缓冲区是否足够
*pdwDataWritten = dwwrite;
return NtStatus;
}
NTSTATUS SysIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;
ULONG dwDataWritten = 0;
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(pIoStackIrp) /* Should Never Be NULL! */
{
switch(pIoStackIrp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_GET_DBGPRINT_DATA:
handle_get_dbdata(Irp, pIoStackIrp, &dwDataWritten);
break;
case IOCTL_PASS_USER_EVENT:
handle_pass_uevent(Irp, pIoStackIrp, &dwDataWritten);
InitializeListHead(&hdbdata_list);
install_idt_hook(0x2d, (PVOID)my_int_2d);
break;
case IOCTL_UNPASS_USER_EVENT:
if(pKEvent)
{
ObDereferenceObject(pKEvent);
pKEvent = NULL;
}
break;
case IOCTL_INSTALL_INT3:
InitializeListHead(&hbpdata_list);
install_idt_hook(0x3, (PVOID)my_interrupt_hook);
break;
case IOCTL_UNINSTALL_INT3:
unistall_idt_hook(0x3);
break;
case IOCTL_INSERT_BREAKPOINT:
// 验证一下..
insert_breakpoint((PVOID)(*(ULONG*)Irp->AssociatedIrp.SystemBuffer));
break;
case IOCTL_GET_BREAKPOINT_CONTEXT:
get_bpcontext(Irp, pIoStackIrp, &dwDataWritten);
break;
case IOCTL_SET_STEPING:
b_steping = TRUE;
break;
case IOCTL_SET_STEPING_COUNT:
tmp_count = *(int*)Irp->AssociatedIrp.SystemBuffer;
break;
case IOCTL_UNSET_STEPING:
b_steping = FALSE;
break;
case IOCTL_INSTALL_INT1:
InitializeListHead(&hcalldata_list);
InitializeListHead(&heipinfo_list);
install_idt_hook(0x1, (PVOID)my_int_1);
break;
case IOCTL_UNINSTALL_INT1:
unistall_idt_hook(0x1);
break;
case IOCTL_GET_CALL_DATA:
get_call_info(Irp, pIoStackIrp, &dwDataWritten);
break;
case IOCTL_SET_GET_EIPINFO:
call_or_address = TRUE; //// 是否只用一个命令就可以,...
can_get_callinfo = FALSE; //////////////////////////////////// ????????
break;
case IOCTL_SET_GET_CALLINFO:
call_or_address = FALSE;
break;
case IOCTL_GET_EIP_DATA:
get_eip_info(Irp, pIoStackIrp, &dwDataWritten);
break; }
}
Irp->IoStatus.Status = NtStatus;
Irp->IoStatus.Information = dwDataWritten;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return NtStatus;
} ////////////////////////////////
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
VOID MySleep(LONG msec)
{
LARGE_INTEGER my_interval;
my_interval.QuadPart = DELAY_ONE_MILLISECOND;
my_interval.QuadPart *= msec;
KeDelayExecutionThread(KernelMode,0,&my_interval);
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
NTSTATUS NtStatus = STATUS_SUCCESS;
ULONG uiIndex = 0;
PDEVICE_OBJECT pDeviceObject = NULL;
UNICODE_STRING usDriverName, usDosDeviceName;
ULONG i;
NTSTATUS status;
// install_idt_hook(NT_INT_TIMER, (PVOID)my_interrupt_hook);
// install_idt_hook(1, (PVOID)my_int_1);
RtlInitUnicodeString(&usDriverName, L"\\Device\\Sys_SKD");
RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\Sys_SKD");
NtStatus = IoCreateDevice(theDriverObject,
0,
&usDriverName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pDeviceObject); if(NtStatus == STATUS_SUCCESS)
{
theDriverObject->MajorFunction[IRP_MJ_CLOSE] = SysClose;
theDriverObject->MajorFunction[IRP_MJ_CREATE] = SysCreate;
theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SysIoControl;
theDriverObject->DriverUnload = OnUnload;
IoCreateSymbolicLink(&usDosDeviceName, &usDriverName);
}
// insert_breakpoint((PVOID)0x8057a588);
// install_idt_hook(0x2d, (PVOID)my_int_2d);
return STATUS_SUCCESS;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)