diff --git a/include/instructions/RabbitizerInstr.h b/include/instructions/RabbitizerInstr.h index e82f0ab..7236755 100644 --- a/include/instructions/RabbitizerInstr.h +++ b/include/instructions/RabbitizerInstr.h @@ -65,8 +65,14 @@ bool RabbitizerInstr_IsNop(const RabbitizerInstr *self); uint32_t RabbitizerInstr_GetBranchOffset(const RabbitizerInstr *self); + +size_t RabbitizerInstr_GetSizeForBufferInstrDisasm(const RabbitizerInstr *self, size_t immOverrideLength); size_t RabbitizerInstr_DisassembleInstruction(const RabbitizerInstr *self, char *dst, const char *immOverride, size_t immOverrideLength); + +size_t RabbitizerInstr_GetSizeForBufferDataDisasm(const RabbitizerInstr *self); size_t RabbitizerInstr_DisassembleAsData(const RabbitizerInstr *self, char *dst); + +size_t RabbitizerInstr_GetSizeForBuffer(const RabbitizerInstr *self, size_t immOverrideLength); size_t RabbitizerInstr_Disassemble(const RabbitizerInstr *self, char *dst, const char *immOverride, size_t immOverrideLength); #endif diff --git a/src/instructions/RabbitizerInstr_Disassemble.c b/src/instructions/RabbitizerInstr_Disassemble.c index 6afa24d..ae7ae15 100644 --- a/src/instructions/RabbitizerInstr_Disassemble.c +++ b/src/instructions/RabbitizerInstr_Disassemble.c @@ -228,6 +228,36 @@ const OperandCallback instrOpercandCallbacks[] = { }; +size_t RabbitizerInstr_GetSizeForBufferInstrDisasm(const RabbitizerInstr *self, size_t immOverrideLength) { + size_t totalSize = 0; + size_t opcodeNameLength; + + opcodeNameLength = strlen(RabbitizerInstr_GetOpcodeName(self)); + + totalSize += opcodeNameLength; + + if (self->descriptor->operands[0] == RABBITIZER_REGISTER_TYPE_INVALID) { + // There are no operands + return totalSize; + } + + totalSize += self->extraLjustWidthOpcode; + totalSize++; + + for (size_t i = 0; i < ARRAY_COUNT(self->descriptor->operands) && self->descriptor->operands[i] != RABBITIZER_REGISTER_TYPE_INVALID; i++) { + if (i != 0) { + totalSize += 2; + } + + // A bit arbitrary, but no operand should be longer than 25 characters + totalSize += 25; + totalSize += immOverrideLength; + } + + return totalSize; +} + + size_t RabbitizerInstr_DisassembleInstruction(const RabbitizerInstr *self, char *dst, const char *immOverride, size_t immOverrideLength) { size_t totalSize = 0; const char *opcodeName; @@ -288,6 +318,17 @@ size_t RabbitizerInstr_DisassembleInstruction(const RabbitizerInstr *self, char } +size_t RabbitizerInstr_GetSizeForBufferDataDisasm(const RabbitizerInstr *self) { + size_t totalSize = 0; + + totalSize += strlen(".word"); + totalSize += /*InstructionConfig.OPCODE_LJUST +*/ self->extraLjustWidthOpcode; + totalSize += 11; + + return totalSize; +} + + size_t RabbitizerInstr_DisassembleAsData(const RabbitizerInstr *self, char *dst) { size_t totalSize = 0; size_t tempSize; @@ -361,6 +402,25 @@ bool RabbitizerInstr_MustDisasmAsData(const RabbitizerInstr *self) { +size_t RabbitizerInstr_GetSizeForBuffer(const RabbitizerInstr *self, size_t immOverrideLength) { + if (!RabbitizerInstr_IsImplemented(self) || RabbitizerInstr_MustDisasmAsData(self)) { + size_t totalSize = 0; + + totalSize += RabbitizerInstr_GetSizeForBufferDataDisasm(self); + + /* if (InstructionConfig.UNKNOWN_INSTR_COMMENT) */ { + totalSize += 40; + totalSize += 3; + totalSize += RabbitizerInstr_GetSizeForBufferInstrDisasm(self, immOverrideLength); + } + + return totalSize; + } + + return RabbitizerInstr_GetSizeForBufferInstrDisasm(self,immOverrideLength); +} + + size_t RabbitizerInstr_Disassemble(const RabbitizerInstr *self, char *dst, const char *immOverride, size_t immOverrideLength) { if (!RabbitizerInstr_IsImplemented(self) || RabbitizerInstr_MustDisasmAsData(self)) { size_t totalSize = 0; diff --git a/test.c b/test.c index 43228e5..194cd63 100644 --- a/test.c +++ b/test.c @@ -3,12 +3,13 @@ #include "instructions/RabbitizerInstr.h" -#include "stdio.h" +#include +#include int main() { uint32_t word = 0x8D4A7E18; RabbitizerInstr instr; - char buffer[0x1000]; // huge buffer for testing purposes + char *buffer; RabbitizerInstr_Init(&instr, word); @@ -16,10 +17,14 @@ int main() { instr.extraLjustWidthOpcode += 10; + buffer = malloc(RabbitizerInstr_GetSizeForBuffer(&instr, 0) + 1); + RabbitizerInstr_Disassemble(&instr, buffer, NULL, 0); printf("%08X: %s\n", word, buffer); + free(buffer); + RabbitizerInstr_Destroy(&instr); return 0;