//保存原先开头的5个自己
BYTE reg_ZwSetValueKeyOldAddress[7]={0};
//jmp新的函数地址
BYTE reg_ZwSetValueKeyNewAddress[5]={0xe9,0,0,0,0};
BYTE reg_ZwSetValueKeyJmpAddress[7]={0xea,0,0,0,0,0x08,0};
//去除内存保护
VOID UnProtected()
{
_asm{
push eax
mov eax,cr0
and eax,not 10000h
mov cr0,eax
pop eax
}
};
//恢复内存保护
VOID Protected()
{
_asm{
push eax
mov eax,cr0
or eax,10000h
mov cr0,eax
pop eax
}
};
//SDT结构体
typedef struct ServiceDescriptorTable {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTable;
unsigned int NumberOfServices;
unsigned int *ParamTableBase;
}ServiceDescriptorTable,*PServiceDescriptorTable;
//获得SSDT函数地址
#define GetSSDTFuncAddress(_func) KeServiceDescriptorTable->ServiceTableBase[ *(PULONG)((PUCHAR)_func+1)]
typedef NTSTATUS (*PNtSetValueKey)( IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
NTSTATUS JmpZwSetValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
NTSTATUS NewZwSetValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
PNtSetValueKey NtSetValueKey = NULL;
//在这里InlineHook
VOID reg_inlineHook()
{
//赋值前面定义的数组
KIRQL Irql;
KSPIN_LOCK SDTSpinLock;
__try
{
KeAcquireSpinLock (&SDTSpinLock, &Irql);
NtSetValueKey = (PNtSetValueKey)GetSSDTFuncAddress(ZwSetValueKey);
//保存函数前7个字节内容
RtlCopyMemory(reg_ZwSetValueKeyOldAddress,(PBYTE)NtSetValueKey,7);
//保存新函数五个字节之后偏移
*(PULONG)(reg_ZwSetValueKeyNewAddress+1)=(ULONG)NewZwSetValueKey-((ULONG)NtSetValueKey + 5);
//开始inline hook
//关闭内存写保护
UnProtected();
//函数开头五个字节写JMP
RtlCopyMemory((PBYTE)NtSetValueKey,reg_ZwSetValueKeyNewAddress,5);
*(PULONG)(reg_ZwSetValueKeyJmpAddress+1) =(ULONG)((PBYTE)NtSetValueKey + 7);
RtlCopyMemory((PBYTE)JmpZwSetValueKey, reg_ZwSetValueKeyOldAddress, 7);
RtlCopyMemory((PBYTE)JmpZwSetValueKey + 7, reg_ZwSetValueKeyJmpAddress, 7);
//开启内存写保护
Protected();
KeReleaseSpinLock (&SDTSpinLock, Irql);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
//恢复
VOID reg_unInlineHook()
{
//赋值前面定义的数组
KIRQL Irql;
KSPIN_LOCK SDTSpinLock;
__try
{
KeAcquireSpinLock (&SDTSpinLock, &Irql);
//关闭写保护
UnProtected();
//用原先保存的地址覆盖前7个字节
RtlCopyMemory((PBYTE)NtSetValueKey,reg_ZwSetValueKeyOldAddress,7);
//开启写保护
Protected();
KeReleaseSpinLock (&SDTSpinLock, Irql);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
__declspec(naked) NTSTATUS JmpZwSetValueKey
(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
)
{
__asm
{
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
}
}
NTSTATUS NewZwSetValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
)
{
__try
{
DbgPrint("进来了!");
//返回
return JmpZwSetValueKey(
KeyHandle,
ValueName,
TitleIndex,
Type,
Data,
DataSize
);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return STATUS_UNSUCCESSFUL;
}
}
上面就是代码了,钩子能安装,安装后不会蓝屏,但是就是感觉没有进入JmpZwSetValueKey,
新建注册表键值,总是提示失败;还有就是恢复钩子后,等几十秒,就莫名其妙的蓝屏了。
下面是windbg的报错信息:
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS (ce)
A driver unloaded without cancelling timers, DPCs, worker threads, etc.
The broken driver's name is displayed on the screen.
Arguments:
Arg1: b1c587a1, memory referenced
Arg2: 00000000, value 0 = read operation, 1 = write operation
Arg3: b1c587a1, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 00000000, Mm internal code.
Debugging Details:
------------------
READ_ADDRESS: b1c587a1
FAULTING_IP:
Deianeira+37a1
b1c587a1 ?? ???
DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0xCE
PROCESS_NAME: winlogon.exe
TRAP_FRAME: b20c342c -- (.trap 0xffffffffb20c342c)
ErrCode = 00000000
eax=c0000034 ebx=8056f2ee ecx=8056c3df edx=53c00001 esi=b20c35f8 edi=b20c3554
eip=b1c587a1 esp=b20c34a0 ebp=b20c34e0 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
<Unloaded_Test.sys>+0x37a1:
b1c587a1 ?? ???
Resetting default scope
IP_MODULE_UNLOADED:
Test+37a1
b1c587a1 ?? ???
LAST_CONTROL_TRANSFER: from 804f8bad to 80528c0c
FAILED_INSTRUCTION_ADDRESS:
Test+37a1
b1c587a1 ?? ???
请大大们给个帮助。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法