DisassemblyData
描述要显示的集成开发环境(IDE)的一个反汇编指令。
语法
public struct DisassemblyData {
public uint dwFields;
public string bstrAddress;
public string bstrAddressOffset;
public string bstrCodeBytes;
public string bstrOpcode;
public string bstrOperands;
public string bstrSymbol;
public ulong uCodeLocationId;
public TEXT_POSITION posBeg;
public TEXT_POSITION posEnd;
public string bstrDocumentUrl;
public uint dwByteOffset;
public uint dwFlags;
};
成员
dwFields
DISAS标准版MBLY_STREAM_FIELDS 常量,用于指定填写哪些字段。
bstrAddress
地址作为一些起点的偏移量(通常是关联函数的开头)。
bstrCodeBytes
此指令的代码字节。
bstrOpcode
此指令的操作码。
bstrOperands
此指令的操作数。
bstrSymbol
与地址(公共符号、标签等)关联的符号名称(如果有)。
uCodeLocationId
此反汇编行的代码位置标识符。 如果一行的代码上下文地址大于另一行的代码上下文地址,则第一行的反汇编代码位置标识符也将大于第二行的代码位置标识符。
posBeg
对应于 反汇编数据开始的文档中位置的TEXT_POSITION 。
posEnd
对应于 反汇编数据结束的文档中位置的TEXT_POSITION 。
bstrDocumentUrl
对于可表示为文件名的文本文档,将使用 bstrDocumentUrl
格式填充源 file://file name
的文件名。
对于不能表示为文件名的文本文档, bstrDocumentUrl
是文档的唯一标识符,并且调试引擎必须实现 GetDocument 方法。
此字段还可以包含有关检查和的其他信息。 有关详细信息,请参阅“备注”。
dwByteOffset
指令的字节数来自代码行的开头。
dwFlags
DISAS标准版MBLY_FLAGS常量,该常量指定哪些标志处于活动状态。
注解
每个 DisassemblyData
结构描述一个反汇编指令。 从 Read 方法返回这些结构的数组。
TEXT_POSITION结构仅用于基于文本的文档。 仅针对从语句或行生成的第一个指令(例如,何时 dwByteOffset == 0
)填写此指令的源代码范围。
对于非文本的文档,可以从代码获取文档上下文,字段 bstrDocumentUrl
应为 null 值。 bstrDocumentUrl
如果该字段与bstrDocumentUrl
上DisassemblyData
一个数组元素中的字段相同,则将其设置为 bstrDocumentUrl
null 值。
dwFlags
如果字段设置了DF_DOCUMENT_CHECKSUM
标志,则其他检查和信息遵循字段指向的bstrDocumentUrl
字符串。 具体而言,在 null 字符串终止符之后,会遵循一个 GUID,标识检查和算法,该算法又后跟一个 4 字节值,指示检查和中的字节数,而后跟检查和字节。 请参阅本主题中的示例,了解如何在 Visual C# 中对此字段进行编码和解码。
示例
如果DF_DOCUMENT_CHECKSUM
设置了标志,该bstrDocumentUrl
字段可以包含字符串以外的其他信息。 创建和读取此编码字符串的过程在 Visual C++ 中非常简单。 但是,在 Visual C# 中,这是另一回事。 对于那些好奇的人,以下示例显示了从 Visual C# 创建编码字符串的一种方法,以及解码 Visual C# 中编码字符串的一种方法。
using System;
using System.Runtime.InteropServices;
namespace MyNamespace
{
class MyClass
{
string EncodeData(string documentString,
Guid checksumGuid,
byte[] checksumData)
{
string returnString = documentString;
if (checksumGuid == null || checksumData == null)
{
// Nothing more to do. Just return the string.
return returnString;
}
returnString += '\0'; // separating null value
// Add checksum GUID to string.
byte[] guidDataArray = checksumGuid.ToByteArray();
int guidDataLength = guidDataArray.Length;
IntPtr pBuffer = Marshal.AllocCoTaskMem(guidDataLength);
for (int i = 0; i < guidDataLength; i++)
{
Marshal.WriteByte(pBuffer, i, guidDataArray[i]);
}
// Copy guid data bytes to string as wide characters.
// Assumption: sizeof(char) == 2.
for (int i = 0; i < guidDataLength / sizeof(char); i++)
{
returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
}
// Add checksum count (a 32-bit value).
Int32 checksumCount = checksumData.Length;
Marshal.StructureToPtr(checksumCount, pBuffer, true);
for (int i = 0; i < sizeof(Int32) / sizeof(char); i++)
{
returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
}
// Add checksum data.
pBuffer = Marshal.AllocCoTaskMem(checksumCount);
for (int i = 0; i < checksumCount; i++)
{
Marshal.WriteByte(pBuffer, i, checksumData[i]);
}
for (int i = 0; i < checksumCount / sizeof(char); i++)
{
returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
}
Marshal.FreeCoTaskMem(pBuffer);
return returnString;
}
void DecodeData( string encodedString,
out string documentString,
out Guid checksumGuid,
out byte[] checksumData)
{
documentString = String.Empty;
checksumGuid = Guid.Empty;
checksumData = null;
IntPtr pBuffer = Marshal.StringToBSTR(encodedString);
if (null != pBuffer)
{
int bufferOffset = 0;
// Parse string out. String is assumed to be Unicode.
documentString = Marshal.PtrToStringUni(pBuffer);
bufferOffset += (documentString.Length + 1) * sizeof(char);
// Parse Guid out.
// Read guid bytes from buffer and store in temporary
// buffer that contains only the guid bytes. Then the
// Marshal.PtrToStructure() can work properly.
byte[] guidDataArray = checksumGuid.ToByteArray();
int guidDataLength = guidDataArray.Length;
IntPtr pGuidBuffer = Marshal.AllocCoTaskMem(guidDataLength);
for (int i = 0; i < guidDataLength; i++)
{
Marshal.WriteByte(pGuidBuffer, i,
Marshal.ReadByte(pBuffer, bufferOffset + i));
}
bufferOffset += guidDataLength;
checksumGuid = (Guid)Marshal.PtrToStructure(pGuidBuffer, typeof(Guid));
Marshal.FreeCoTaskMem(pGuidBuffer);
// Parse out the number of checksum data bytes (always 32-bit value).
int dataCount = Marshal.ReadInt32(pBuffer, bufferOffset);
bufferOffset += sizeof(Int32);
// Parse out the checksum data.
checksumData = new byte[dataCount];
for (int i = 0; i < dataCount; i++)
{
checksumData[i] = Marshal.ReadByte(pBuffer, bufferOffset + i);
}
}
}
}
}