Skip to content

Commit d95a424

Browse files
committed
Handle not decodable instructions.
1 parent ede1e75 commit d95a424

File tree

1 file changed

+54
-67
lines changed

1 file changed

+54
-67
lines changed

NativeCore/Shared/DistormHelper.cpp

Lines changed: 54 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -58,99 +58,87 @@ bool AreOperandsStatic(const _DInst &instruction, const int prefixLength)
5858
return true;
5959
}
6060

61-
int GetStaticInstructionBytes(const _DInst &instruction, const uint8_t *data)
61+
_CodeInfo CreateCodeInfo(const uint8_t* address, int length, const _OffsetType virtualAddress)
6262
{
6363
_CodeInfo info = {};
64-
info.codeOffset = reinterpret_cast<_OffsetType>(data);
65-
info.code = data;
66-
info.codeLen = instruction.size;
64+
info.codeOffset = virtualAddress;
65+
info.code = address;
66+
info.codeLen = length;
6767
info.features = DF_NONE;
68+
6869
#ifdef RECLASSNET32
6970
info.dt = Decode32Bits;
7071
#else
7172
info.dt = Decode64Bits;
7273
#endif
7374

74-
_PrefixState ps = {};
75-
memset(ps.pfxIndexer, PFXIDX_NONE, sizeof(int) * PFXIDX_MAX);
76-
ps.start = data;
77-
ps.last = data;
78-
79-
prefixes_decode(data, info.codeLen, &ps, info.dt);
75+
return info;
76+
}
8077

81-
info.codeOffset = reinterpret_cast<_OffsetType>(ps.last);
82-
info.code = ps.last;
8378

84-
const auto prefixLength = static_cast<int>(ps.start - ps.last);
85-
info.codeLen -= prefixLength;
79+
int GetStaticInstructionBytes(const _DInst &instruction, const uint8_t *data)
80+
{
81+
auto info = CreateCodeInfo(data, instruction.size, reinterpret_cast<_OffsetType>(data));
8682

87-
inst_lookup(&info, &ps);
83+
_PrefixState ps = {};
84+
int isPrefixed;
85+
inst_lookup(&info, &ps, &isPrefixed);
8886

89-
if (AreOperandsStatic(instruction, prefixLength))
87+
if (AreOperandsStatic(instruction, ps.count))
9088
{
9189
return instruction.size;
9290
}
9391

94-
return instruction.size - info.codeLen;
92+
return instruction.size - info.codeLen - ps.count;
9593
}
9694

