首页 > 其他分享 >8.4 ProcessHeap

8.4 ProcessHeap

时间:2023-09-26 12:33:37浏览次数:51  
标签:ForceFlags 8.4 ProcessHeap mov eax 调试 hProcess

ProcessHeap 是Windows进程的默认堆,每个进程都有一个默认的堆,用于在进程地址空间中分配内存空间。默认情况下ProcessHeap由内核进行初始化,该堆中存在一个未公开的属性,它被设置为加载器为进程分配的第一个堆的位置(进程堆标志),ProcessHeap标志位于PEB结构中偏移为0x18处,第一个堆头部有一个属性字段,这个属性叫做ForceFlags属性偏移为0x44,该属性为0说明程序没有被调试,非0说明被调试,另外的Flags属性为2说明被调试,不为2则说明没有被调试。

0:000> dt !_peb
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x018 ProcessHeap      : Ptr32 Void       // 找到Process偏移地址

0:000> !heap                                  // 找出堆区首地址
        Heap Address      NT/Segment Heap
             1270000              NT Heap

0:000> !heap -a 1270000                       // 查询heep的内存
Index   Address  Name      Debugging options enabled
  1:   01270000 
    Segment at 01270000 to 0136f000 (00006000 bytes committed)
    Flags:                40000062
    ForceFlags:           40000060
    Granularity:          8 bytes
    Segment Reserve:      00100000
    Segment Commit:       00002000

0:000> dt _HEAP 1270000                       // 找到ForceFlags标志的偏移地址
ntdll!_HEAP
   +0x000 Segment          : _HEAP_SEGMENT
   +0x000 Entry            : _HEAP_ENTRY
   +0x040 Flags            : 0x40000062
   +0x044 ForceFlags       : 0x40000060

这里需要注意一点,堆区在不同系统中偏移值是不同的,在Windows10系统中ForceFlags属性位于堆头部偏移量为0x44处,而默认情况如果被调试则ForceFlags属性为0x40000060,而Flags标志为0x40000062,有了这些参考那么通过汇编语言实现将变得很容易,如下代码则是通过汇编分别读取这两个堆头参数;

#include <stdio.h>
#include <windows.h>

// 两种方式输出
int IsDebug(DWORD x)
{
    DWORD Debug = 0;

    if (x == 1)
    {
        __asm
        {
            mov eax, fs:[0x18]       // TED基地址
            mov eax, [eax + 0x30]    // PEB基地址
            mov eax, [eax + 0x18]    // 定位 ProcessHeap
            mov eax, [eax + 0x44]    // 定位到 ForceFlags
            mov Debug, eax
        }
    }
    if (x == 2)
    {
        __asm
        {
            mov eax, fs:[0x18]       // TED基地址
            mov eax, [eax + 0x30]    // PEB基地址
            mov eax, [eax + 0x18]    // 定位 ProcessHeap
            mov eax, [eax + 0x40]    // 定位到 Flags
            mov Debug, eax
        }
    }

    return Debug;
}

int main(int argc, char * argv[])
{
    if (IsDebug(1) && IsDebug(2))
    {
        printf("[-] 进程正在被调试 \n");
    }
    else
    {
        printf("[*] 进程正常 \n");
    }

    system("pause");
    return 0;
}

另一种通过C语言实现的反调试版本,其反调试原理与上方相同,只不过此处我们使用了系统的API来完成检测标志位的。

#include <stdio.h>
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS(NTAPI *typedef_ZwQueryInformationProcess)(
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength OPTIONAL
    );

