首页
社区
课程
招聘
[讨论][求助]用切换CR3来读写进程内存,那么如何获取真实CR3
发表于: 2018-11-16 11:32 12008

[讨论][求助]用切换CR3来读写进程内存,那么如何获取真实CR3

2018-11-16 11:32
12008
刚刚看了一下看雪论坛里某帖子开源的驱动读写某保护进程,好像用的就是用KeStackAttachProcess(pEProcess,&KAPC);这个函数附加到目标进程(你们说是什么挂靠)我想这个函数里面难道不是用切换CR3读写的吗?

如果CR3被隐藏或保护是不是用上述的挂靠方式一样不能读写内存??问题还是回到了下面,还有多少种方法可以获得真正的CR3?



64位驱动已实现利用切换CR3的方式来读写进程内存,听说有些进程会对自身的DirectoryTableBase做手脚,那么还有别的方法可以获取真实的CR3吗?之前看某看雪大佬说HOOK KiSwapContext获取真实CR3,这是其中一个方法,我想问有没有不用HOOK的方法获取真实CR3,毕竟64位过PG也很烦。。。

祝看雪论坛越办越好,相助国人IT水平整体提高~

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2018-11-16 14:56 被Jy王编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (29)
雪    币: 12848
活跃值: (9108)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
2
@腾讯游戏安全中心 @gslab
2018-11-16 14:39
1
雪    币: 433
活跃值: (1895)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
回调啊 坛子里有说的
2018-11-16 14:46
0
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
萌克力 回调啊 坛子里有说的
我等会查查回调的相关资料看看,是线程回调吗?
2018-11-16 14:58
0
雪    币: 209
活跃值: (778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
自己的CreateProcess或LoadImage回调的功能:
根据游戏进程名,保存游戏进程的EPROCESS
根据游戏进程名,保存游戏进程的页表
使用自己备份的页表读写游戏进程的内存
KeStackAttachProcess、RtlCopyMemory


DNF不是伪造,是清零。找到原始CR3写回去就OK了 
2018-11-16 16:20
2
雪    币: 914
活跃值: (2293)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
6
注册线程回调,
回调里直接 PsGetCurrentProcess() ->PsGetProcessImageFileName()
判断当前进程是否是目标进程,是目标进程则 __readcr3().

插APC,强行插进去直接 __readcr3().
2018-11-16 16:22
2
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
惊电 自己的CreateProcess或LoadImage回调的功能: 根据游戏进程名,保存游戏进程的EPROCESS 根据游戏进程名,保存游戏进程的页表 使用自己备份的页表读写游戏进程的内存 Ke ...
先送10个雪碧,您说的方案我等会回家查阅资料实现看看!感谢您!
2018-11-16 16:32
1
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
万剑归宗 注册线程回调, 回调里直接 PsGetCurrentProcess() ->PsGetProcessImageFileName() 判断当前进程是否是目标进程,是目标进程则 __readcr ...
先送10个雪碧,您说的方案我等会回家查阅资料实现看看!感谢您!
2018-11-16 16:32
0
雪    币: 914
活跃值: (2293)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
9
Jy王 先送10个雪碧,您说的方案我等会回家查阅资料实现看看!感谢您!
如果是TP你就不要做这种浪费时间的事了,直接hook ShadowSSDT 或者 插APC
2018-11-16 16:35
0
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
大哥,注册回调线程是说的哪个函数啊?我开始以为是CrateThread呢,可是发现这个好像不对。。
2018-11-16 16:44
0
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
万剑归宗 注册线程回调, 回调里直接 PsGetCurrentProcess() ->PsGetProcessImageFileName() 判断当前进程是否是目标进程,是目标进程则 __readcr ...
大哥,注册回调线程是说的哪个函数啊?我开始以为是CrateThread呢,可是发现这个好像不对。。
2018-11-16 16:44
0
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
大哥这两个函数说的我一头雾水,我还是不太能理解怎么做,您有相关的资料或贴子能转发给我看下吗,我不知道该咋做,咋百度。。
2018-11-16 16:50
0
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
惊电 自己的CreateProcess或LoadImage回调的功能: 根据游戏进程名,保存游戏进程的EPROCESS 根据游戏进程名,保存游戏进程的页表 使用自己备份的页表读写游戏进程的内存 Ke ...
大哥这两个函数说的我一头雾水,我还是不太能理解怎么做,您有相关的资料或贴子能转发给我看下吗,我不知道该咋做,咋百度。。
2018-11-16 16:50
0
雪    币: 914
活跃值: (2293)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
14
Jy王 大哥这两个函数说的我一头雾水,我还是不太能理解怎么做,您有相关的资料或贴子能转发给我看下吗,我不知道该咋做,咋百度。。
https://bbs.pediy.com/thread-187348.htm
仔细看一遍。
最后于 2018-11-16 16:54 被万剑归宗编辑 ,原因:
2018-11-16 16:54
1
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
万剑归宗 Jy王 大哥这两个函数说的我一头雾水,我还是不太能理解怎么做,您有相关的资料或贴子能转发给我看下吗,我不知道该咋做,咋百度。。 https://bbs. ...
好的,谢谢你
2018-11-16 17:09
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
cr3早就不处理了,你现在拿到的cr3访问的页面都被清空了 没用
2018-11-16 21:03
0
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
fakersaber cr3早就不处理了,你现在拿到的cr3访问的页面都被清空了 没用
早就不处理指的是哪个进程不处理,页面被清空那么内存数据都存哪去。。。你说的清空页面应该是页面转移了吧。。。进程总得分配页面存储数据吧,都清空了还有进程吗。。。可能我说的不太对,仅有的知识水平就这个理解方式
2018-11-16 23:04
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
Jy王 早就不处理指的是哪个进程不处理,页面被清空那么内存数据都存哪去。。。你说的清空页面应该是页面转移了吧。。。进程总得分配页面存储数据吧,都清空了还有进程吗。。。可能我说的不太对,仅有的知识水平就这个理解 ...
你apc插入拿到的pml4e值跟启动游戏后从eprocess的值是一样的,现在不会清空cr3,清空的不是入口而是页表,真实的页表只有他的IDT中断处理里面判断给不给恢复。
2018-11-17 00:51
0
雪    币: 209
活跃值: (778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
它清空页表的时间能比你的CreateProcess回调通知更早?
如果是这样,那就直接Hook它的中断或异常处理,找到它保存的真实页表,或直接把它的判断逻辑给改了
2018-11-17 02:06
1
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
fakersaber 你apc插入拿到的pml4e值跟启动游戏后从eprocess的值是一样的,现在不会清空cr3,清空的不是入口而是页表,真实的页表只有他的IDT中断处理里面判断给不给恢复。
到底是清空页表还是页面我都搞糊涂了
2018-11-17 09:43
0
雪    币: 12848
活跃值: (9108)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
21
Jy王 到底是清空页表还是页面我都搞糊涂了
这么说吧 PTE->page_frame_number = 0
2018-11-17 19:13
2
雪    币: 34
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
hzqst 这么说吧 PTE->page_frame_number = 0
懂了,谢谢您
2018-11-18 11:42
1
雪    币: 634
活跃值: (1149)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
楼上说的 都别想了。除了3楼。以外说的 都别试了。以为这是5月前吗?开玩笑
2018-11-29 09:47
0
雪    币: 634
活跃值: (1149)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
24
我写的 是Attach进去 转物理 对部分游戏 有局限。要清缓存。清缓存的帖子已经删了。。
不要再去通过什么LoadImage APC啥的。拿CR3没用的对DNF 穿越XX还好。DNF废了
另外我写的Attach转物理 你把清CPU缓存的补充上改改 所有TX游戏都支持读写。不骗你。
这个给你  我开源过 好像在挂海还是哪里忘记了。。不知道你看过没。给你个思路。2月前的。照着这个思路你绝对可以 找到的 。
你要是真的想找TP备份的话 就下边这样。自己更新下吧
#include <ntddk.h>
#include <ntstrsafe.h>
#include <WinDef.h>
#include <intrin.h>
#ifdef __cplusplus
extern "C"
{
#endif
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT pPDriverObj, _In_ PUNICODE_STRING pRegistryPath);
VOID UnLoadDriver(_In_  PDRIVER_OBJECT pPDriverObj);
#ifdef __cplusplus
}
#endif

#pragma pack(push, 1)

typedef struct _IDTR //IDT基址
{
USHORT limit; //范围 占8位
ULONG64 base; //基地址 占32位 _IDT_ENTRY类型指针
}IDTR, *PIDTR;

typedef union _IDT_ENTRY
{
struct kidt
{
USHORT OffsetLow;
USHORT Selector;
USHORT IstIndex : 3;
USHORT Reserved0 : 5;
USHORT Type : 5;
USHORT Dpl : 2;
USHORT Present : 1;
USHORT OffsetMiddle;
ULONG OffsetHigh;
ULONG Reserved1;
}idt;
UINT64 Alignment;
} IDT_ENTRY, *PIDT_ENTRY;

#pragma pack(pop)

//输出调试内容
void DebugPrint(const char* fmt, ...)
{
UNREFERENCED_PARAMETER(fmt);
va_list ap;
va_start(ap, fmt);//将ap指向fmt后的第一个参数
vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, fmt, ap);
va_end(ap);//将ap置为NULL
return;
}

