@@ -7,18 +7,18 @@ extern "C"
77#include < ../src/instructions.h>
88}
99
10- bool AreOperandsStatic (_DInst * instruction, const int prefixLength)
10+ bool AreOperandsStatic (const _DInst & instruction, const int prefixLength)
1111{
12- const auto fc = META_GET_FC (instruction-> meta );
12+ const auto fc = META_GET_FC (instruction. meta );
1313 if (fc == FC_UNC_BRANCH || fc == FC_CND_BRANCH)
1414 {
15- if (instruction-> size - prefixLength < 5 )
15+ if (instruction. size - prefixLength < 5 )
1616 {
1717 return true ;
1818 }
1919 }
2020
21- const auto ops = instruction-> ops ;
21+ const auto ops = instruction. ops ;
2222 for (auto i = 0 ; i < OPERANDS_NO; i++)
2323 {
2424 switch (ops[i].type )
@@ -37,7 +37,7 @@ bool AreOperandsStatic(_DInst *instruction, const int prefixLength)
3737 case O_DISP:
3838 case O_SMEM:
3939 case O_MEM:
40- if (instruction-> dispSize < 32 )
40+ if (instruction. dispSize < 32 )
4141 {
4242 continue ;
4343 }
@@ -58,12 +58,12 @@ bool AreOperandsStatic(_DInst *instruction, const int prefixLength)
5858 return true ;
5959}
6060
61- int GetStaticInstructionBytes (_DInst * instruction, const uint8_t *data)
61+ int GetStaticInstructionBytes (const _DInst & instruction, const uint8_t *data)
6262{
6363 _CodeInfo info = {};
6464 info.codeOffset = reinterpret_cast <_OffsetType>(data);
6565 info.code = data;
66- info.codeLen = instruction-> size ;
66+ info.codeLen = instruction. size ;
6767 info.features = DF_NONE;
6868#ifdef RECLASSNET32
6969 info.dt = Decode32Bits;
@@ -88,13 +88,13 @@ int GetStaticInstructionBytes(_DInst *instruction, const uint8_t *data)
8888
8989 if (AreOperandsStatic (instruction, prefixLength))
9090 {
91- return instruction-> size ;
91+ return instruction. size ;
9292 }
9393
94- return instruction-> size - info.codeLen ;
94+ return instruction. size - info.codeLen ;
9595}
9696
97- bool DisassembleCodeImpl (const RC_Pointer address, const RC_Size length, const RC_Pointer virtualAddress, const bool determineStaticInstructionBytes, InstructionData* instruction )
97+ _CodeInfo CreateCodeInfo (const RC_Pointer address, const RC_Size length, const RC_Pointer virtualAddress)
9898{
9999 _CodeInfo info = {};
100100 info.codeOffset = reinterpret_cast <_OffsetType>(virtualAddress);
@@ -108,50 +108,85 @@ bool DisassembleCodeImpl(const RC_Pointer address, const RC_Size length, const R
108108 info.dt = Decode64Bits;
109109#endif
110110
111- _DInst decodedInstructions[1 ] = {};
112- unsigned int instructionCount = 0 ;
113-
114- const auto res = distorm_decompose (&info, decodedInstructions, 1 , &instructionCount);
115- if (res == DECRES_INPUTERR || !(res == DECRES_SUCCESS || res == DECRES_MEMORYERR) || instructionCount != 1 )
116- {
117- return false ;
118- }
119-
120- _DecodedInst instructionInfo = {};
121- distorm_format (&info, &decodedInstructions[0 ], &instructionInfo);
111+ return info;
112+ }
122113
123- instruction->Length = instructionInfo.size ;
124- std::memcpy (instruction->Data , address, instructionInfo.size );
114+ void FillInstructionData (const RC_Pointer address, const _DInst& instruction, const _DecodedInst& instructionInfo, const bool determineStaticInstructionBytes, InstructionData* data)
115+ {
116+ data->Length = instructionInfo.size ;
117+ std::memcpy (data->Data , address, instructionInfo.size );
125118
126119 MultiByteToUnicode (
127120 reinterpret_cast <const char *>(instructionInfo.mnemonic .p ),
128- instruction ->Instruction ,
121+ data ->Instruction ,
129122 instructionInfo.mnemonic .length
130123 );
131124 if (instructionInfo.operands .length != 0 )
132125 {
133- instruction ->Instruction [instructionInfo.mnemonic .length ] = ' ' ;
126+ data ->Instruction [instructionInfo.mnemonic .length ] = ' ' ;
134127
135128 MultiByteToUnicode (
136129 reinterpret_cast <const char *>(instructionInfo.operands .p ),
137130 0 ,
138- instruction ->Instruction ,
131+ data ->Instruction ,
139132 instructionInfo.mnemonic .length + 1 ,
140133 std::min<int >(64 - 1 - instructionInfo.mnemonic .length , instructionInfo.operands .length )
141134 );
142135 }
143136
144137 if (determineStaticInstructionBytes)
145138 {
146- instruction ->StaticInstructionBytes = GetStaticInstructionBytes (
147- &decodedInstructions[ 0 ] ,
139+ data ->StaticInstructionBytes = GetStaticInstructionBytes (
140+ instruction ,
148141 reinterpret_cast <const uint8_t *>(address)
149142 );
150143 }
151144 else
152145 {
153- instruction ->StaticInstructionBytes = -1 ;
146+ data ->StaticInstructionBytes = -1 ;
154147 }
148+ }
155149
156- return true ;
150+ bool DisassembleInstructionsImpl (const RC_Pointer address, const RC_Size length, const RC_Pointer virtualAddress, const bool determineStaticInstructionBytes, EnumerateInstructionCallback callback)
151+ {
152+ auto info = CreateCodeInfo (address, length, virtualAddress);
153+
154+ const unsigned MaxInstructions = 50 ;
155+
156+ _DInst decodedInstructions[MaxInstructions] = {};
157+ unsigned count = 0 ;
158+
159+ while (true )
160+ {
161+ const auto res = distorm_decompose (&info, decodedInstructions, MaxInstructions, &count);
162+ if (res == DECRES_INPUTERR)
163+ {
164+ return false ;
165+ }
166+
167+ for (auto i = 0u ; i < count; ++i)
168+ {
169+ _DecodedInst instructionInfo = {};
170+ distorm_format (&info, &decodedInstructions[i], &instructionInfo);
171+
172+ InstructionData data;
173+ FillInstructionData (address, decodedInstructions[i], instructionInfo, determineStaticInstructionBytes, &data);
174+
175+ if (callback (&data) == false )
176+ {
177+ return true ;
178+ }
179+ }
180+
181+ if (res == DECRES_SUCCESS || count == 0 )
182+ {
183+ return true ;
184+ }
185+
186+ const auto offset = decodedInstructions[count - 1 ].addr - info.codeOffset ;
187+
188+ info.codeOffset += offset;
189+ info.code += offset;
190+ info.codeLen -= offset;
191+ }
157192}
0 commit comments