/** * @brief Return the address of the nth instruction after the instruction pointed by ip. @n * This function has been grabbed from OllyDbg ("Disassembleforward" in asmserv.c) * * @param[in] data Address of the data to disassemble * @param[in] base Original base address of the memory page (Required to disassemble destination addresses) * @param[in] size Size of the data block pointed by data * @param[in] ip RVA of the current instruction (Relative to data pointer) * @param[in] n Number of instruction next * * @return Return the RVA (Relative to the data pointer) of the nth instruction after the instruction pointed by ip */ ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n) { int i; uint cmdsize; unsigned char* pdata; // Reset Disasm Structure Capstone cp; if(data == NULL) return 0; if(ip >= size) ip = size - 1; if(n <= 0) return ip; pdata = data + ip; size -= ip; for(i = 0; i < n && size > 0; i++) { if(mCodeFoldingManager && mCodeFoldingManager->isFolded(ip + base)) { cmdsize = mCodeFoldingManager->getFoldEnd(ip + base) - (ip + base) + 1; } else { if(!cp.DisassembleSafe(ip + base, pdata, (int)size)) cmdsize = 1; else cmdsize = cp.Size(); cmdsize = mEncodeMap->getDataSize(base + ip, cmdsize); } pdata += cmdsize; ip += cmdsize; size -= cmdsize; } return ip; }
/** * @brief Return the address of the nth instruction before the instruction pointed by ip. @n * This function has been grabbed from OllyDbg ("Disassembleback" in asmserv.c) * * @param[in] data Address of the data to disassemble * @param[in] base Original base address of the memory page (Required to disassemble destination addresses) * @param[in] size Size of the data block pointed by data * @param[in] ip RVA of the current instruction (Relative to data pointer) * @param[in] n Number of instruction back * * @return Return the RVA (Relative to the data pointer) of the nth instruction before the instruction pointed by ip */ ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n) { int i; uint abuf[128], addr, back, cmdsize; unsigned char* pdata; // Reset Disasm Structure Capstone cp; // Check if the pointer is not null if(data == NULL) return 0; // Round the number of back instructions to 127 if(n < 0) n = 0; else if(n > 127) n = 127; // Check if the instruction pointer ip is not outside the memory range if(ip >= size) ip = size - 1; // Obvious answer if(n == 0) return ip; if(ip < (uint)n) return ip; //TODO: buffer overflow due to unchecked "back" value back = MAX_DISASM_BUFFER * (n + 3); // Instruction length limited to 16 if(ip < back) back = ip; addr = ip - back; if(mCodeFoldingManager && mCodeFoldingManager->isFolded(addr + base)) { duint newback = mCodeFoldingManager->getFoldBegin(addr + base); if(newback >= base && newback < size + base) addr = newback - base; } pdata = data + addr; for(i = 0; addr < ip; i++) { abuf[i % 128] = addr; if(mCodeFoldingManager && mCodeFoldingManager->isFolded(addr + base)) { duint newaddr = mCodeFoldingManager->getFoldBegin(addr + base); if(newaddr >= base) { addr = newaddr - base; } cmdsize = mCodeFoldingManager->getFoldEnd(addr + base) - (addr + base) + 1; } else { if(!cp.DisassembleSafe(addr + base, pdata, (int)size)) cmdsize = 2; //heuristic for better output (FF FE or FE FF are usually part of an instruction) else cmdsize = cp.Size(); cmdsize = mEncodeMap->getDataSize(base + addr, cmdsize); } pdata += cmdsize; addr += cmdsize; back -= cmdsize; size -= cmdsize; } if(i < n) return abuf[0]; else return abuf[(i - n + 128) % 128]; }