x86: handle instructions with LOCK/REP/REPNE prefix after other prefixes. bear with this until we have a better approach
diff --git a/cs.c b/cs.c
index c9bc135..4cd9e5f 100644
--- a/cs.c
+++ b/cs.c
@@ -419,6 +419,7 @@
void *tmp;
size_t skipdata_bytes;
uint64_t offset_org;
+ uint8_t *tmpbuf = NULL, *org_tmpbuf = NULL;
if (!handle) {
// FIXME: how to handle this case:
@@ -433,12 +434,14 @@
memset(insn_cache, 0, sizeof(insn_cache));
+ // save the original offset for SKIPDATA
offset_org = offset;
+
while (size > 0) {
MCInst_Init(&mci);
mci.csh = handle;
- r = handle->disasm(ud, buffer, size, &mci, &insn_size, offset, handle->getinsn_info);
+ r = handle->disasm(ud, buffer, &tmpbuf, size, &mci, &insn_size, offset, handle->getinsn_info);
if (r) {
SStream ss;
SStream_Init(&ss);
@@ -486,6 +489,14 @@
}
buffer += insn_size;
+ if (tmpbuf != NULL) {
+ // save the original tmpbuf to free it later
+ if (org_tmpbuf == NULL)
+ org_tmpbuf = tmpbuf;
+
+ tmpbuf += insn_size;
+ }
+
size -= insn_size;
offset += insn_size;
@@ -564,6 +575,10 @@
}
}
+ // free tmpbuf if it was allocated in @disasm
+ if (org_tmpbuf)
+ cs_mem_free(org_tmpbuf);
+
if (f) {
// resize total to contain newly disasm insns
void *tmp = cs_mem_realloc(total, total_size + f * sizeof(insn_cache[0]));