首页
社区
课程
招聘
[原创]跨进程内存读取, 附源码
发表于: 2009-6-26 21:24 52959

[原创]跨进程内存读取, 附源码

2009-6-26 21:24
52959

在科锐学习的第4阶段, 保护模式课后作业,跨进程内存读写的小工具.

第一次内核编程,代码写的比较乱,不免也有些错误.各位牛哥们,见笑乐,!时间仓促,也没对代码进程封装,和界面相关太多.
1.  切换目标进程的CR3
      通常,跨进程读写内存,用到ReadProcessMemory, WriteProcessMemory, 但需要进程句柄,如果目标进程受到保护,可能获得进程句柄会失败.
      ReadProcessMemory最后会调用到KeStackAttachProcess附加到目标进程上切换进程环境进行拷贝的, 所以想到拿到目标进程的虚拟内存内容,可以将目标进程的页目录基地址放入CR3中即可.

首先要获得目标进程的cr3寄存器,即页目录基地址(开启PAE, 页目录指针表),
每个进程在内核里都有一个EPROCESS结构.

nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   …….
nt!_KPROCESS
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 ProfileListHead  : _LIST_ENTRY
   +0x018 DirectoryTableBase : [2] Uint4B
   +0x020 LdtDescriptor    : _KGDTENTRY
   +0x028 Int21Descriptor  : _KIDTENTRY
   ………