ULONG64 GetIdtAddr(ULONG64 pIdtBaseAddr, UCHAR pIndex)
/**
获取IDT表地址
**/
{
PIDT_ENTRY Pidt_info = (PIDT_ENTRY)(pIdtBaseAddr);
Pidt_info += pIndex;
ULONG64 vCurrentAddr = 0;
ULONG64 vCurrentHighAddr = 0;
vCurrentAddr = Pidt_info->idt.OffsetMiddle;
vCurrentAddr = vCurrentAddr << 16;
vCurrentAddr += Pidt_info->idt.OffsetLow;

vCurrentHighAddr = Pidt_info->idt.OffsetHigh;
vCurrentHighAddr = vCurrentHighAddr << 32;
vCurrentAddr += vCurrentHighAddr;
return vCurrentAddr;
}


NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT pPDriverObj, _In_ PUNICODE_STRING pRegistryPath)
{
UNREFERENCED_PARAMETER(pRegistryPath);
pPDriverObj->DriverUnload = (PDRIVER_UNLOAD)UnLoadDriver;

DebugPrint("驱动加载\n");

/**
TP版KiPageFault

fffff880`09f54000 50              push    rax
fffff880`09f54001 48b87830ce0980f8ffff mov rax,0FFFFF88009CE3078h  ---- 这里实际上是真实处理函数的地址 需要 & 0xFFFFFFFFFFF00000
fffff880`09f5400b 4883ec08        sub     rsp,8
fffff880`09f5400f 48890424        mov     qword ptr [rsp],rax
fffff880`09f54013 48311424        xor     qword ptr [rsp],rdx
fffff880`09f54017 e810000000      call    fffff880`09f5402c
fffff880`09f5401c 896eff          mov     dword ptr [rsi-1],ebp
fffff880`09f5401f 230500000089    and     eax,dword ptr [fffff87f`92f54025]

**/
//得到TP KiPageFault地址
_IDTR vContent;
__sidt(&vContent);
ULONG64 vTpKiPageFault = GetIdtAddr(vContent.base, 0xE);

//得到TP 动态内存起始值
ULONG64 vTpMemory = *(PULONG64)(vTpKiPageFault + 0x3) & 0xFFFFFFFFFFF00000;

//得到TP KiPageFault真实处理函数
ULONG64 vTpKiPageFaultFuncAddr = vTpMemory + 0x4CE7C;

if (MmIsAddressValid((PVOID)vTpKiPageFaultFuncAddr))
{//真实处理函数有效

//得到TP数据对象基地址
ULONG64 vTpDataObjectBase = *(PULONG)(vTpMemory + 0x1738B) + vTpMemory + 0x1738F;

if (MmIsAddressValid((PVOID)vTpDataObjectBase))
{//基地址有效

//得到TP 用来保存真实CR3 保存当前所属进程ID 的对象
ULONG64 vTpDataObject = *(PULONG64)vTpDataObjectBase;

DebugPrint("数据对象:0x%016llx, 真实CR3:0x%016llx, 所属进程ID:%d\n", vTpDataObject, *(PULONG64)(vTpDataObject + 0x70), *(PULONG)(vTpDataObject + 0x18));
}
else
DebugPrint("vTpDataObjectBase无法读取:0x%016llx\n", vTpDataObjectBase);
}
else
DebugPrint("vTpKiPageFaultFuncAddr无法读取:0x%016llx\n", vTpKiPageFaultFuncAddr);

return STATUS_SUCCESS;
}


/**
*卸载驱动
**/
VOID UnLoadDriver(_In_  PDRIVER_OBJECT pPDriverObj)
{
UNREFERENCED_PARAMETER(pPDriverObj);
DebugPrint("驱动卸载\n");
}
最后于 2018-11-29 10:18 被BDBig编辑 ,原因:
2018-11-29 09:48
2
雪    币: 634
活跃值: (1149)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
25
惊电 它清空页表的时间能比你的CreateProcess回调通知更早? 如果是这样,那就直接Hook它的中断或异常处理,找到它保存的真实页表,或直接把它的判断逻辑给改了
+1。这个方案,不错。实际获取真实的CR3就是搜tp的特征。。。至少我是这么干的。。。。
2018-11-29 09:51
0
游客
登录 | 注册 方可回帖
返回
//