BOOL IsDebug()
{
    HANDLE hProcess = NULL;
    DWORD ProcessId = 0;
    PROCESS_BASIC_INFORMATION Pbi;
    typedef_ZwQueryInformationProcess pZwQueryInformationProcess = NULL;
    ProcessId = GetCurrentProcessId();
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
    if (hProcess != NULL)
    {
        HMODULE hModule = LoadLibrary("ntdll.dll");
        pZwQueryInformationProcess = (typedef_ZwQueryInformationProcess)GetProcAddress(hModule, "ZwQueryInformationProcess");

        NTSTATUS Status = pZwQueryInformationProcess(hProcess, ProcessBasicInformation, &Pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
        if (NT_SUCCESS(Status))
        {
            DWORD ByteRead = 0;
            DWORD ProcessHeap = 0;
            ULONG PebBase = (ULONG)Pbi.PebBaseAddress;
            DWORD ForceFlagsValue = 1;

            ReadProcessMemory(hProcess, (LPCVOID)(PebBase + 0x18), &ProcessHeap, 2, &ByteRead);
            ReadProcessMemory(hProcess, (LPCVOID)(ProcessHeap + 0x40), &ForceFlagsValue, 4, &ByteRead);

            if (ForceFlagsValue != 0)
            {
                return TRUE;
            }
        }
        CloseHandle(hProcess);
    }
    return FALSE;
}

int main(int argc, char * argv[])
{
    if (IsDebug())
    {
        printf("[-] 正在被调试 \n");
    }

    system("pause");
    return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/e45d84ae.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

标签:ForceFlags,8.4,ProcessHeap,mov,eax,调试,hProcess
From: https://www.cnblogs.com/LyShark/p/17729830.html

相关文章

  • 有n个整数,使前面各数顺序向后m个位置,最后m个数变成最前面m个数,见图 8.43。写一函数实
    4,有n个整数,使前面各数顺序向后m个位置,最后m个数变成最前面m个数,见图8.43。写一函数实现以上功能在主函数中输入个整数和输出调整后的n个数。我的代码:1.使用双向链表voidMoveDLink(DoubleListhead,intm,intn){/*寻找原链表第n-m个节点*/DoubleListcurrent......
  • KubeSphere 社区双周报 | Java functions framework 支持 SkyWalking | 2023.8.4-8.17
    KubeSphere社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过commit的贡献者,并对近期重要的PR进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。本次双周报涵盖时间为:2023.08.04-2023.08.17。贡献者名单新晋KubeSphereCon......
  • CLO Standalone 7(3D服装设计软件) v7.1.178.42210 (x64)中文永久使用
    CLOStandalone7是一款专业的3D服装设计软件,它为服装设计师和制造商提供了先进的工具和功能,以快速而准确地创建、模拟和可视化服装设计。点击获取CLOStandalone7 CLOStandalone7具有以下主要特点和功能:三维虚拟设计:CLOStandalone7使用先进的三维建模技术,可以在虚拟......
  • WT6020同步降压24V降8.4V5A
    WT6020是高效率的,利用抖动频率,平均电流模式架构的单片同步降压DC/DC转换器。具有出色的线路和负载调节能力,能够提供高达10A的连续负载。该器件在7V至30V的输入电压范围内工作,并提供1V至25V的可调输出电压。WT6020具有短路和热保护电路,以提高系统可靠性。内部软启动避免了启动......
  • 8.4
    今天看到天梯赛的题我是真的头疼,可能太久没碰过这玩意了吧,感觉生疏的不行,主要是思路过不去了.一些简单的问题总是,变成复杂的思路,害得我半天整不出来,真的想吐.计算思维我是真的服..希望我可以哦在剩下的半个月找回点感觉吧. ......
  • 2023.8.4
    P4513小白逛公园求区间的最大子段和。一眼线段树题。那么我们考虑对于线段树的每个节点应该怎么维护:对于每个节点,额外设几个变量:sum,ml,mr,ms,分别表示区间和、包含左端点的最大子段和,包含右端点的最大子段和,最大子段和。我们用p1,p2来表示左儿子和右儿子。ms的维护:......
  • 暑假周记(8.4)
    今天早上是被热醒的,一开始没在意,后来发现我卧室的空调也报废了,正好,借着两个空调都坏了,让老舅把烦人的表妹接走了,上午给小孩们上完课,中午就睡在唯一一个好空调所在的地方——厨房,也算刷新人生经历,第一次在厨房睡觉了,可是翻了好久的身,根本睡不着,那床太小了,跟我肩膀一样宽,长度也跟身......
  • 8.4
    集合框架被设计成要满足以下几个目标。该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。对一个集合的扩展和适应必须是简单的。为此,整个集合框架就围绕一组标准接口而设计。你可以......
  • 8.4做题记录
    上午1#include<bits/stdc++.h>2usingnamespacestd;3intmain()4{5freopen("str.in","r",stdin);6freopen("str.out","w",stdout);7strings="a";8intn,k;9cin&......
  • 8.4总结
    今天比较忙一点,弄学生会的事情,搞不明白为啥上面这么nc,自己给我发的文件有好几处错误,害得我两次重新弄那个,真的无语,哎,没办法了,今晚最后一稿交上去了,我觉得问题不大了,接着让我准备防洪的,我没照片怎么弄啊,还不让用网上的照片累心......