@@ -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+
18321947public:
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