dll代码
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include<stdio.h>
PVOID Hooaddr = 0;
LONG FirstVEHandler(
EXCEPTION_POINTERS* ExceptionInfo
)
{
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0x00C0000005) {
if (ExceptionInfo->ExceptionRecord->ExceptionAddress == Hooaddr)
{
printf("线程到达断点位置%p\n", GetCurrentThreadId());
}
//EXCEPTION_SINGLE_STEP:
}
void Init() {
MessageBox(NULL, L"点我设置异常", L"", MB_OK);
Hooaddr = GetModuleHandle(0);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
CreateThread(0, 0,(LPTHREAD_START_ROUTINE) Init, 0, 0, 0);
return 1;
}
exe代码
#include<Windows.h>
#include<stdio.h>
void runcode()
{
while (1) {
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, 0, 0x14);
}
int main()
{
}
实验结果

那个runcode所在页不可读了
线程第一次读取了那个页后触发异常,然后进入系统异常处理流程,系统异常处理流程又读了那个地址
又触发一个异常,不了了之
getchar();
}
else
{
PVOID ExceptionAddress = ExceptionInfo->ExceptionRecord->ExceptionAddress;
ULONG64 srartaddress = (ULONG64)ExceptionAddress & 0xFFFFFFFFF000;
ULONG64 Hoodstartaadress= (ULONG64)Hooaddr & 0xFFFFFFFFF000;
// printf("11\n");
if (srartaddress == Hoodstartaadress) {
CONTEXT Context = { 0 };
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &Context);
//2. 设置陷阱标志位
Context.EFlags |= 0x100;
//3. 设置线程上下文
SetThreadContext(GetCurrentThread(), &Context);
DWORD oldprotect = 0;
VirtualProtect(Hooaddr, 0x1000, PAGE_EXECUTE_READ, &oldprotect);
return EXCEPTION_CONTINUE_EXECUTION;
}
else
{
printf("ExceptionAddress%p\n", ExceptionAddress);
MessageBox(NULL, L"", L"", MB_OK);
return EXCEPTION_CONTINUE_SEARCH;
}
}
}
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
CONTEXT Context = { 0 };
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &Context);
//2. 判断是否是硬件断点导致的异常
if (Context.Dr6 & 0xF) //B0~B3不为空 硬件断点
{
return EXCEPTION_CONTINUE_SEARCH;
}
else //单步异常
{
if (ExceptionInfo->ExceptionRecord->ExceptionAddress == Hooaddr)
{
printf("线程到达断点位置%p\n", GetCurrentThreadId());
getchar();
}
else
{
PVOID ExceptionAddress = ExceptionInfo->ExceptionRecord->ExceptionAddress;
ULONG64 srartaddress = (ULONG64)ExceptionAddress & 0xFFFFFFFFF000;
ULONG64 Hoodstartaadress = (ULONG64)Hooaddr & 0xFFFFFFFFF000;
if (srartaddress == Hoodstartaadress) {
CONTEXT Context = { 0 };
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &Context);
//2. 设置陷阱标志位
Context.EFlags |= 0x100;
//3. 设置线程上下文
SetThreadContext(GetCurrentThread(), &Context);
DWORD oldprotect = 0;
VirtualProtect(Hooaddr, 0x1000, PAGE_NOACCESS, &oldprotect);
return EXCEPTION_CONTINUE_EXECUTION;
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}
}
getchar();
}
else
{
PVOID ExceptionAddress = ExceptionInfo->ExceptionRecord->ExceptionAddress;
ULONG64 srartaddress = (ULONG64)ExceptionAddress & 0xFFFFFFFFF000;
ULONG64 Hoodstartaadress= (ULONG64)Hooaddr & 0xFFFFFFFFF000;
// printf("11\n");
if (srartaddress == Hoodstartaadress) {
CONTEXT Context = { 0 };
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &Context);
//2. 设置陷阱标志位
Context.EFlags |= 0x100;
//3. 设置线程上下文
SetThreadContext(GetCurrentThread(), &Context);
DWORD oldprotect = 0;
VirtualProtect(Hooaddr, 0x1000, PAGE_EXECUTE_READ, &oldprotect);
return EXCEPTION_CONTINUE_EXECUTION;
}
else
{
printf("ExceptionAddress%p\n", ExceptionAddress);
MessageBox(NULL, L"", L"", MB_OK);
return EXCEPTION_CONTINUE_SEARCH;
}
}
}
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
CONTEXT Context = { 0 };
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &Context);
//2. 判断是否是硬件断点导致的异常
if (Context.Dr6 & 0xF) //B0~B3不为空 硬件断点
{
return EXCEPTION_CONTINUE_SEARCH;
}
else //单步异常
{
if (ExceptionInfo->ExceptionRecord->ExceptionAddress == Hooaddr)
{
printf("线程到达断点位置%p\n", GetCurrentThreadId());
getchar();
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!