// 获得当前进程EPROCESS信息
            ULONG uEprocess = 0;
            __asm
            {
                mov eax, fs:[0x124]    // _ethread
                mov eax, [eax+0x44]    // _kprocess
                mov uEprocess, eax
            }

            KdPrint(("EPROCESS: 0x%08x\n", uEprocess));
            LIST_ENTRY ListHead;
            InitializeListHead(&ListHead);

            ULONG uFirstEprocess = uEprocess;
            ULONG uCount = 0;
            PLIST_ENTRY pActiveProcessLinks;
            ProcessInfoList *pProcssList = NULL;

            ULONG uNameOffset = GetPlantformDependentInfo(FILE_NAME_OFFSET);
            ULONG uPidOffset = GetPlantformDependentInfo(PROCESS_ID_OFFSET);
            ULONG uLinkOffset = GetPlantformDependentInfo(PROCESS_LINK_OFFSET);
            ULONG uExitTime = GetPlantformDependentInfo(EXIT_TIME_OFFSET);
            // 遍历链表获得进程信息
            do 
            {
                
                pProcssList= 
                    (ProcessInfoList *)ExAllocatePool(PagedPool, sizeof(ProcessInfoList));
                if (pProcssList == NULL)
                {
                    status = STATUS_INSUFFICIENT_RESOURCES;
	            break;
                }

                PLARGE_INTEGER ExitTime;
                ExitTime = (PLARGE_INTEGER)(uEprocess + uExitTime);
                if (ExitTime->QuadPart == 0)
                {
                    if (*(int *)(uEprocess + uPidOffset) <= 0)
                    {
                        pProcssList->ProcInfo.uProcessId = 0;
                        pProcssList->ProcInfo.uEprocess = uEprocess;
                        pProcssList->ProcInfo.uCR3 = *(PULONG)(uEprocess + 0x18);
                        RtlCopyMemory(pProcssList->ProcInfo.pszImageFileName, "Idle", 16);
                        InsertHeadList(&ListHead, &pProcssList->ListEntry);
                        KdPrint(("PID: %d, EPROCESS: 0x%08x, FileName: %s, CR3: 0x%08x\n",
                            pProcssList->ProcInfo.uProcessId,
                            pProcssList->ProcInfo.uEprocess,
                            pProcssList->ProcInfo.pszImageFileName,
                            pProcssList->ProcInfo.uCR3));
                    }
                    else
                    {

                        pProcssList->ProcInfo.uEprocess = uEprocess;
                        pProcssList->ProcInfo.uCR3 = *(PULONG)(uEprocess + 0x18);
                        pProcssList->ProcInfo.uProcessId = *(PULONG)(uEprocess + uPidOffset);
                        RtlCopyMemory(pProcssList->ProcInfo.pszImageFileName, 
                            (PVOID)(uEprocess + uNameOffset), 
                            16);
                        InsertHeadList(&ListHead, &pProcssList->ListEntry);
                        KdPrint(("PID: %d, EPROCESS: 0x%08x, FileName: %s, CR3:  0x%08x\n",
                            pProcssList->ProcInfo.uProcessId,
                            pProcssList->ProcInfo.uEprocess,
                            pProcssList->ProcInfo.pszImageFileName,
                            pProcssList->ProcInfo.uCR3));


                    }
                    uCount++;
                }

                pActiveProcessLinks = (PLIST_ENTRY)(uEprocess + uLinkOffset);
                uEprocess = (ULONG)pActiveProcessLinks->Blink - uLinkOffset;


                if (uEprocess == uFirstEprocess)
                {
                    break;
                }
            } while (uEprocess != 0);
            _try
            {
                WriteMemoryInfo *pInfo = 
                    (WriteMemoryInfo *)ExAllocatePool(PagedPool, sizeof(WriteMemoryInfo));

                RtlCopyMemory(pInfo, pIoBuffer, sizeof(WriteMemoryInfo));

                PVOID pWrite =  ExAllocatePool(PagedPool, pInfo->nWriteSize);

                RtlCopyMemory(pWrite, pInfo->pData, pInfo->nWriteSize);
                //pInfo->pData = (PBYTE)ExAllocatePool(PagedPool, pInfo->nWriteSize);
                ULONG uOldCr3 = 0;
                ULONG uCurrentCr3 = *(PULONG)(pInfo->nEprocess + 0x18);
                if (pInfo->nMemoryAddr == 0)
                {
                    status = STATUS_UNSUCCESSFUL;
                    break;
                }
                __asm
                {
                    mov eax, cr3
                    mov uOldCr3, eax

                    mov eax, uCurrentCr3
                    mov cr3, eax
                }

                __asm
                {
                    cli
                    push eax
                    mov eax, cr0
                    and eax, not 10000h
                    mov cr0, eax
                }

                RtlCopyMemory((PVOID)pInfo->nMemoryAddr, 
                    pWrite, pInfo->nWriteSize);

                __asm

                {
                    mov eax, CR0
                    or eax, 10000h
                    mov cr0,eax
                    pop eax
                    sti

                }
                __asm
                {
                    mov eax, uOldCr3
                    mov cr3, eax
                }


                uOutSize = pInfo->nWriteSize;
                if (pInfo != NULL)
                {

                    ExFreePool(pInfo);
                    pInfo = NULL;
                }
                // Return success
                status = STATUS_SUCCESS;
            }
            __except(1)
            {
                status = STATUS_UNSUCCESSFUL;
            }
            __try
            {   
                ReadMemoryInfo *pInfo = 
                    (ReadMemoryInfo *)ExAllocatePool(PagedPool, sizeof(ReadMemoryInfo));
                RtlCopyMemory(pInfo, pIoBuffer, sizeof(ReadMemoryInfo));
                ULONG uOldCr3 = 0;
                ULONG uCurrentCr3 = *(PULONG)(pInfo->nEprocess + 0x18);
                if (pInfo->nMemoryAddr == 0)
                {
                    status = STATUS_UNSUCCESSFUL;
                    break;
                }
                __asm
                {
                    mov eax, cr3
                    mov uOldCr3, eax

                    mov eax, uCurrentCr3
                    mov cr3, eax

                }
                RtlCopyMemory(pIoBuffer, 
                    (PVOID)pInfo->nMemoryAddr ,pInfo->nReadSize);
                uOutSize = pInfo->nReadSize;
                __asm
                {
                    mov eax, uOldCr3
                    mov cr3, eax
                }

                if (pInfo != NULL)
                {
                    ExFreePool(pInfo);
                    pInfo = NULL;
                }
                // Return success
                status = STATUS_SUCCESS;
            }
            __except(1)
            {
                status = STATUS_UNSUCCESSFUL;
            }
