首页
社区
课程
招聘
[求助]为啥这两种写入都会导致目标进程无法再次启动,只能重启
发表于: 2022-5-1 20:33 6735

[求助]为啥这两种写入都会导致目标进程无法再次启动,只能重启

2022-5-1 20:33
6735
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
NTSTATUS WriteMemoryNormalMdl(IN HANDLE PID, IN  PVOID BaseAddress, IN SIZE_T Length, IN PVOID Buffer)
{
    BOOLEAN attach = FALSE;
    ULONG64 cr0 = 0;
    NTSTATUS Status = STATUS_SUCCESS;
    PEPROCESS pEProcess = NULL;
    KAPC_STATE ApcState = { 0 };
    Status = PsLookupProcessByProcessId(PID, &pEProcess);
    if (!NT_SUCCESS(Status) && !MmIsAddressValid(pEProcess)) { return STATUS_UNSUCCESSFUL; }
    __try
    {
        PMDL mdl = IoAllocateMdl(Buffer, Length, 0, 0, NULL);
 
        MmBuildMdlForNonPagedPool(mdl);
        unsigned char* Map = (unsigned char*)MmMapLockedPages(mdl, KernelMode);
        if (!Map)
        {
            IoFreeMdl(mdl);
            return NULL;
        }
 
        if (PsGetCurrentProcess() != pEProcess)
        {
            KeStackAttachProcess(pEProcess, &ApcState);
            attach = TRUE;
        }
 
        __try {
            if (MmIsAddressValid(BaseAddress))
            {
                cr0 = __readcr0();
                cr0 &= 0xfffffffffffeffff;
                __writecr0(cr0);
                _disable();
                RtlCopyMemory(BaseAddress, Map, Length);
                KeLowerIrql(KeRaiseIrqlToDpcLevel());
                cr0 = __readcr0();
                cr0 |= 0x10000;
                _enable();
                __writecr0(cr0);
            }
        }
        __except (1)
        {
            DbgPrint("MMC 无法访问地址.\n");
        }
        if (attach)KeUnstackDetachProcess(&ApcState);
        DbgPrint("MMC 释放内存\n");
        MmUnmapLockedPages((PVOID)Map, mdl);
        IoFreeMdl(mdl);
 
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        KeUnstackDetachProcess(&ApcState);
 
        Status = STATUS_UNSUCCESSFUL;
    }
    ObDereferenceObject(pEProcess);
    return Status;
}
 
 
NTSTATUS write(PEPROCESS pProcess, PVOID Address, PVOID AllocatedBuffer, SIZE_T size, SIZE_T* written)
{
    ULONG_PTR process_dirbase = GetProcessCr3(pProcess);
    NTSTATUS NtRet{};
    SIZE_T CurOffset = 0;
    SIZE_T TotalSize = size;
    while (TotalSize)
    {
        ULONG64 CurPhysAddr = TranslateLinearAddress(process_dirbase, (ULONG64)Address + CurOffset);
        if (!CurPhysAddr) return STATUS_UNSUCCESSFUL;
 
        ULONG64 WriteSize = min(PAGE_SIZE - (CurPhysAddr & 0xFFF), TotalSize);
        SIZE_T BytesWritten = 0;
        NtRet = WritePhysicalAddress((PVOID)CurPhysAddr, (PVOID)((ULONG64)AllocatedBuffer + CurOffset), WriteSize, &BytesWritten);
        TotalSize -= BytesWritten;
        CurOffset += BytesWritten;
        if (NtRet != STATUS_SUCCESS) break;
        if (BytesWritten == 0) break;
    }
 
    *written = CurOffset;
    return NtRet;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
2
无法触发cow
2022-5-1 23:05
0
雪    币: 184
活跃值: (285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
はつゆき 无法触发cow
要怎么解决呢,试了几份都这样
2022-5-3 05:16
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
4
ZwProtectVirtualMemory
2022-5-3 09:32
0
雪    币: 184
活跃值: (285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
はつゆき ZwProtectVirtualMemory
是指的ZwProtectVirtualMemory改属性,然后用其他的写入吗,不用这两个
2022-5-3 11:58
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
6
是的
2022-5-3 12:11
0
雪    币: 184
活跃值: (285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
はつゆき 是的
好的吧
2022-5-3 14:34
0
雪    币: 35
活跃值: (1796)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这种写法会连文件一起伪性修改了 下次打开,数据不正确就崩了
2022-5-10 12:42
0
雪    币: 184
活跃值: (285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
shuwoa 这种写法会连文件一起伪性修改了 下次打开,数据不正确就崩了
这两种有优化的解决的可能吗
2022-5-11 01:58
0
雪    币: 35
活跃值: (1796)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
往昔_2012 这两种有优化的解决的可能吗
读写的函数有一千万个,根本没必要用这种方法,这个方法只有一个好处,就是在映射内核地址并写入的时候不怕它是否被占用
2022-5-12 02:46
0
游客
登录 | 注册 方可回帖
返回
//