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
입력할 필드를 지정하는 DISASSEMBLY_STREAM_FIELDS 상수입니다.
bstrAddress
주소는 일부 시작점(일반적으로 연결된 함수의 시작 부분)의 오프셋입니다.
bstrCodeBytes
이 명령의 코드 바이트입니다.
bstrOpcode
이 명령의 opcode입니다.
bstrOperands
이 명령의 피연산자입니다.
bstrSymbol
주소(공용 기호, 레이블 등)와 연결된 기호 이름(있는 경우)입니다.
uCodeLocationId
이 디스어셈블된 줄의 코드 위치 식별자입니다. 한 줄의 코드 컨텍스트 주소가 다른 줄의 코드 컨텍스트 주소보다 크면 첫 번째 줄의 디스어셈블된 코드 위치 식별자도 두 번째 줄의 코드 위치 식별자보다 큽니다.
posBeg
디스어셈블리 데이터가 시작되는 문서의 위치에 해당하는 TEXT_POSITION입니다.
posEnd
디스어셈블리 데이터가 끝나는 문서의 위치에 해당하는 TEXT_POSITION입니다.
bstrDocumentUrl
파일 이름으로 표시할 수 있는 텍스트 문서의 경우 bstrDocumentUrl
필드는 file://file name
형식을 사용하여 원본을 찾을 수 있는 파일 이름으로 채워집니다.
파일 이름으로 나타낼 수 없는 텍스트 문서의 경우 bstrDocumentUrl
은 문서의 고유 식별자이며 디버그 엔진은 GetDocument 메서드를 구현해야 합니다.
이 필드에는 체크섬에 대한 추가 정보가 포함될 수도 있습니다. 자세한 내용은 설명을 참조하세요.
dwByteOffset
명령이 코드 줄의 시작에서 가져온 바이트 수입니다.
dwFlags
활성 상태인 플래그를 지정하는 DISASSEMBLY_FLAGS 상수입니다.
설명
각 DisassemblyData
구조는 디스어셈블리의 한 가지 지침을 설명합니다. 이러한 구조체의 배열은 Read 메서드에서 반환됩니다.
TEXT_POSITION 구조체는 텍스트 기반 문서에만 사용됩니다. 이 명령의 소스 코드 범위는 문 또는 줄에서 생성된 첫 번째 명령(예: dwByteOffset == 0
인 경우)에 대해서만 채워집니다.
텍스트가 아닌 문서의 경우 코드에서 문서 컨텍스트를 가져올 수 있으며 bstrDocumentUrl
필드는 null 값이어야 합니다. bstrDocumentUrl
필드가 이전 DisassemblyData
배열 요소의 bstrDocumentUrl
필드와 같으면 bstrDocumentUrl
을 null 값으로 설정합니다.
dwFlags
필드에 DF_DOCUMENT_CHECKSUM
플래그가 설정된 경우 bstrDocumentUrl
필드가 가리키는 문자열 뒤에 추가 체크섬 정보가 추가됩니다. 특히 null 문자열 종결자 뒤에는 체크섬 알고리즘을 식별하는 GUID와 체크섬의 바이트 수를 나타내는 4바이트 값이 차례로 표시되고 그 뒤에 체크섬 바이트가 옵니다. Visual C#에서 이 필드를 인코딩하고 디코딩하는 방법은 이 항목의 예제를 참조하세요.
예시
bstrDocumentUrl
필드는 DF_DOCUMENT_CHECKSUM
플래그가 설정된 경우 문자열 이외의 추가 정보를 포함할 수 있습니다. 이 인코딩된 문자열을 만들고 읽는 프로세스는 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);
}
}
}
}
}