在内存地址004A9640 写入 E803,怎么实现?
谢谢先!

解决方案 »

  1.   


    using System;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;class MyClass
    {
        public static void Main()
        {
            Marshal.WriteInt32((IntPtr)(0x004A9640), 0xE803);
        }
    }
    还有很多方法在Marshal类中,楼主可以去看一下。希望我的回答会有帮助。
      

  2.   

    报错是正常的,你要改写的内存地址是保护状态的,不可以访问。要是可以随便对任意内存做修改,那系统的安全性何在啊。要改写的内存必须是可以访问的,可写的。具体操作系统的内存管理机制,你可以看看《windows核心编程》。PS. 刚重新看了你的问题,发现应该用Marshal.WriteInt16,不过读写还是会报错的。至于在C#中如何获得任意内存的读写权限,这是个难题啊。
      

  3.   

    错误 1 与“System.Runtime.InteropServices.Marshal.WriteInt16(System.IntPtr, short)”最匹配的重载方法具有一些无效参数 D:\My Documents\Visual Studio 2005\w3\ConsoleApplication2\ConsoleApplication2\Program.cs 9 9 ConsoleApplication2
    错误 2 参数“2”: 无法从“int”转换为“short” D:\My Documents\Visual Studio 2005\w3\ConsoleApplication2\ConsoleApplication2\Program.cs 9 50 ConsoleApplication2
    还是报错呢请教请教,谢谢先!
      

  4.   

    我的意思是指你要先把地址变成可写,可访问,才可以用WriteInt16来写入。004A9640这个地址貌似不可写啊,系统还没有给这个虚拟地址分配物理地址。
      

  5.   

    在内存地址004A9640 写入 E803
    我不知道在什么情况下写入……
    是DOS?Windows?Linux...
    IDE是TASM,MASM,GNU C++,VC,...
    在DOS或者裸机上写汇编,先进入CPU的保护模式,再设置CS,最后在004A9640处写入E803……
    在Windows下,可以先进入ring0级,然后写内存……
    进入ring0,厄,百度一下“汇编进入ring0”吧……
    以下来自:http://www.hackbase.com/tech/2009-04-24/52406.html
    2009-04-24 10:40:11  www.hackbase.com  来源:邪恶八进制信息安全团队
    本篇文章来源于 黑客基地-全球最大的中文黑客站 原文链接:http://www.hackbase.com/tech/2009-04-24/52406.html关键字:NT,Ring0,无驱。
    测试环境:Windows 2000 SP4,Windows XP SP2,Windows 2003 未测试在NT下无驱进入Ring0是一个老生常谈的方法了,网上也有一些C代码的例子,我之所以用汇编重写是因为上次在 
    [原创/探讨]Windows 核心编程研究系列之一(改变进程 PTE) 
    的帖子中自己没有实验成功(其实已经成功了,只是自己太马虎,竟然还不知道 -_-b),顺面聊聊PM(保护模式)中的调用门的使用情况。鉴于这些都是可以作为基本功来了解的知识点,所以对此已经熟悉的朋友就可以略过不看了,当然由于本人水平有限,各位前来“挑挑刺”也是非常欢迎的,呵呵。 下面言归正传,我们知道在NT中进入Ring0的一般方法是通过驱动,我的Windows 核心编程研究系列 文章前两篇都使用了 这个方法进入Ring0 完成特定功能。现在我们还可以通过在Ring3下直接写物理内存的方法来进入Ring0,其主要步骤是:0 以写权限打开物理内存对象; 
    1 取得 系统 GDT 地址,并转换成物理地址; 
    2 构造一个调用门; 
    3 寻找 GDT 中空闲的位置,将 CallGate 植入; 
    4 Call植入的调用门。 前面已打通主要关节,现在进一步看看细节问题: 
    [零] 默认只有 System 用户有写物理内存的权限 administrators 组的用户只有读的权限,但是通过修改用户安全对象中的DACL 可以增加写的权限:
    Copy code
    _SetPhyMemDACLs proc uses ebx edi esi \ 
    _hPhymem:HANDLE,\ 
    _ptusrname:dword 
    local @dwret:dword 
    local @htoken:HANDLE 
    local @hprocess:HANDLE 
    local @个
    local @OldDACLs:PACL
    local @SecurityDescriptor:PSECURITY_DESCRIPTOR 
    local @Access:EXPLICIT_ACCESS 
    mov @dwret,FALSE 
    invoke RtlZeroMemory,addr @NewDACLs,sizeof @NewDACLs 
    invoke RtlZeroMemory,addr @SecurityDescriptor,\ 
    sizeof @SecurityDescriptor 
    invoke GetSecurityInfo,_hPhymem,SE_KERNEL_OBJECT,\ 
    DACL_SECURITY_INFORMATION,NULL,NULL,\ 
    addr @OldDACLs,NULL,\ 
    addr @SecurityDescriptor 
    .if eax != ERROR_SUCCESS 
    jmp SAFE_RET 
    .endif 
    invoke RtlZeroMemory,addr @Access,sizeof @Access 
    mov @Access.grfAccessPermissions,SECTION_ALL_ACCESS 
    mov @Access.grfAccessMode,GRANT_ACCESS 
    mov @Access.grfInheritance,NO_INHERITANCE 
    mov @Access.stTRUSTEE.MultipleTrusteeOperation,\ 
    NO_MULTIPLE_TRUSTEE 
    mov @Access.stTRUSTEE.TrusteeForm,TRUSTEE_IS_NAME 
    mov @Access.stTRUSTEE.TrusteeType,TRUSTEE_IS_USER 
    push _ptusrname 
    pop @Access.stTRUSTEE.ptstrName 
    invoke GetCurrentProcess 
    mov @hprocess,eax 
    invoke OpenProcessToken,@hprocess,TOKEN_ALL_ACCESS,\ 
    addr @htoken 
    invoke SetEntriesInAcl,1,addr @Access,\ 
    @OldDACLs,addr @NewDACLs 
    .if eax != ERROR_SUCCESS 
    jmp SAFE_RET 
    .endif 
    invoke SetSecurityInfo,_hPhymem,SE_KERNEL_OBJECT,\ 
    DACL_SECURITY_INFORMATION,NULL,NULL,\ 
    @NewDACLs,NULL 
    .if eax != ERROR_SUCCESS 
    jmp SAFE_RET 
    .endif 
    mov @dwret,TRUE 
    SAFE_RET: 
    .if @NewDACLs != NULL 
    invoke LocalFree,@NewDACLs 
    mov @NewDACLs,NULL 
    .endif 
    .if @SecurityDescriptor != NULL 
    invoke LocalFree,@SecurityDescriptor 
    mov @SecurityDescriptor,NULL 
    .endif 
    mov eax,@dwret 
    ret 
    _SetPhyMemDACLs endp
    [一] 可以在Ring3下使用SGDT指令取得系统GDT表的虚拟地址,这条指令没有被Intel设计成特权0级的指令。据我的观察,在 Windows 2000 SP4 中 GDT 表的基址都是相同的,而且在虚拟机VMware5.5 虚拟的 Windows 2000 SP4中执行 SGDT 指令后返回的是错误的结果,在虚拟的 Windows XP 中也有同样情况,可能是虚拟机的问题,大家如果有条件可以试一下:
    local @stGE:GDT_ENTRY 
    mov @dwret,FALSE 
    lea esi,@stGE 
    sgdt fword ptr [esi] 
    assume esi:ptr GDT_ENTRY 
    ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
    ;在 VMware 虚拟环境下用以下两条指令替代 
    ;只用于 Windows 2000 SP4 
    ;mov [esi].Base,80036000h 
    ;mov [esi].Limit,03ffh 
    ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
    mov eax,[esi].Base 
    invoke @GetPhymemLite,eax 
    .if eax == FALSE 
    jmp quit 
    .endif 
    下面就是虚拟地址转换物理地址了,这在Ring0中很简单,直接调用MmGetPhysicalAddress 即可,但在Ring3中要另想办法,还好系统直接将 0x80000000 – 0xa0000000 影射到物理0地址开始的位置,所以可以写一个轻量级的GetPhysicalAddress来替代。:)Copy code
    @GetPhymemLite proc uses esi edi ebx _vaddr 
    local @dwret:dword 
    mov @dwret,FALSE 
    .if _vaddr < 80000000h 
    jmp quit 
    .endif 
    .if _vaddr >= 0a0000000h 
    jmp quit 
    .endif 
    mov eax,_vaddr 
    and eax,01ffff000h ;or sub eax,80000000h 
    mov @dwret,eax 
    quit: 
    mov eax,@dwret 
    ret 
    @GetPhymemLite endp
    [二]调用门在保护模式中可以看成是低特权级代码向高特权级代码转换的一种实现机制,如图1所示(由于本人较懒,所以借用李彦昌先生所著的80x86保护模式系列教程 中的部分截图,希望李先生看到后不要见怪 ^-^):
    .....(省略-_-///)