// 获得CR4的值
__asm
{
      _emit 0x0F 
      _emit 0x20
      _emit 0xE0
      mov uCR4, eax
}
// 获得页目录表项(PDE)
dwPageDirIndex = (dwVirtualAddr & 0xffc00000) >> 22;
DWORD dwPageDirEntry = ReadPageDirEntryNoPAE(dwPageDirIndex);
if (dwPageDirEntry == 0)
{
    return;
}
// 获得页大小
DWORD CReadMemoryDlg::GetPageSizeNoPAE(DWORD dwAddr)
{
    if ((dwAddr & 0x00000080) == 0x00000080)
    {
        return MBSIZE;
    }
    else
    {
        return KBSIZE;
    }
}
dwPageTableIndex = (dwVirtualAddr & 0x0003ff000) >> 12;
DWORD dwPageTableBaseAddr = dwPageDirEntry & 0xfffff000;
// 获得页表
DWORD dwPageTable = ReadPageTableNoPAE(dwPageTableBaseAddr, 
                    		dwPageTableIndex);
if (dwPageTable == 0)
{
     return;
}
if (IsPresentNoPAE(dwPageTable) == FALSE)
{
     return;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (74)
雪    币: 342
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
写得好学习一下
2009-6-27 13:54
0
雪    币: 339
活跃值: (72)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
3
很强,支持源码附带。
2009-6-27 14:11
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
很不错,下载学习,多谢楼主分享。
2009-6-27 17:40
0
雪    币: 2548
活跃值: (965)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
5
支持楼主分享
2009-6-27 17:42
0
雪    币: 116
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
果真是瞌睡就有人送枕头 谢过LZ
2009-6-27 18:11
0
雪    币: 63
活跃值: (17)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
顶一下 有源代码看看
2009-6-27 21:40
0
雪    币: 226
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
谢谢,支持一下.
2009-6-27 21:53
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
9
没仔细看 是指可以抛弃ReadProcessMemory, WriteProcessMemory了么?
2009-6-27 22:04
0
雪    币: 95
活跃值: (11)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
是这样的,,,
2009-6-27 23:20
0
雪    币: 1024
活跃值: (240)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
11
好文章 顶之
2009-6-27 23:22
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
不错,好文,学习
2009-6-27 23:41
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
呵呵 不错 是我学习的对象, ,哎 现在还看不懂 我才第二阶段,学完了希望能像你一样强!学习
2009-6-28 01:20
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
好复杂呀...      直接 KeStackAttachProcess目标  不是很方便吗?
2009-6-28 06:24
0
雪    币: 107
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
学习下,楼主你辛苦啦
2009-6-28 07:22
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
16

如果KeStackAttachProcess被XX了呢?光图方便可是不行的~
2009-6-28 07:39
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
17
进来学校1下PAE模式
2009-6-28 08:36
0
雪    币: 290
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
好贴啊,占个位置仔细膜拜
2009-6-28 09:42
0
雪    币: 62
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
19
好文,顶之
2009-6-28 15:01
0
雪    币: 260
活跃值: (18)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
占位,方便查阅!
2009-6-28 16:29
0
雪    币: 308
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
强大!!!!!
2009-6-29 00:14
0
雪    币: 25
活跃值: (477)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
22
????????????????????????????
2009-6-29 00:24
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
看不懂..头
2009-6-29 00:29
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
不错的好文章,直接跳到内存分页去读取内存,好思路啊,学习学习
2009-6-29 15:23
0
雪    币: 1373
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
有源码,练习一下。
2009-6-29 15:59
0
游客
登录 | 注册 方可回帖
返回
//