Skip to content

Commit 06611c1

Browse files
committed
Fix Thumb-2 out-of-bounds read during lifting
Fix for sentry crash BINARYNINJA-89
1 parent 2e89fe2 commit 06611c1

2 files changed

Lines changed: 33 additions & 12 deletions

File tree

arch/armv7/thumb2_disasm/arch_thumb2.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,11 @@ class Thumb2Architecture: public ArmCommonArchitecture
9898
return "thumbv7-none-none";
9999
}
100100

101-
void populateDecomposeRequest(decomp_request *req, const uint8_t *data, size_t len,
101+
bool populateDecomposeRequest(decomp_request *req, const uint8_t *data, size_t len,
102102
uint64_t addr, int inIfThen, int inIfThenLast)
103103
{
104+
if (!data || len < 2)
105+
return false;
104106
req->instr_word16 = 0;
105107
req->instr_word32 = 0;
106108
if(m_endian == LittleEndian) {
@@ -122,14 +124,17 @@ class Thumb2Architecture: public ArmCommonArchitecture
122124
req->inIfThenLast = inIfThenLast;
123125
req->carry_in = 0;
124126
req->addr = (uint32_t)addr;
127+
return true;
125128
}
126129

127130
virtual bool Disassemble(const uint8_t* data, uint64_t addr, size_t maxLen, decomp_result& result)
128131
{
129132
(void)addr;
130133
(void)maxLen;
131134
decomp_request request;
132-
populateDecomposeRequest(&request, data, maxLen, addr, IFTHEN_UNKNOWN, IFTHENLAST_UNKNOWN);
135+
136+
if (!populateDecomposeRequest(&request, data, maxLen, addr, IFTHEN_UNKNOWN, IFTHENLAST_UNKNOWN))
137+
return false;
133138

134139
memset(&result, 0, sizeof(result));
135140
if (thumb_decompose(&request, &result) != STATUS_OK)
@@ -176,7 +181,8 @@ class Thumb2Architecture: public ArmCommonArchitecture
176181
decomp_request request;
177182
decomp_result decomp;
178183

179-
populateDecomposeRequest(&request, data, maxLen, addr, IFTHEN_UNKNOWN, IFTHENLAST_UNKNOWN);
184+
if (!populateDecomposeRequest(&request, data, maxLen, addr, IFTHEN_UNKNOWN, IFTHENLAST_UNKNOWN))
185+
return false;
180186

181187
if (thumb_decompose(&request, &decomp) != STATUS_OK)
182188
return false;
@@ -460,7 +466,8 @@ class Thumb2Architecture: public ArmCommonArchitecture
460466
decomp_request request;
461467
decomp_result decomp;
462468

463-
populateDecomposeRequest(&request, data, len, addr, IFTHEN_UNKNOWN, IFTHENLAST_UNKNOWN);
469+
if (!populateDecomposeRequest(&request, data, len, addr, IFTHEN_UNKNOWN, IFTHENLAST_UNKNOWN))
470+
return false;
464471

465472
if (thumb_decompose(&request, &decomp) != STATUS_OK)
466473
return false;
@@ -1759,7 +1766,8 @@ class Thumb2Architecture: public ArmCommonArchitecture
17591766
decomp_request request;
17601767
decomp_result decomp;
17611768

1762-
populateDecomposeRequest(&request, data, len, addr, IFTHEN_NO, IFTHENLAST_NO);
1769+
if (!populateDecomposeRequest(&request, data, len, addr, IFTHEN_NO, IFTHENLAST_NO))
1770+
return false;
17631771

17641772
if (thumb_decompose(&request, &decomp) != STATUS_OK)
17651773
return false;
@@ -1792,14 +1800,19 @@ class Thumb2Architecture: public ArmCommonArchitecture
17921800

17931801
for (size_t i = 0; i < instrCount; i++)
17941802
{
1803+
if (offset >= len || (len - offset) < 2)
1804+
return false;
1805+
17951806
bool isTrue = (i == 0) || (((mask >> (4 - i)) & 1) == (cond & 1));
1807+
size_t remainingLen = len - offset;
17961808

1797-
populateDecomposeRequest(&request, data+offset, len-offset, addr+offset,
1798-
IFTHEN_YES, ((i + 1) >= instrCount) ? IFTHENLAST_YES : IFTHENLAST_NO);
1809+
if (!populateDecomposeRequest(&request, data+offset, remainingLen, addr+offset,
1810+
IFTHEN_YES, ((i + 1) >= instrCount) ? IFTHENLAST_YES : IFTHENLAST_NO))
1811+
return false;
17991812

18001813
if (thumb_decompose(&request, &decomp) != STATUS_OK)
18011814
return false;
1802-
if ((offset + (decomp.instrSize / 8)) > len)
1815+
if ((decomp.instrSize / 8) > remainingLen)
18031816
return false;
18041817
if ((decomp.status & STATUS_UNDEFINED) || (!decomp.format))
18051818
return false;

defaultarch.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -796,16 +796,24 @@ bool Architecture::DefaultLiftFunction(LowLevelILFunction* function, FunctionLif
796796
if (buffer.GetLength() == 0)
797797
buffer = data->ReadBuffer(i->GetStart(), i->GetEnd() - i->GetStart());
798798

799-
if (addr < i->GetStart() || addr >= (i->GetStart() + buffer.GetLength()))
799+
uint64_t blockStart = i->GetStart();
800+
size_t bufferLen = buffer.GetLength();
801+
if (addr < blockStart || (addr - blockStart) >= bufferLen)
800802
{
801-
// Instruction data not found, emit undefined IL instruction
802803
function->AddInstruction(function->AddExpr(LLIL_UNDEF, 0, 0));
803804
logger->LogDebug("Instruction data not found, inserted LLIL_UNDEF at %#" PRIx64, addr);
804805
break;
805806
}
806807

807-
len = (i->GetStart() + buffer.GetLength()) - addr;
808-
opcode = (const uint8_t*)buffer.GetDataAt(addr - i->GetStart());
808+
size_t bufferOffset = static_cast<size_t>(addr - blockStart);
809+
len = bufferLen - bufferOffset;
810+
opcode = (const uint8_t*)buffer.GetDataAt(bufferOffset);
811+
if (!opcode)
812+
{
813+
function->AddInstruction(function->AddExpr(LLIL_UNDEF, 0, 0));
814+
logger->LogDebug("Instruction data not found, inserted LLIL_UNDEF at %#" PRIx64, addr);
815+
break;
816+
}
809817
}
810818

811819
size_t instrCountBefore = function->GetInstructionCount();

0 commit comments

Comments
 (0)