Skip to content

Commit

Permalink
SCI: Added handling of invalid jump offsets (e.g. QFG2, script 260)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluegr committed Nov 28, 2011
1 parent 29fb48b commit 381e92a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
3 changes: 2 additions & 1 deletion engines/sci/console.cpp
Expand Up @@ -2978,7 +2978,8 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
// there is a jump after a ret, we don't stop processing
if (opcode == op_bt || opcode == op_bnt || opcode == op_jmp) {
uint16 curJmpOffset = offset + (uint16)opparams[0];
if (curJmpOffset > maxJmpOffset)
// QFG2 has invalid jumps outside the script buffer in script 260
if (curJmpOffset > maxJmpOffset && curJmpOffset < script->getScriptSize())
maxJmpOffset = curJmpOffset;
}

Expand Down
10 changes: 8 additions & 2 deletions engines/sci/engine/scriptdebug.cpp
Expand Up @@ -296,7 +296,7 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) {
Script *script_entity = (Script *)mobj;

const byte *scr = script_entity->getBuf();
int scr_size = script_entity->getBufSize();
int scr_size = script_entity->getScriptSize();

if (pos.offset >= scr_size)
return false;
Expand All @@ -310,7 +310,13 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) {
case op_bt:
case op_bnt:
case op_jmp:
jumpTarget = pos + bytecount + opparams[0];
{
reg_t jmpTarget = pos + bytecount + opparams[0];
// QFG2 has invalid jumps outside the script buffer in script 260
if (jmpTarget.offset >= scr_size)
return false;
jumpTarget = jmpTarget;
}
return true;
default:
return false;
Expand Down
12 changes: 12 additions & 0 deletions engines/sci/engine/vm.cpp
Expand Up @@ -764,16 +764,28 @@ void run_vm(EngineState *s) {
// Branch relative if true
if (s->r_acc.offset || s->r_acc.segment)
s->xs->addr.pc.offset += opparams[0];

if (s->xs->addr.pc.offset >= local_script->getScriptSize())
error("[VM] op_bt: request to jump past the end of script %d (offset %d, script is %d bytes)",
local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize());
break;

case op_bnt: // 0x18 (24)
// Branch relative if not true
if (!(s->r_acc.offset || s->r_acc.segment))
s->xs->addr.pc.offset += opparams[0];

if (s->xs->addr.pc.offset >= local_script->getScriptSize())
error("[VM] op_bnt: request to jump past the end of script %d (offset %d, script is %d bytes)",
local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize());
break;

case op_jmp: // 0x19 (25)
s->xs->addr.pc.offset += opparams[0];

if (s->xs->addr.pc.offset >= local_script->getScriptSize())
error("[VM] op_jmp: request to jump past the end of script %d (offset %d, script is %d bytes)",
local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize());
break;

case op_ldi: // 0x1a (26)
Expand Down

0 comments on commit 381e92a

Please sign in to comment.