内存WriteWatch跟踪技术

本文介绍了一个使用Windows API实现的内存监控程序,能够实时检测是否有第三方软件修改了特定内存区域,并通过创建线程来监控这些修改。此外,程序还实现了在检测到修改时暂停并恢复线程的功能。
部署运行你感兴趣的模型镜像
#include <windows.h>
#include <stdio.h>

typedef struct _POSITION_
{
  DWORD dx;
  DWORD dz;
  DWORD dy;
}POSITION,*PPOSITION;

#define BASE_SIZE 0x1000
#define WALK_ADD 10
DWORD WINAPI WatchThread(LPVOID Param)
{
  ULONG size = 0;
  DWORD p = 0;
  UINT  Ret = 0;
  PVOID px[0x400] = { 0 };
  while (1)
  {
    size = 0x400;
    p = 0;
    Ret = GetWriteWatch(WRITE_WATCH_FLAG_RESET, Param, BASE_SIZE, px, &size, &p);
    if (Ret == 0
      && size != 0)
    {
      MessageBoxW(NULL, L"发现第三方软件修改关键内存", L"发现第三方软件", MB_OK);
    }
  }
  return 0;
}
int __cdecl main(int argc, char *argv[])
{
  //申请Base基址内存
  PVOID Base = VirtualAlloc(NULL, BASE_SIZE, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE);
  PPOSITION pos = (PPOSITION)Base;
  //初始化坐标
  pos->dx = pos->dy = pos->dz = 1000;
  //清空监控记录
  ResetWriteWatch(Base, BASE_SIZE);
  //开启监控线程
  HANDLE hThread = CreateThread(NULL, 0, WatchThread, Base, 0, NULL);
  while (1)
  {
    //暂停监控线程
    SuspendThread(hThread);//也可以通过其他方式进行!!!!暂停线程只是简单模型
    //模拟走路过程
    pos->dx += WALK_ADD;
    //继续监控
    ResetWriteWatch(Base, BASE_SIZE);
    ResumeThread(hThread);
    //输出X坐标
    printf("x = %d\n", pos->dx);
    Sleep(1000);
  }
  return 0;
}
无意翻到老V的帖子,怕忘记记录下

您可能感兴趣的与本文相关的镜像

Yolo-v8.3

Yolo-v8.3

Yolo

YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的Joseph Redmon 和Ali Farhadi 开发。 YOLO 于2015 年推出,因其高速和高精度而广受欢迎

