zoukankan      html  css  js  c++  java
  • windows64 位 环境 与32位 环境

    1. LLP64 数据模型

    数据模型    short   int   long   longlong   指针    操作系统类型

    ILP32   2     4    4       8      4       win32

    LLP64   2    4    4    8      8     windows 64 位

    LP64   2    4    8    8      8      UNIX 64 位

    2.WOW64    参考: https://msdn.microsoft.com/en-us/library/aa384249(v=vs.85).aspx

    在64bit windows系统中, 64bit程序加载kernel32.dll和ntdll.dll等dll文件都是64bit的,而

    32bit程序加载的kernel32.dll和ntdll.dll等dll文件都是32bit的

    前者的dll模块在C:windowssystem32 目录下

    后者的dll模块在C:windowssysWOW64 目录下

    WOW64 机制会将32bit程序的API调用重定向到64bit的dll中.即API调用过程:

    程序->kernel32.dll(32bit的)->ntdll.dll(32bit的)->WOW64->ntdll.dll(64bit)->内核(64bit)

    此外WOW64机制只运行在ring3层上,内核驱动程序在64bit系统上必须编译成64bit的才能运行,否则会导致蓝屏

    WOW64的文件夹,注册表重定向机制: 32bit和64bit程序调用GetSystemDirectory()时都返回 C:windowssystem32

    而实际上32bit程序本应该返回C:windowssysWOW64. WOW64机制将其修改掉名字,而32bit程序如果操作该目录时还是

    操作了C:windowssysWOW64 目录,只是显示的名字是C:windowssystem32

    注册表操作同样被重定向,例如HKLMSOFTWARE的键时将被定向到HKLMSOFTWAREWow6432Node  

    3.通用寄存器

    e编程r, 共8字节, 低4字节仍然叫e..  如 rax, eax, ax, al

    call和jmp 指令 操作数. 当call和jmp的操作数是个从地址取数时使用相对偏移.例如:

    x       z    call   qword ptr [y]

    x是该指令地址,8字节,  z是该指令的机器码,6字节, y是个地址,8字节 即z的前2字节是call的机器码,为ff15 然后的值= y-x-6 取后4字节的值

    4.函数调用约定

    debug模式:

    main截取:
    DWORD n = test64(1, 2, 3, 4, 5, 6, 7); 00007FF672041AAE mov dword ptr [rsp+30h],7 00007FF672041AB6 mov dword ptr [rsp+28h],6 00007FF672041ABE mov dword ptr [rsp+20h],5 00007FF672041AC6 mov r9d,4 00007FF672041ACC mov r8d,3 00007FF672041AD2 mov edx,2 00007FF672041AD7 mov ecx,1 00007FF672041ADC call test64 (07FF67204134Dh) 00007FF672041AE1 mov dword ptr [n],eax

    DWORD WINAPI test64(int a, int b, int c, int d, int e, int f, int g)
    {
    00007FF6038C34F0 mov dword ptr [rsp+20h],r9d
    00007FF6038C34F5 mov dword ptr [rsp+18h],r8d
    00007FF6038C34FA mov dword ptr [rsp+10h],edx
    00007FF6038C34FE mov dword ptr [rsp+8],ecx
    00007FF6038C3502 push rbp
    00007FF6038C3503 push rdi
    00007FF6038C3504 sub rsp,0C8h ;提高栈顶来存变量
    00007FF6038C350B mov rbp,rsp
    00007FF6038C350E mov rdi,rsp
    00007FF6038C3511 mov ecx,32h
    00007FF6038C3516 mov eax,0CCCCCCCCh
    00007FF6038C351B rep stos dword ptr [rdi]
    00007FF6038C351D mov ecx,dword ptr [rsp+0E8h]
    return a + b + c + d + e + f + g;
    00007FF6038C3524 mov eax,dword ptr [b]
    00007FF6038C352A mov ecx,dword ptr [a]
    00007FF6038C3530 add ecx,eax
    00007FF6038C3532 mov eax,ecx
    00007FF6038C3534 add eax,dword ptr [c]
    00007FF6038C353A add eax,dword ptr [d]
    00007FF6038C3540 add eax,dword ptr [e]
    00007FF6038C3546 add eax,dword ptr [f]
    00007FF6038C354C add eax,dword ptr [g]
    }
    00007FF6038C3552 lea rsp,[rbp+0C8h] ;回收
    00007FF6038C3559 pop rdi
    00007FF6038C355A pop rbp
    00007FF6038C355B ret



    1.64bit的call前4个参数通过ecx,edx,r8d,r9d 寄存器传递, 后续的参数通过栈传递. 且直接将参数写到栈中,而不是通过push指令

    2.代码中指定了WINAPI(即__stdcall)调用方式仍然不以__stdcall方式传递参数. 通过栈传递的参数也没有移动rsp,只是以rsp作为基址来保存

    参数

    3.被调用函数中并没有平衡参数的栈帧

    4.返回值仍然通过rax传递

    release 模式:

    int main()
    {
    00007FF79A661000  sub         rsp,48h  
    
        handle_t a = CreateFile(0, 0, 0, 0, 0, 0, 0);
    00007FF79A661004  xor         eax,eax  
    00007FF79A661006  xor         r9d,r9d  
    00007FF79A661009  mov         qword ptr [rsp+30h],rax  
    00007FF79A66100E  xor         r8d,r8d  
    00007FF79A661011  mov         dword ptr [rsp+28h],eax  
    00007FF79A661015  xor         edx,edx  
    00007FF79A661017  xor         ecx,ecx  
    00007FF79A661019  mov         dword ptr [rsp+20h],eax  
    00007FF79A66101D  call        qword ptr [__imp_CreateFileW (07FF79A662000h)]  
    
       return 1;
    00007FF79A661023  mov         eax,1  
    }
    00007FF79A661028  add         rsp,48h  
    }
    00007FF79A66102C  ret  

    1.main函数中调用CreateFile 时,传递参数和debug模式是一样的规则

    2.main函数中直接通过rsp减去48h来保存这次的变量和参数的占用的空间,根本没有用到rbp和push,pop指令建立栈帧

    3.传递参数时rsp从20h开始(从第5个参数开始向后看), 说明rsp为前4个参数预留了空间

    CreateFileW:
    00007FFE1EB57158 sub rsp,58h 00007FFE1EB5715C mov r10d,dword ptr [rsp
    +88h] 00007FFE1EB57164 mov dword ptr [rsp+30h],20h 00007FFE1EB5716C mov eax,r10d 00007FFE1EB5716F and eax,7FB7h 00007FFE1EB57174 mov dword ptr [rsp+34h],eax 00007FFE1EB57178 mov eax,r10d 00007FFE1EB5717B and eax,0FFF00000h 00007FFE1EB57180 mov dword ptr [rsp+38h],eax 00007FFE1EB57184 bt r10d,14h 00007FFE1EB57189 jb 00007FFE1EB5A6E5 00007FFE1EB5718F and dword ptr [rsp+3Ch],0 00007FFE1EB57194 mov rax,qword ptr [rsp+90h] 00007FFE1EB5719C and dword ptr [rsp+28h],0 00007FFE1EB571A1 mov qword ptr [rsp+40h],r9 00007FFE1EB571A6 mov r9d,dword ptr [rsp+80h] 00007FFE1EB571AE mov qword ptr [rsp+48h],rax 00007FFE1EB571B3 lea rax,[rsp+30h] 00007FFE1EB571B8 mov qword ptr [rsp+20h],rax 00007FFE1EB571BD call 00007FFE1EB571D0 00007FFE1EB571C2 add rsp,58h 00007FFE1EB571C6 ret

    5.PE32+ 与PE32比较

    nt头:

    typedef struct _IMAGE_NT_HEADERS64 {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER64 OptionalHeader; //不同
    } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
    
    typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER32 OptionalHeader; //不同
    } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

    可选头:

    typedef struct _IMAGE_OPTIONAL_HEADER {
        WORD    Magic;          //值不同
        BYTE    MajorLinkerVersion;
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;
        DWORD   SizeOfInitializedData;
        DWORD   SizeOfUninitializedData;
        DWORD   AddressOfEntryPoint;
        DWORD   BaseOfCode;
        DWORD   BaseOfData;    //被删除
        DWORD   ImageBase;    //类型不同
        DWORD   SectionAlignment;
        DWORD   FileAlignment;
        WORD    MajorOperatingSystemVersion;
        WORD    MinorOperatingSystemVersion;
        WORD    MajorImageVersion;
        WORD    MinorImageVersion;
        WORD    MajorSubsystemVersion;
        WORD    MinorSubsystemVersion;
        DWORD   Win32VersionValue;
        DWORD   SizeOfImage;
        DWORD   SizeOfHeaders;
        DWORD   CheckSum;
        WORD    Subsystem;
        WORD    DllCharacteristics;
        DWORD   SizeOfStackReserve; //下面几个栈堆字段类型不同
        DWORD   SizeOfStackCommit;
        DWORD   SizeOfHeapReserve;
        DWORD   SizeOfHeapCommit;
        DWORD   LoaderFlags;
        DWORD   NumberOfRvaAndSizes;
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;typedef struct _IMAGE_OPTIONAL_HEADER64 {    WORD        Magic;
        BYTE        MajorLinkerVersion;
        BYTE        MinorLinkerVersion;
        DWORD       SizeOfCode;
        DWORD       SizeOfInitializedData;
        DWORD       SizeOfUninitializedData;
        DWORD       AddressOfEntryPoint;
        DWORD       BaseOfCode;
        ULONGLONG   ImageBase;
        DWORD       SectionAlignment;
        DWORD       FileAlignment;
        WORD        MajorOperatingSystemVersion;
        WORD        MinorOperatingSystemVersion;
        WORD        MajorImageVersion;
        WORD        MinorImageVersion;
        WORD        MajorSubsystemVersion;
        WORD        MinorSubsystemVersion;
        DWORD       Win32VersionValue;
        DWORD       SizeOfImage;
        DWORD       SizeOfHeaders;
        DWORD       CheckSum;
        WORD        Subsystem;
        WORD        DllCharacteristics;
        ULONGLONG   SizeOfStackReserve;
        ULONGLONG   SizeOfStackCommit;
        ULONGLONG   SizeOfHeapReserve;
        ULONGLONG   SizeOfHeapCommit;
        DWORD       LoaderFlags;
        DWORD       NumberOfRvaAndSizes;
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;


    IMAGE_THUNK_DATA:

    typedef struct _IMAGE_THUNK_DATA32 {
        union {
            DWORD ForwarderString;      // PBYTE 
            DWORD Function;             // PDWORD
            DWORD Ordinal;
            DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME
        } u1;//类型不同
    } IMAGE_THUNK_DATA32;
    typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
    typedef struct _IMAGE_THUNK_DATA64 {
        union {
            ULONGLONG ForwarderString;  // PBYTE 
            ULONGLONG Function;         // PDWORD
            ULONGLONG Ordinal;
            ULONGLONG AddressOfData;    // PIMAGE_IMPORT_BY_NAME
        } u1;
    } IMAGE_THUNK_DATA64;
    typedef IMAGE_THUNK_DATA64 * PIMAGE_THUNK_DATA64;

    导入表描述符倒是一样的

    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        union {
            DWORD   Characteristics;            // 0 for terminating null import descriptor
            DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
        } DUMMYUNIONNAME;
        DWORD   TimeDateStamp;                  // 0 if not bound,
                                                // -1 if bound, and real date	ime stamp
                                                //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                                // O.W. date/time stamp of DLL bound to (Old BIND)
    
        DWORD   ForwarderChain;                 // -1 if no forwarders
        DWORD   Name;
        DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
    } IMAGE_IMPORT_DESCRIPTOR;
    typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

    线程局部存储:

    typedef struct _IMAGE_TLS_DIRECTORY64 {
        ULONGLONG StartAddressOfRawData;
        ULONGLONG EndAddressOfRawData;
        ULONGLONG AddressOfIndex;         // PDWORD
        ULONGLONG AddressOfCallBacks;     // PIMAGE_TLS_CALLBACK *;
        DWORD SizeOfZeroFill;
        union {
            DWORD Characteristics;
            struct {
                DWORD Reserved0 : 20;
                DWORD Alignment : 4;
                DWORD Reserved1 : 8;
            } DUMMYSTRUCTNAME;
        } DUMMYUNIONNAME;
    
    } IMAGE_TLS_DIRECTORY64;
    
    typedef IMAGE_TLS_DIRECTORY64 * PIMAGE_TLS_DIRECTORY64;
    
    typedef struct _IMAGE_TLS_DIRECTORY32 {
        DWORD   StartAddressOfRawData;
        DWORD   EndAddressOfRawData;
        DWORD   AddressOfIndex;             // PDWORD
        DWORD   AddressOfCallBacks;         // PIMAGE_TLS_CALLBACK *
        DWORD   SizeOfZeroFill;
        union {
            DWORD Characteristics;
            struct {
                DWORD Reserved0 : 20;
                DWORD Alignment : 4;
                DWORD Reserved1 : 8;
            } DUMMYSTRUCTNAME;
        } DUMMYUNIONNAME;
    
    } IMAGE_TLS_DIRECTORY32;
    typedef IMAGE_TLS_DIRECTORY32 * PIMAGE_TLS_DIRECTORY32;

    6.nt6.0及以上的内核的会话隔离机制

    基本介绍

    系统重要进程和服务进程都运行在会话0中, 而用户登录后启动的程序都在该用户所在的会话中,包括explorer. 在用户会话向

    会话0中的进程进行一些操作时将会有些麻烦.

  • 相关阅读:
    进阶篇:3.1.8)DFM塑胶-注射模具和设备
    PAT-甲级-1001-A+B Format
    腾讯-004-两个排序数组的中位数
    机器学习三 决策树
    腾讯-002-两数相加
    2018.3.15
    2018.3.14
    2018.3.13
    废代码合集
    边缘检测程序(matlab)
  • 原文地址:https://www.cnblogs.com/freesec/p/6566923.html
Copyright © 2011-2022 走看看