通常有两种类型的SIMD指令:
A.使用对齐的内存地址的那些,如果地址未在操作数大小边界上对齐,则会引发一般保护(#GP)异常:
movaps xmm0, xmmword ptr [rax]
vmovaps ymm0, ymmword ptr [rax]
vmovaps zmm0, zmmword ptr [rax]
Run Code Online (Sandbox Code Playgroud)
B.以及使用未对齐内存地址的那些,不会引发此类异常:
movups xmm0, xmmword ptr [rax]
vmovups ymm0, ymmword ptr [rax]
vmovups zmm0, zmmword ptr [rax]
Run Code Online (Sandbox Code Playgroud)
但是我只是好奇,为什么我要用脚射击自己并使用第一组的对齐记忆指令呢?
我一直在努力修改来自 Microsoft 的此代码示例,该示例显示(有些过时)如何从可执行文件中检索代码签名信息。它可以工作,但如果二进制文件是双重签名的,则它不会检索信息。
所以我做了一些研究并尝试重写它以使其识别 Windows 中许多现代可执行文件中存在的双重签名。不幸的是,很少有(模糊的)建议可用(1),(2),例如使用UnauthenticatedAttributes和szOID_NESTED_SIGNATURE(无论这意味着什么)但仅用于检索时间戳的建议。
所以我试图重写那个微软代码,这是我得到的:
(要构建它,只需将其复制到 Visual Studio 控制台项目中并更改 .exe 文件路径。处理双重签名的代码在PrintDualSignatureInfo()函数中。)
#include "stdafx.h"
//SOURCE:
// https://support.microsoft.com/en-us/help/323809/how-to-get-information-from-authenticode-signed-executables
//
#include <windows.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <stdio.h>
#include <tchar.h>
#include <atlconv.h>
#pragma comment(lib, "crypt32.lib")
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
typedef struct {
LPWSTR lpszProgramName;
LPWSTR lpszPublisherLink;
LPWSTR lpszMoreInfoLink;
} SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO;
BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
PSPROG_PUBLISHERINFO Info);
BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st);
BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext);
BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO …Run Code Online (Sandbox Code Playgroud) 我试图了解SSE / AVX指令的VEX前缀编码。因此,请问我是否提出简单的要求。我有以下相关问题。
让我们来看一下MOVUP(D / S)指令(0F 10)。如果我正确遵循2字节VEX前缀编码:
以下两种指令编码产生相同的结果:
db 0fh, 10h, 00000000b ; movups xmm0,xmmword ptr [rax]
db 0c5h, 11111000b, 10h, 00000000b ; vmovups xmm0,xmmword ptr [rax]
Run Code Online (Sandbox Code Playgroud)
由于这两个:
db 066h, 0fh, 10h, 00000000b ; movupd xmm0,xmmword ptr [rax]
db 0c5h, 11111001b, 10h, 00000000b ; vmovupd xmm0,xmmword ptr [rax]
Run Code Online (Sandbox Code Playgroud)
因此,我的问题是:
v这些说明中的第一个代表什么?仅仅是表示VEX前缀的使用吗?
如果我VEX在上面的示例中使用或不使用前缀,是否有任何区别(指令长度除外)?
我试图在他们的文档中了解Intel的语法。说,此屏幕截图:
在VEX.128.0F.WIG我可以看到的.128是L第二个VEX字节的位2()。然后.0F是一个3字节的VEX前缀,m-mmmm格式为00001,对吗?但是 …
只是为了学习这一点,我试图掌握如何使用HLE 前缀 XACQUIRE和XRELEASE. 阅读英特尔文档后,我的理解是,在执行带有XACQUIRE前缀的指令后,CPU 进入某种写锁,直到带有XRELEASE前缀的指令。所以我写了下面的测试代码,看看我是否正确。嗯,还有一些我不明白的地方,因为我的代码示例失败了。
那么有人可以告诉我这些 HLE 前缀遗漏了什么吗?
两次失败:
该xtest指令报告未启用 HLE,并且
因为我假设的“mutex-ed”代码不作为互斥体运行,所以它无法并发。
接下来是Windows C++项目,用VS 2017编译的x64 .asm文件如下:
.code
testCPUID PROC
push rbx
; CPUID.07h.EBX.HLE[bit 4]==1
mov eax, 7h
xor ecx, ecx
cpuid
and rbx, 1 shl 4
mov rax, rbx
pop rbx
ret
testCPUID ENDP
testHLEWrite PROC
; RCX = pointer to TST91 struct:
; void* pPtrToNextWrite;
; int nNextValue;
; void* pCutoffPtr;
; void* pBeginPtr;
xor edx, edx
xacquire xchg …Run Code Online (Sandbox Code Playgroud) 我正在阅读有关控制寄存器的 Intel 文档,但我很难理解 CR8 寄存器的使用方式。引用文档(2-18卷3A):
\n\n\n\n\n任务优先级(CR8 的位 3:0)\xe2\x80\x94 这设置对应于要阻止的最高优先级中断的阈值\n。A\n 值为 0 表示所有中断均已启用。该字段在 64 位模式下可用。值 15 表示所有中断将被禁用。
\n
如果您不介意的话,我有 3 个简短的问题:
\n\n因此 CR8 的位 3 到 0 构成了这 16 个优先级值。但优先事项是什么?我认为是一个正在运行的“线程”,对吗?
但是,与接收中断以查看是否必须被阻止时相比,CR8 中的优先级值是多少?
当中断被阻塞时,这意味着什么?它是“延迟”到以后的时间,还是只是被丢弃,即丢失?
我知道有些库可以"解析"二进制机器代码/操作码来告诉x86-64 CPU指令的长度.
但我想知道,因为CPU有内部电路来确定这一点,有没有办法使用处理器本身来告诉二进制代码的指令大小?(甚至可能是黑客?)
我试图了解D flag在 x86-64 代码中使用时代码段描述符中的工作原理。它设置在D/B代码段描述符的第 22 位,如下图所示:
D/B(默认操作大小/默认堆栈指针大小和/或上限)标志
根据段描述符是可执行代码段、向下扩展数据段还是堆栈段执行不同的功能。(对于 32 位代码和数据段,此标志应始终设置为 1,对于 16 位代码和数据段,应始终设置为 0。)
• 可执行代码段。该标志称为 D 标志,它表示段中指令引用的有效地址和操作数的默认长度。如果设置了标志,则假定为 32 位地址和 32 位或 8 位操作数;如果清楚,则假定为 16 位地址和 16 位或 8 位操作数。指令前缀 66H 可用于选择默认值以外的操作数大小,前缀 67H 可用于选择默认值以外的地址大小。
所以我试图了解它影响哪些 x86-64 指令以及如何影响?
附注。当我尝试通过设置该位来运行一些测试(在 Windows 内核中)时,操作系统立即出现三重故障。