断链实现: 在内核中很多数据使用_LIST_ENTRY,双向循环链表作为数据结构 typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, *PLIST_ENTRY; 首先要先了解EPROCESS,和KPROCESS两个重要的结构体; 每个windows进程在0环都有这样一个对应的结构体: nt!_EPROCESS +0x000 Pcb : _KPROCESS +0x098 ProcessLock : _EX_PUSH_LOCK 进程锁 +0x0a0 CreateTime : _LARGE_INTEGER 进程创建时间 +0x0a8 ExitTime : _LARGE_INTEGER 进程结束时间 +0x0b0 RundownProtect : _EX_RUNDOWN_REF +0x0b4 UniqueProcessId : Ptr32 Void PID进程id +0x0b8 ActiveProcessLinks : _LIST_ENTRY 活跃进程链表 双向循环链表 可断链 +0x0c0 ProcessQuotaUsage : [2] Uint4B 物理页相关统计 +0x0c8 ProcessQuotaPeak : [2] Uint4B +0x0d0 CommitCharge : Uint4B cpu占用信息 +0x0d4 QuotaBlock : Ptr32 _EPROCESS_QUOTA_BLOCK +0x0d8 CpuQuotaBlock : Ptr32 _PS_CPU_QUOTA_BLOCK cpu占用信息 +0x0dc PeakVirtualSize : Uint4B 虚拟内存相关统计 +0x0e0 VirtualSize : Uint4B +0x0e4 SessionProcessLinks : _LIST_ENTRY +0x0ec DebugPort : Ptr32 Void 调试相关≠0则被调试 +0x0f0 ExceptionPortData : Ptr32 Void +0x0f0 ExceptionPortValue : Uint4B +0x0f0 ExceptionPortState : Pos 0, 3 Bits +0x0f4 ObjectTable : Ptr32 _HANDLE_TABLE 句柄表 内核对象 +0x0f8 Token : _EX_FAST_REF +0x0fc WorkingSetPage : Uint4B +0x100 AddressCreationLock : _EX_PUSH_LOCK +0x104 RotateInProgress : Ptr32 _ETHREAD +0x108 ForkInProgress : Ptr32 _ETHREAD +0x10c HardwareTrigger : Uint4B +0x110 PhysicalVadRoot : Ptr32 _MM_AVL_TABLE +0x114 CloneRoot : Ptr32 Void +0x118 NumberOfPrivatePages : Uint4B +0x11c NumberOfLockedPages : Uint4B +0x120 Win32Process : Ptr32 Void +0x124 Job : Ptr32 _EJOB +0x128 SectionObject : Ptr32 Void +0x12c SectionBaseAddress : Ptr32 Void +0x130 Cookie : Uint4B +0x134 Spare8 : Uint4B +0x138 WorkingSetWatch : Ptr32 _PAGEFAULT_HISTORY +0x13c Win32WindowStation : Ptr32 Void +0x140 InheritedFromUniqueProcessId : Ptr32 Void 父进程id +0x144 LdtInformation : Ptr32 Void +0x148 VdmObjects : Ptr32 Void +0x14c ConsoleHostProcess : Uint4B +0x150 DeviceMap : Ptr32 Void +0x154 EtwDataSource : Ptr32 Void +0x158 FreeTebHint : Ptr32 Void +0x160 PageDirectoryPte : Uint8B +0x168 Session : Ptr32 Void +0x16c ImageFileName : [15] UChar 进程名最多存16个字符,截断 +0x17b PriorityClass : UChar +0x17c JobLinks : _LIST_ENTRY +0x184 LockedPagesList : Ptr32 Void +0x188 ThreadListHead : _LIST_ENTRY 双向循环链表 +0x190 SecurityPort : Ptr32 Void +0x194 PaeTop : Ptr32 Void +0x198 ActiveThreads : Uint4B 活跃线程数量 +0x19c ImagePathHash : Uint4B +0x1a0 DefaultHardErrorProcessing : Uint4B +0x1a4 LastThreadExitStatus : Int4B +0x1a8 Peb : Ptr32 _PEB PEB(process ENVIRONMENT BLOCK 进程环境块) +0x1ac PrefetchTrace : _EX_FAST_REF +0x1b0 ReadOperationCount : _LARGE_INTEGER +0x1b8 WriteOperationCount : _LARGE_INTEGER +0x1c0 OtherOperationCount : _LARGE_INTEGER +0x1c8 ReadTransferCount : _LARGE_INTEGER +0x1d0 WriteTransferCount : _LARGE_INTEGER +0x1d8 OtherTransferCount : _LARGE_INTEGER +0x1e0 CommitChargeLimit : Uint4B +0x1e4 CommitChargePeak : Uint4B +0x1e8 AweInfo : Ptr32 Void +0x1ec SeAuditProcessCreationInfo : 进程路径_SE_AUDIT_PROCESS_CREATION_INFO +0x1f0 Vm : _MMSUPPORT +0x25c MmProcessLinks : _LIST_ENTRY +0x264 HighestUserAddress : Ptr32 Void +0x268 ModifiedPageCount : Uint4B +0x26c Flags2 : Uint4B +0x26c JobNotReallyActive : Pos 0, 1 Bit +0x26c AccountingFolded : Pos 1, 1 Bit +0x26c NewProcessReported : Pos 2, 1 Bit +0x26c ExitProcessReported : Pos 3, 1 Bit +0x26c ReportCommitChanges : Pos 4, 1 Bit +0x26c LastReportMemory : Pos 5, 1 Bit +0x26c ReportPhysicalPageChanges : Pos 6, 1 Bit +0x26c HandleTableRundown : Pos 7, 1 Bit +0x26c NeedsHandleRundown : Pos 8, 1 Bit +0x26c RefTraceEnabled : Pos 9, 1 Bit +0x26c NumaAware : Pos 10, 1 Bit +0x26c ProtectedProcess : Pos 11, 1 Bit 保护进程 +0x26c DefaultPagePriority : Pos 12, 3 Bits +0x26c PrimaryTokenFrozen : Pos 15, 1 Bit +0x26c ProcessVerifierTarget : Pos 16, 1 Bit +0x26c StackRandomizationDisabled : Pos 17, 1 Bit +0x26c AffinityPermanent : Pos 18, 1 Bit +0x26c AffinityUpdateEnable : Pos 19, 1 Bit +0x26c PropagateNode : Pos 20, 1 Bit +0x26c ExplicitAffinity : Pos 21, 1 Bit +0x26c Spare1 : Pos 22, 1 Bit +0x26c ForceRelocateImages : Pos 23, 1 Bit +0x26c DisallowStrippedImages : Pos 24, 1 Bit +0x26c LowVaAccessible : Pos 25, 1 Bit +0x26c RestrictIndirectBranchPrediction : Pos 26, 1 Bit +0x26c AddressPolicyFrozen : Pos 27, 1 Bit +0x26c SpeculativeStoreBypassDisable : Pos 28, 1 Bit +0x270 Flags : Uint4B +0x270 CreateReported : Pos 0, 1 Bit +0x270 NoDebugInherit : Pos 1, 1 Bit +0x270 ProcessExiting : Pos 2, 1 Bit +0x270 ProcessDelete : Pos 3, 1 Bit +0x270 Wow64SplitPages : Pos 4, 1 Bit +0x270 VmDeleted : Pos 5, 1 Bit +0x270 OutswapEnabled : Pos 6, 1 Bit +0x270 Outswapped : Pos 7, 1 Bit +0x270 ForkFailed : Pos 8, 1 Bit +0x270 Wow64VaSpace4Gb : Pos 9, 1 Bit +0x270 AddressSpaceInitialized : Pos 10, 2 Bits +0x270 SetTimerResolution : Pos 12, 1 Bit +0x270 BreakOnTermination : Pos 13, 1 Bit +0x270 DeprioritizeViews : Pos 14, 1 Bit +0x270 WriteWatch : Pos 15, 1 Bit +0x270 ProcessInSession : Pos 16, 1 Bit +0x270 OverrideAddressSpace : Pos 17, 1 Bit +0x270 HasAddressSpace : Pos 18, 1 Bit +0x270 LaunchPrefetched : Pos 19, 1 Bit +0x270 InjectInpageErrors : Pos 20, 1 Bit +0x270 VmTopDown : Pos 21, 1 Bit +0x270 ImageNotifyDone : Pos 22, 1 Bit +0x270 PdeUpdateNeeded : Pos 23, 1 Bit +0x270 VdmAllowed : Pos 24, 1 Bit +0x270 CrossSessionCreate : Pos 25, 1 Bit +0x270 ProcessInserted : Pos 26, 1 Bit +0x270 DefaultIoPriority : Pos 27, 3 Bits +0x270 ProcessSelfDelete : Pos 30, 1 Bit +0x270 SetTimerResolutionLink : Pos 31, 1 Bit +0x274 ExitStatus : Int4B +0x278 VadRoot : _MM_AVL_TABLE +0x298 AlpcContext : _ALPC_PROCESS_CONTEXT +0x2a8 TimerResolutionLink : _LIST_ENTRY +0x2b0 RequestedTimerResolution : Uint4B +0x2b4 ActiveThreadsHighWatermark : Uint4B +0x2b8 SmallestTimerResolution : Uint4B +0x2bc TimerResolutionStackRecord : Ptr32 _PO_DIAG_STACK_RECORD +0x2c0 SequenceNumber : Uint8B +0x2c8 CreateInterruptTime : Uint8B +0x2d0 CreateUnbiasedInterruptTime : Uint8B +0x2d8 SecurityDomain : Uint8B _EPROCESS的第一个成员是KPROCESS nt!_KPROCESS +0x000 Header : _DISPATCHER_HEADER 可等待内核对象 +0x010 ProfileListHead : _LIST_ENTRY +0x018 DirectoryTableBase : Uint4B CR3 通过线性地址以及分页模式定位物理基地址 +0x01c LdtDescriptor : _KGDTENTRY +0x024 Int21Descriptor : _KIDTENTRY 历史遗留 +0x02c ThreadListHead : _LIST_ENTRY 双向循环链表 +0x034 ProcessLock : Uint4B 内核进程锁 +0x038 Affinity : _KAFFINITY_EX cpu亲核性 +0x044 ReadyListHead : _LIST_ENTRY 进程就绪列表 +0x04c SwapListEntry : _SINGLE_LIST_ENTRY交互磁盘 +0x050 ActiveProcessors : _KAFFINITY_EX 活跃核心 +0x05c AutoAlignment : Pos 0, 1 Bit 对齐 +0x05c DisableBoost : Pos 1, 1 Bit +0x05c DisableQuantum : Pos 2, 1 Bit 关闭时间碎片 +0x05c ActiveGroupsMask : Pos 3, 1 Bit +0x05c ReservedFlags : Pos 4, 28 Bits +0x05c ProcessFlags : Int4B +0x060 BasePriority : Char 基础优先级8,进程下所有线程最低的优先级 +0x061 QuantumReset : Char时间碎片 +0x062 Visited : UChar +0x063 Unused3 : UChar +0x064 ThreadSeed : [1] Uint4B +0x068 IdealNode : [1] Uint2B +0x06a IdealGlobalNode : Uint2B +0x06c Flags : _KEXECUTE_OPTIONS +0x06d AddressPolicy : UChar +0x06e IopmOffset : Uint2B +0x070 Unused4 : Uint4B +0x074 StackCount : _KSTACK_COUNT +0x078 ProcessListEntry : _LIST_ENTRY +0x080 CycleTime : Uint8B +0x088 KernelTime : Uint4B +0x08c UserTime : Uint4B +0x090 VdmTrapcHandler : Ptr32 Void //虚拟8086模式下使用 其中在_EPROCESS我们需要关注的是 ActiveProcessLinks 进程活跃链表 SessionProcessLinks 会话链表 ObjectTable 私有句柄表 其中在_KPROCESS我们需要关注的是 ProcessListEntry 进程链表 想要隐藏进程把所在数据的链表进程断链即可 //断链关键代码 FORCEINLINE BOOLEAN MyRemoveEntryList( _In_ PLIST_ENTRY Entry ) { PLIST_ENTRY PrevEntry; PLIST_ENTRY NextEntry; NextEntry = Entry->Flink; PrevEntry = Entry->Blink; if ((NextEntry->Blink != Entry) || (PrevEntry->Flink != Entry)) { return FALSE; } PrevEntry->Flink = NextEntry; NextEntry->Blink = PrevEntry; return (BOOLEAN)(PrevEntry == NextEntry); } // //断链 ProcessListEntry PLIST_ENTRY ProfileListHead = (PLIST_ENTRY)((PUCHAR)mypEProcess + 0x18); MyRemoveEntryList(ProfileListHead); //断链 struct _LIST_ENTRY ThreadListHead; //0x30 PLIST_ENTRY ThreadListHead = (PLIST_ENTRY)((PUCHAR)mypEProcess + 0x30); MyRemoveEntryList(ProfileListHead); //断链struct_LIST_ENTRYSessionProcessLinks PLIST_ENTRY essionProcessLinks = (PLIST_ENTRY)((PUCHAR)mypEProcess + get_eprocess_session_offset()); MyRemoveEntryList(essionProcessLinks); //断链 private ObjectTable _HANDLE_TABLE* table= (_HANDLE_TABLE*)((PUCHAR)mypEProcess + get_eprocess_objecttable_offset()); MyRemoveEntryList(table->HandleTableList); 当然仅仅断链是不够的,因为操作系统还有一张全局句柄表PspCidTable,其中存储了线程和进程,我们还需要把我们的进程从全局句柄表中抹除,可以使用ExDestroyHandle _int64 __fastcall ExDestroyHandle(__int64 a1, __int64 a2, __int64 a3) { unsigned int v6; // ebx if ( *(_QWORD *)(a1 + 96) ) ExpUpdateDebugInfo(a1, KeGetCurrentThread(), a2, 2i64); v6 = ExSweepSingleHandle(a1, a3); ExpFreeHandleTableEntry(a1, a2, a3); return v6; } if (instance->fn_get_os_build_number() == 7600 || instance->fn_get_os_build_number() == 7601) table_code = ((PHANDLE_TABLE_W7)table)->TableCode; else table_code = table->TableCode; auto level = table_code & 3; if (level == 1) { return (PHANDLE_TABLE_ENTRY)(*(uint64_t*)(table_code - 1 + 8 * (u_handle >> 10)) + 4 * (u_handle & 0X3FF)); } else if (level == 2) { return (PHANDLE_TABLE_ENTRY)(*(uint64_t*)(*(uint64_t*)(table_code - 2 + 8 * (u_handle >> 19)) + 8 * (u_handle >> 10 & 0X1FF)) + 4 * (u_handle & 0x3ff)); } else { return (PHANDLE_TABLE_ENTRY)(table_code + 4 * (u_handle & 0x3ff)); } 注:高版本对全局句柄表有加密 实验: 隐藏前DebugView 8404 隐藏后 需要注意,关闭进程前需要还原全局句柄表,不然会蓝屏; 其次在高版本系统上PG增加了对隐藏进程的检测,有概率触发蓝屏,不过没那么快,运气好能挺好几个小时; 具体的隐藏进程完整代码可以参考一份开源的:https://github.com/Oxygen1a1/HideProcess 那么问题来了,如果恶意软件隐藏自己的进程我们如何查询呢? 思考:进程是给用户看的,CPU不认识进程,代码也是跑在线程上面的 ,最重要的是cpu线程的调度是基于某些链表进行调度的,如果把cpu调度链表也断了,进程也就跑不起来了,可谓是真正实现了无痕进程隐藏;其次内核中有很多链表都能回溯到进程信息。 本人采用的方法是通过遍历枚举线程去回溯到进程,在 _ETHREAD中_CLIENT_ID储存了当前线程所属的进程id //0x10 bytes (sizeof) struct _CLIENT_ID { VOID* UniqueProcess; //0x0 VOID* UniqueThread; //0x8 }; 查询恶意隐藏进程思路:正常调用API遍历进程并存储表A,暴力枚举线程回溯进程并存储表B,如果B中的进程在A中找不到基本可以判断进程进行了隐藏。 完善隐藏进程代码,方便学习
最新发布
11-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值