@@ -1829,6 +1829,121 @@ class MipsImportedFunctionRecognizer: public FunctionRecognizer
1829
1829
return false ;
1830
1830
}
1831
1831
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
+
1832
1947
public:
1833
1948
virtual bool RecognizeLowLevelIL (BinaryView* data, Function* func, LowLevelILFunction* il) override
1834
1949
{
@@ -1838,6 +1953,9 @@ class MipsImportedFunctionRecognizer: public FunctionRecognizer
1838
1953
if (RecognizeELFPLTEntries1 (data, func, il))
1839
1954
return true ;
1840
1955
1956
+ if (RecognizeELFPLTEntries2 (data, func, il))
1957
+ return true ;
1958
+
1841
1959
return false ;
1842
1960
}
1843
1961
};
0 commit comments