Skip to content

Commit 13c41bc

Browse files
committed
Recognize uClibc MIPS ELF PLT entries
1 parent 4db391c commit 13c41bc

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

arch/mips/arch_mips.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,6 +1829,121 @@ class MipsImportedFunctionRecognizer: public FunctionRecognizer
18291829
return false;
18301830
}
18311831

1832+
1833+
bool RecognizeELFPLTEntries2(BinaryView* data, Function* func, LowLevelILFunction* il)
1834+
{
1835+
// Look for the following code pattern:
1836+
// $t7 = addr_past_got_end
1837+
// $t9 = [$t7 - backward_offset_into_got].d
1838+
// $t8 = $t7 + (-backward_offset_into_got)
1839+
// OPTIONAL: $t7 = addr_past_got_end
1840+
// tailcall($t9)
1841+
if (il->GetInstructionCount() < 4)
1842+
return false;
1843+
if (il->GetInstructionCount() > 5)
1844+
return false;
1845+
1846+
LowLevelILInstruction lui = il->GetInstruction(0);
1847+
if (lui.operation != LLIL_SET_REG)
1848+
return false;
1849+
LowLevelILInstruction luiOperand = lui.GetSourceExpr<LLIL_SET_REG>();
1850+
if (!LowLevelILFunction::IsConstantType(luiOperand.operation))
1851+
return false;
1852+
if (luiOperand.size != func->GetArchitecture()->GetAddressSize())
1853+
return false;
1854+
uint64_t addrPastGot = luiOperand.GetConstant();
1855+
uint32_t pltReg = lui.GetDestRegister<LLIL_SET_REG>();
1856+
1857+
LowLevelILInstruction ld = il->GetInstruction(1);
1858+
if (ld.operation != LLIL_SET_REG)
1859+
return false;
1860+
uint32_t targetReg = ld.GetDestRegister<LLIL_SET_REG>();
1861+
LowLevelILInstruction ldOperand = ld.GetSourceExpr<LLIL_SET_REG>();
1862+
if (ldOperand.operation != LLIL_LOAD)
1863+
return false;
1864+
if (ldOperand.size != func->GetArchitecture()->GetAddressSize())
1865+
return false;
1866+
LowLevelILInstruction ldAddrOperand = ldOperand.GetSourceExpr<LLIL_LOAD>();
1867+
uint64_t entry = addrPastGot;
1868+
int64_t ldAddrRightOperandValue = 0;
1869+
1870+
if ((ldAddrOperand.operation == LLIL_ADD) || (ldAddrOperand.operation == LLIL_SUB))
1871+
{
1872+
LowLevelILInstruction ldAddrLeftOperand = ldAddrOperand.GetRawOperandAsExpr(0);
1873+
LowLevelILInstruction ldAddrRightOperand = ldAddrOperand.GetRawOperandAsExpr(1);
1874+
if (ldAddrLeftOperand.operation != LLIL_REG)
1875+
return false;
1876+
if (ldAddrLeftOperand.GetSourceRegister<LLIL_REG>() != pltReg)
1877+
return false;
1878+
if (!LowLevelILFunction::IsConstantType(ldAddrRightOperand.operation))
1879+
return false;
1880+
ldAddrRightOperandValue = ldAddrRightOperand.GetConstant();
1881+
if (ldAddrOperand.operation == LLIL_SUB)
1882+
ldAddrRightOperandValue = -ldAddrRightOperandValue;
1883+
entry = addrPastGot + ldAddrRightOperandValue;
1884+
}
1885+
else if (ldAddrOperand.operation != LLIL_REG) //If theres no constant
1886+
return false;
1887+
1888+
Ref<Symbol> sym = data->GetSymbolByAddress(entry);
1889+
if (!sym)
1890+
return false;
1891+
if (sym->GetType() != ImportAddressSymbol)
1892+
return false;
1893+
1894+
LowLevelILInstruction add = il->GetInstruction(2);
1895+
if (add.operation != LLIL_SET_REG)
1896+
return false;
1897+
LowLevelILInstruction addOperand = add.GetSourceExpr<LLIL_SET_REG>();
1898+
1899+
if (addOperand.operation == LLIL_ADD)
1900+
{
1901+
LowLevelILInstruction addLeftOperand = addOperand.GetLeftExpr<LLIL_ADD>();
1902+
LowLevelILInstruction addRightOperand = addOperand.GetRightExpr<LLIL_ADD>();
1903+
if (addLeftOperand.operation != LLIL_REG)
1904+
return false;
1905+
if (addLeftOperand.GetSourceRegister<LLIL_REG>() != pltReg)
1906+
return false;
1907+
if (!LowLevelILFunction::IsConstantType(addRightOperand.operation))
1908+
return false;
1909+
if (addRightOperand.GetConstant() != ldAddrRightOperandValue)
1910+
return false;
1911+
}
1912+
else if ((addOperand.operation != LLIL_REG) || (addOperand.GetSourceRegister<LLIL_REG>() != pltReg)) //Simple assignment
1913+
return false;
1914+
1915+
LowLevelILInstruction jump = il->GetInstruction(3);
1916+
if (jump.operation == LLIL_SET_REG)
1917+
{
1918+
if (il->GetInstructionCount() != 5)
1919+
return false;
1920+
if (jump.GetDestRegister<LLIL_SET_REG>() != pltReg)
1921+
return false;
1922+
LowLevelILInstruction luiOperand = jump.GetSourceExpr<LLIL_SET_REG>();
1923+
if (!LowLevelILFunction::IsConstantType(luiOperand.operation))
1924+
return false;
1925+
if (luiOperand.size != func->GetArchitecture()->GetAddressSize())
1926+
return false;
1927+
if (((uint64_t) luiOperand.GetConstant()) != addrPastGot)
1928+
return false;
1929+
jump = il->GetInstruction(4);
1930+
}
1931+
1932+
if ((jump.operation != LLIL_JUMP) && (jump.operation != LLIL_TAILCALL))
1933+
return false;
1934+
LowLevelILInstruction jumpOperand = (jump.operation == LLIL_JUMP) ? jump.GetDestExpr<LLIL_JUMP>() : jump.GetDestExpr<LLIL_TAILCALL>();
1935+
if (jumpOperand.operation != LLIL_REG)
1936+
return false;
1937+
if (jumpOperand.GetSourceRegister<LLIL_REG>() != targetReg)
1938+
return false;
1939+
1940+
Ref<Symbol> funcSym = Symbol::ImportedFunctionFromImportAddressSymbol(sym, func->GetStart());
1941+
data->DefineAutoSymbol(funcSym);
1942+
func->ApplyImportedTypes(funcSym);
1943+
return true;
1944+
}
1945+
1946+
18321947
public:
18331948
virtual bool RecognizeLowLevelIL(BinaryView* data, Function* func, LowLevelILFunction* il) override
18341949
{
@@ -1838,6 +1953,9 @@ class MipsImportedFunctionRecognizer: public FunctionRecognizer
18381953
if (RecognizeELFPLTEntries1(data, func, il))
18391954
return true;
18401955

1956+
if (RecognizeELFPLTEntries2(data, func, il))
1957+
return true;
1958+
18411959
return false;
18421960
}
18431961
};

0 commit comments

Comments
 (0)