• 【旧文章搬运】获取并修改PEB中的映像路径,命令行和当前目录


    原文发表于百度空间,2008-7-24

    当时对UNICODE_STRING的使用还有点问题,导致最终效果图中字符串被截断了
    ==========================================================================

    先从分析PEB开始吧.
    感觉分析这个东西,首先要把类型定义搞清楚,这个在Windbg里dt _PEB就可以了
    搞清楚定义主要是为了定位相关变量的偏移.
    PEB中的ProcessParameters部分就是进程的参数了,里面就有我们感兴趣的映像路径等信息
    之所以对这个感兴趣,是因为以前看到过修改PEB中的映像路径过防火墙的
    获取PEB很简单,也早有人说过这个问题.
    在用户模式下,fs寄存器指向TEB结构,在TEB开头部分是这么定义的:
    lkd> dt _TEB
    nt!_TEB
       +0x000 NtTib            : _NT_TIB
       +0x01c EnvironmentPointer : Ptr32 Void
       +0x020 ClientId         : _CLIENT_ID
       +0x028 ActiveRpcHandle : Ptr32 Void
       +0x02c ThreadLocalStoragePointer : Ptr32 Void
       +0x030 ProcessEnvironmentBlock : Ptr32 _PEB        //这个就指向PEB

    再看PEB的开头部分:
    lkd> dt _PEB
    nt!_PEB
       +0x000 InheritedAddressSpace : UChar
       +0x001 ReadImageFileExecOptions : UChar
       +0x002 BeingDebugged    : UChar
       +0x003 SpareBool        : UChar
       +0x004 Mutant           : Ptr32 Void
       +0x008 ImageBaseAddress : Ptr32 Void
       +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
       +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS //指向进程的参数

    再来看_RTL_USER_PROCESS_PARAMETERS 的结构:
    lkd> dt _RTL_USER_PROCESS_PARAMETERS
    nt!_RTL_USER_PROCESS_PARAMETERS
       +0x000 MaximumLength    : Uint4B
       +0x004 Length           : Uint4B
       +0x008 Flags            : Uint4B
       +0x00c DebugFlags       : Uint4B
       +0x010 ConsoleHandle    : Ptr32 Void
       +0x014 ConsoleFlags     : Uint4B
       +0x018 StandardInput    : Ptr32 Void
       +0x01c StandardOutput   : Ptr32 Void
       +0x020 StandardError    : Ptr32 Void
       +0x024 CurrentDirectory : _CURDIR   //当前目录
       +0x030 DllPath          : _UNICODE_STRING
       +0x038 ImagePathName    : _UNICODE_STRING  //映像路径
       +0x040 CommandLine      : _UNICODE_STRING     //命令行
       +0x048 Environment      : Ptr32 Void
       +0x04c StartingX        : Uint4B
       +0x050 StartingY        : Uint4B
       +0x054 CountX           : Uint4B
       +0x058 CountY           : Uint4B
       +0x05c CountCharsX      : Uint4B
       +0x060 CountCharsY      : Uint4B
       +0x064 FillAttribute    : Uint4B
       +0x068 WindowFlags      : Uint4B
       +0x06c ShowWindowFlags : Uint4B
       +0x070 WindowTitle      : _UNICODE_STRING
       +0x078 DesktopInfo      : _UNICODE_STRING
       +0x080 ShellInfo        : _UNICODE_STRING
       +0x088 RuntimeData      : _UNICODE_STRING
       +0x090 CurrentDirectores : [32] _RTL_DRIVE_LETTER_CURDIR

    到这儿,应该就比较清楚了,反正这些东西都是在用户空间的,可以看也可以改.
    关键代码如下:

    typedef struct _RTL_USER_PROCESS_PARAMETERS
    {
    DWORD MaximumLength;
    DWORD Length;
    DWORD Flags;
    DWORD DebugFlags;
    HANDLE ConsoleHandle;
    DWORD ConsoleFlags;
    HANDLE StandardInput;
    HANDLE StandardOutput;
    HANDLE StandardError;
    CURDIR CurrentDirectory;
    UNICODE_STRING DllPath;
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
    void* Environment; //指向MULTI的宽字符串
    DWORD StartingX;
    DWORD StartingY;
    DWORD CountX;
    DWORD CountY;
    DWORD CountCharsX;
    DWORD CountCharsY;
    DWORD FillAttribute;
    DWORD WindowFlags;
    DWORD ShowWindowFlags;
    UNICODE_STRING WindowTitle;
    UNICODE_STRING DesktopInfo;
    UNICODE_STRING ShellInfo;
    UNICODE_STRING RuntimeData;
    RTL_DRIVE_LETTER_CURDIR CurrentDirectores;
    }RTL_USER_PROCESS_PARAMETERS;
    
    void* PEB;
    PWSTR p;
    PWSTR fakeImagePath=L"I am achillis,this is fake image path";
    PWSTR fakeCommandLine=L"I am achillis,this is fake commandline";
    PWSTR fakeCurrentDirectory=L"I am achillis,this is fake CurrentDirectory";
    RTL_USER_PROCESS_PARAMETERS *pUserParam;
    _asm
    {
    mov eax,fs:[0x30] //TEB->PEB
    mov eax,[eax+0x10]   //PEB->ProcessParameters
    mov pUserParam,eax 
    }
    printf("RTL_USER_PROCESS_PARAMETERS:0x%08x
    ",pUserParam);
    //输出映像路径等信息
    //wprintf(L"DllPath:%s
    ",pUserParam->DllPath.Buffer);
    wprintf(L"[ImagePath]:%s
    ",pUserParam->ImagePathName.Buffer);
    wprintf(L"[CommandLine]:%s
    ",pUserParam->CommandLine.Buffer);
    wprintf(L"[CurrentDirectory]:%s
    ",pUserParam->CurrentDirectory.DosPath.Buffer);
    //修改其中的内容
    lstrcpyW(pUserParam->ImagePathName.Buffer,fakeImagePath);
    lstrcpyW(pUserParam->CommandLine.Buffer,fakeCommandLine);
    lstrcpyW(pUserParam->CurrentDirectory.DosPath.Buffer,fakeCurrentDirectory);
    

    效果还行,但是路径那块儿还是有问题,被截断了.
    丢个图吧,高手飘过~

     

  • 相关阅读:
    Spring 发生 has not been refreshed yet 异常
    rsyslog config
    grok
    阿里云态势
    Unity的asm笔记
    Unity2020或Unity2019安装后无法启动
    rider代码折叠
    使用rider调试lua
    MacType更好的字体渲染
    Unity字体和画面花屏处理
  • 原文地址:https://www.cnblogs.com/achillis/p/10178381.html
Copyright © 2020-2023  润新知