97-
_CodeInfo CreateCodeInfo(const RC_Pointer address, const RC_Size length, const RC_Pointer virtualAddress)
98-
{
99-
_CodeInfo info = {};
100-
info.codeOffset = reinterpret_cast<_OffsetType>(virtualAddress);
101-
info.code = reinterpret_cast<const uint8_t*>(address);
102-
info.codeLen = static_cast<int>(length);
103-
info.features = DF_NONE;
104-
105-
#ifdef RECLASSNET32
106-
info.dt = Decode32Bits;
107-
#else
108-
info.dt = Decode64Bits;
109-
#endif
110-
111-
return info;
112-
}
113-
114-
void FillInstructionData(const RC_Pointer address, const _DInst& instruction, const _DecodedInst& instructionInfo, const bool determineStaticInstructionBytes, InstructionData* data)
95+
void FillInstructionData(const _CodeInfo& info, const RC_Pointer address, const _DInst& instruction, const bool determineStaticInstructionBytes, InstructionData* data)
11596
{
11697
data->Address = reinterpret_cast<RC_Pointer>(instruction.addr);
117-
data->Length = instructionInfo.size;
118-
std::memcpy(data->Data, address, instructionInfo.size);
119-
120-
MultiByteToUnicode(
121-
reinterpret_cast<const char*>(instructionInfo.mnemonic.p),
122-
data->Instruction,
123-
instructionInfo.mnemonic.length
124-
);
125-
if (instructionInfo.operands.length != 0)
126-
{
127-
data->Instruction[instructionInfo.mnemonic.length] = ' ';
128-
129-
MultiByteToUnicode(
130-
reinterpret_cast<const char*>(instructionInfo.operands.p),
131-
0,
132-
data->Instruction,
133-
instructionInfo.mnemonic.length + 1,
134-
std::min<int>(64 - 1 - instructionInfo.mnemonic.length, instructionInfo.operands.length)
135-
);
136-
}
98+
data->Length = instruction.size;
99+
std::memcpy(data->Data, address, instruction.size);
100+
data->StaticInstructionBytes = -1;
137101

138-
if (determineStaticInstructionBytes)
102+
if (instruction.flags == FLAG_NOT_DECODABLE)
139103
{
140-
data->StaticInstructionBytes = GetStaticInstructionBytes(
141-
instruction,
142-
reinterpret_cast<const uint8_t*>(address)
143-
);
104+
std::memcpy(data->Instruction, L"???", sizeof(RC_UnicodeChar) * 3);
144105
}
145106
else
146107
{
147-
data->StaticInstructionBytes = -1;
108+
_DecodedInst instructionInfo = {};
109+
distorm_format(&info, &instruction, &instructionInfo);
110+
111+
MultiByteToUnicode(
112+
reinterpret_cast<const char*>(instructionInfo.mnemonic.p),
113+
data->Instruction,
114+
instructionInfo.mnemonic.length
115+
);
116+
if (instructionInfo.operands.length != 0)
117+
{
118+
data->Instruction[instructionInfo.mnemonic.length] = ' ';
119+
120+
MultiByteToUnicode(
121+
reinterpret_cast<const char*>(instructionInfo.operands.p),
122+
0,
123+
data->Instruction,
124+
instructionInfo.mnemonic.length + 1,
125+
std::min<int>(64 - 1 - instructionInfo.mnemonic.length, instructionInfo.operands.length)
126+
);
127+
}
128+
129+
if (determineStaticInstructionBytes)
130+
{
131+
data->StaticInstructionBytes = GetStaticInstructionBytes(
132+
instruction,
133+
reinterpret_cast<const uint8_t*>(address)
134+
);
135+
}
148136
}
149137
}
150138

151139
bool DisassembleInstructionsImpl(const RC_Pointer address, const RC_Size length, const RC_Pointer virtualAddress, const bool determineStaticInstructionBytes, EnumerateInstructionCallback callback)
152140
{
153-
auto info = CreateCodeInfo(address, length, virtualAddress);
141+
auto info = CreateCodeInfo(static_cast<const uint8_t*>(address), static_cast<int>(length), reinterpret_cast<_OffsetType>(virtualAddress));
154142

155143
const unsigned MaxInstructions = 50;
156144

@@ -169,26 +157,25 @@ bool DisassembleInstructionsImpl(const RC_Pointer address, const RC_Size length,
169157

170158
for (auto i = 0u; i < count; ++i)
171159
{
172-
_DecodedInst instructionInfo = {};
173-
distorm_format(&info, &decodedInstructions[i], &instructionInfo);
160+
const auto& instruction = decodedInstructions[i];
174161

175162
InstructionData data = {};
176-
FillInstructionData(instructionAddress, decodedInstructions[i], instructionInfo, determineStaticInstructionBytes, &data);
163+
FillInstructionData(info, instructionAddress, instruction, determineStaticInstructionBytes, &data);
177164

178165
if (callback(&data) == false)
179166
{
180167
return true;
181168
}
182169

183-
instructionAddress += decodedInstructions[i].size;
170+
instructionAddress += instruction.size;
184171
}
185172

186173
if (res == DECRES_SUCCESS || count == 0)
187174
{
188175
return true;
189176
}
190177

191-
const auto offset = static_cast<unsigned>(decodedInstructions[count - 1].addr - info.codeOffset);
178+
const auto offset = static_cast<unsigned>(decodedInstructions[count - 1].addr + decodedInstructions[count - 1].size - info.codeOffset);
192179

193180
info.codeOffset += offset;
194181
info.code += offset;

0 commit comments

Comments
 (0)