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:\windows\system32\ 目录下

后者的dll模块在C:\windows\sysWOW64\ 目录下

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:\windows\system32\

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

操作了C:\windows\sysWOW64\ 目录,只是显示的名字是C:\windows\system32\

注册表操作同样被重定向,例如HKLM\SOFTWARE\的键时将被定向到HKLM\SOFTWARE\Wow6432Node  

 

 

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\time 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中的进程进行一些操作时将会有些麻烦.

转载于:https://www.cnblogs.com/freesec/p/6566923.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值