能力值:
( LV7,RANK:110 )
|
-
-
2 楼
我晕啊,原因很简单啊,就是代码段具有写保护属性,写入的时候会受到CPU的保护,如果强行写入的话,系统会崩溃的,解决的办法有三个:
1。关闭CPU的写保护,也就是设置CR0寄存器(直接更改CPU写保护状态,容易和别的软件冲突,不推荐)
2 用NTAPI改变对应地址的保护属性,在属性里面加入写属性(Zw*系列函数)(函数没有在内核导出,但是已经在NTDLL.DLL中导出了,比较难,但是使用具有很强的稳定性)
3 创建一个内存描述符 也就是创建对应地址的MDL (使用 MmCreateMdl 或者 IoCreateMdl),然后通过内存描述符取得一个内核地址,这个地址是你要写入的地址在内核的映射,并且这个内核地址你在取得时,通过加入写属性(API调用的时候默认已经加入),让这个内核地址可写就可以了(比较容易,并且稳定,推荐使用)
|
能力值:
( LV7,RANK:110 )
|
-
-
3 楼
给你两个函数,功能是把一个不可写,但可读的地址,映射为一个内核可读可写的内核地址的函数,但是这个函数要求同一个上下文
PMDL NTAPI IoCreateWriteMdlForAddress(PVOID InAddress,PVOID *OutAddress,size_t Size)
{
PMDL pMdl=NULL;
if(Size>0)
{
if((InAddress==NULL)|(Size==0))
return NULL;
// if(!MmIsAddressValid(InAddress))
// return NULL;
if(OutAddress==NULL)
return NULL;
if(!MmIsAddressValid(OutAddress))
return NULL;
}
else
{
return NULL;
}
pMdl=MmCreateMdl(NULL,InAddress,Size);
if(pMdl==NULL)
{
return NULL;
}
MmBuildMdlForNonPagedPool(pMdl);
// My_Mdl->MdlFlags = My_Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
if(!FlagOn(pMdl->MdlFlags,MDL_MAPPED_TO_SYSTEM_VA))
SetFlag(pMdl->MdlFlags,MDL_MAPPED_TO_SYSTEM_VA);
*OutAddress=MmMapLockedPages(pMdl, KernelMode);
return pMdl;
}
VOID NTAPI IoFreeMdlForAddress(PVOID Address,PMDL pMdl)
{
MmUnmapLockedPages(Address,pMdl);
IoFreeMdl(pMdl);
}
我看你的代码,太简陋了吧!只能读取本进程的内存的,不能读取别的进程(原因很简单,你没有切换进程上下文),下次麻烦你写这样的程序的时候,去看一下微软的2000系统的源代码,还有微软的2003的源代码(2003内核源代码是公开的),他们写的内存复制函数没有你那么简陋的
本来想现在帮你更改的,但是时间不够了,今天晚上先了。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
偶的问题木有高人这么热心呢 可能台简单了吧
另外问问 if (MmIsAddressValid(Pbuff))
ProbeForRead ((CONST PVOID)Pbuff, BufferSize, sizeof(CHAR));
这2个函数都是连用啊。偶经常就是不知道该用哪个 结果楼主2个同时用 偶豁然开朗啊
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
不清楚这段话是你自己总结的,还是网上查到的。第2点说的根本就是错的,误导人!
ntdll.dll是ring3层的模块,导不导出函数也都是给ring3调用的,只是ring3进入ring0的接口,除此之外,跟内核调用没有任何直接联系。修改页属性的常规方法就是在ring0使用第1和3两个方法。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
试了第一种方法
//关保护
__asm
{
push eax
mov eax, CR0
and eax, 0FFFEFFFFh
mov CR0, eax
pop eax
}
//开保护
__asm
{
push eax
mov eax, CR0
or eax, NOT 0FFFEFFFFh
mov CR0, eax
pop eax
}
分别加在写内存函数的前后,不过还是写不了
我是想读目标进程里面的代码段,不是自己进程里的代码段 !
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
楼主要读别的进程 这种方式肯定不奏效了哦。楼上大牛都说了
要进行进程上下文context的切换 至于如何切换 呵呵
我也没搞过 静观其变了 哈哈
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
谢谢czcqq的提示和你的代码
用第三种方法成功了,继续研究
|
能力值:
( LV7,RANK:110 )
|
-
-
9 楼
5楼的, 这么简单的问题,你都不知道?通过查找NTDLL.DLL中的Zw系列函数的开头的一条指令
例如 mov eax,101 的函数序列号,就可以在SSDT表中找到NT下对应的函数的内核函数地址
|
能力值:
( LV7,RANK:110 )
|
-
-
10 楼
楼主,你在开关写保护的时候,你写入失败是因为你没有切换到目标进程的上下文环境中
|
能力值:
( LV7,RANK:110 )
|
-
-
11 楼
使用这个函数KeAttachProcess 就可以了
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
第三种方法是成功了,不过在目标进程写入代码之后,关掉进程在打开这个进程,那个地址的代码还是关掉之前写入之后的样子。怎么取消这个映射呢
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
首先,第2条和你现在说的跟修改页属性(LZ所问)没有任何联系,答非所问。
再者,你既然知道这个原理,何不在ring0通过ntoskrnl.exe导出的Zw*来获取Nt*在SSDT中的索引号?ring3获得了有啥意义,不一样还得传到ring0?多此一举~
|
能力值:
( LV3,RANK:20 )
|
-
-
14 楼
请教一下 映射问题解决了么?
|
|
|