summaryrefslogtreecommitdiff
path: root/platform/efi/efi_resolver/src/PeiResolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/efi/efi_resolver/src/PeiResolver.cpp')
-rw-r--r--platform/efi/efi_resolver/src/PeiResolver.cpp444
1 files changed, 235 insertions, 209 deletions
diff --git a/platform/efi/efi_resolver/src/PeiResolver.cpp b/platform/efi/efi_resolver/src/PeiResolver.cpp
index 2699f2bb..c3f5d50a 100644
--- a/platform/efi/efi_resolver/src/PeiResolver.cpp
+++ b/platform/efi/efi_resolver/src/PeiResolver.cpp
@@ -2,277 +2,303 @@
bool PeiResolver::resolvePeiIdt()
{
- string archName = m_view->GetDefaultArchitecture()->GetName();
- string intrinsicName;
- if (archName == "x86")
- intrinsicName = "IDTR32";
- else
- intrinsicName = "IDTR64";
+ string archName = m_view->GetDefaultArchitecture()->GetName();
+ string intrinsicName;
+ if (archName == "x86")
+ intrinsicName = "IDTR32";
+ else
+ intrinsicName = "IDTR64";
- auto refs = m_view->GetCodeReferencesForType(QualifiedName(intrinsicName));
- for (auto ref : refs) {
- if (m_task->IsCancelled())
- return false;
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName(intrinsicName));
+ for (auto ref : refs)
+ {
+ if (m_task->IsCancelled())
+ return false;
- auto mlil = ref.func->GetMediumLevelIL();
- auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
- auto instr = mlil->GetInstruction(instrIdx);
+ auto mlil = ref.func->GetMediumLevelIL();
+ auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
+ auto instr = mlil->GetInstruction(instrIdx);
- auto hlil = ref.func->GetHighLevelIL();
- auto hlils = HighLevelILExprsAt(ref.func, m_view->GetDefaultArchitecture(), ref.addr);
+ auto hlil = ref.func->GetHighLevelIL();
+ auto hlils = HighLevelILExprsAt(ref.func, m_view->GetDefaultArchitecture(), ref.addr);
- for (auto expr : hlils) {
- if (expr.operation != HLIL_INTRINSIC ||
- expr.GetParent().operation != HLIL_ASSIGN ||
- expr.GetParent().GetDestExpr<HLIL_ASSIGN>().operation != HLIL_STRUCT_FIELD ||
- expr.GetParent().GetDestExpr<HLIL_ASSIGN>().GetSourceExpr<HLIL_STRUCT_FIELD>().operation != HLIL_VAR)
- continue;
+ for (auto expr : hlils)
+ {
+ if (expr.operation != HLIL_INTRINSIC || expr.GetParent().operation != HLIL_ASSIGN
+ || expr.GetParent().GetDestExpr<HLIL_ASSIGN>().operation != HLIL_STRUCT_FIELD
+ || expr.GetParent().GetDestExpr<HLIL_ASSIGN>().GetSourceExpr<HLIL_STRUCT_FIELD>().operation != HLIL_VAR)
+ continue;
- auto var = expr.GetParent().GetDestExpr<HLIL_ASSIGN>().GetSourceExpr<HLIL_STRUCT_FIELD>().GetVariable();
- ref.func->CreateUserVariable(var, m_view->GetTypeByName(QualifiedName(intrinsicName)), intrinsicName);
- }
+ auto var = expr.GetParent().GetDestExpr<HLIL_ASSIGN>().GetSourceExpr<HLIL_STRUCT_FIELD>().GetVariable();
+ ref.func->CreateUserVariable(var, m_view->GetTypeByName(QualifiedName(intrinsicName)), intrinsicName);
+ }
- if (instr.operation == MLIL_INTRINSIC) {
- // binja doesn't do type propagation on intrinsic instructions
- auto output_params = instr.GetOutputVariables<MLIL_INTRINSIC>();
- if (output_params.size() < 1)
- continue;
- ref.func->CreateUserVariable(output_params[0],
- m_view->GetTypeByName(QualifiedName(intrinsicName)),
- intrinsicName);
- }
- m_view->UpdateAnalysisAndWait();
- }
+ if (instr.operation == MLIL_INTRINSIC)
+ {
+ // binja doesn't do type propagation on intrinsic instructions
+ auto output_params = instr.GetOutputVariables<MLIL_INTRINSIC>();
+ if (output_params.size() < 1)
+ continue;
+ ref.func->CreateUserVariable(
+ output_params[0], m_view->GetTypeByName(QualifiedName(intrinsicName)), intrinsicName);
+ }
+ m_view->UpdateAnalysisAndWait();
+ }
- // TODO There is an issue related to structure's type propagation, binja doesn't propagate indirect structure access properly
- // here is a temporary fix, should be removed after vector35/binaryninja/#749 got fixed
- refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_PEI_SERVICES"));
- for (auto ref : refs) {
- if (m_task->IsCancelled())
- return false;
+ // TODO There is an issue related to structure's type propagation, binja doesn't propagate indirect structure access
+ // properly
+ // here is a temporary fix, should be removed after vector35/binaryninja/#749 got fixed
+ refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_PEI_SERVICES"));
+ for (auto ref : refs)
+ {
+ if (m_task->IsCancelled())
+ return false;
- auto mlil = ref.func->GetMediumLevelIL();
- auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
- auto instr = mlil->GetInstruction(instrIdx);
+ auto mlil = ref.func->GetMediumLevelIL();
+ auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
+ auto instr = mlil->GetInstruction(instrIdx);
- if (instr.operation != MLIL_SET_VAR)
- continue;
+ if (instr.operation != MLIL_SET_VAR)
+ continue;
- if (instr.GetSourceExpr<MLIL_SET_VAR>().operation != MLIL_LOAD_STRUCT)
- continue;
+ if (instr.GetSourceExpr<MLIL_SET_VAR>().operation != MLIL_LOAD_STRUCT)
+ continue;
- ref.func->CreateUserVariable(instr.GetDestVariable<MLIL_SET_VAR>(),
- mlil->GetExprType(instr.GetSourceExpr<MLIL_SET_VAR>()).GetValue(),
- nonConflictingLocalName(ref.func, "EfiPeiServices"));
- m_view->UpdateAnalysisAndWait();
- }
+ ref.func->CreateUserVariable(instr.GetDestVariable<MLIL_SET_VAR>(),
+ mlil->GetExprType(instr.GetSourceExpr<MLIL_SET_VAR>()).GetValue(),
+ nonConflictingLocalName(ref.func, "EfiPeiServices"));
+ m_view->UpdateAnalysisAndWait();
+ }
- return true;
+ return true;
}
bool PeiResolver::resolvePeiMrc()
{
- auto funcs = m_view->GetAnalysisFunctionList();
- for (auto func : funcs) {
- if (m_task->IsCancelled())
- return false;
+ auto funcs = m_view->GetAnalysisFunctionList();
+ for (auto func : funcs)
+ {
+ if (m_task->IsCancelled())
+ return false;
- auto mlil = func->GetMediumLevelIL();
- auto blocks = mlil->GetBasicBlocks();
- for (auto block : blocks) {
- for (size_t i = block->GetStart(); i < block->GetEnd(); i++) {
- auto instr = mlil->GetInstruction(i);
- if (instr.operation != MLIL_INTRINSIC)
- continue;
- uint32_t intrinsicIdx = instr.GetIntrinsic<MLIL_INTRINSIC>();
+ auto mlil = func->GetMediumLevelIL();
+ auto blocks = mlil->GetBasicBlocks();
+ for (auto block : blocks)
+ {
+ for (size_t i = block->GetStart(); i < block->GetEnd(); i++)
+ {
+ auto instr = mlil->GetInstruction(i);
+ if (instr.operation != MLIL_INTRINSIC)
+ continue;
+ uint32_t intrinsicIdx = instr.GetIntrinsic<MLIL_INTRINSIC>();
- if (m_view->GetDefaultArchitecture()->GetIntrinsicName(intrinsicIdx) != "Coproc_GetOneWord")
- continue;
- auto intrinsicParams = instr.GetParameterExprs<MLIL_INTRINSIC>();
- if (intrinsicParams.size() != 5)
- continue;
+ if (m_view->GetDefaultArchitecture()->GetIntrinsicName(intrinsicIdx) != "Coproc_GetOneWord")
+ continue;
+ auto intrinsicParams = instr.GetParameterExprs<MLIL_INTRINSIC>();
+ if (intrinsicParams.size() != 5)
+ continue;
- bool found = true;
+ bool found = true;
- const int value[5] = { 0xf, 0x0, 0xd, 0x0, 0x2 };
- for (int j = 0; j < 5; j++) {
- auto param = intrinsicParams[j];
- if (param.operation != MLIL_CONST) {
- found = false;
- break;
- }
+ const int value[5] = {0xf, 0x0, 0xd, 0x0, 0x2};
+ for (int j = 0; j < 5; j++)
+ {
+ auto param = intrinsicParams[j];
+ if (param.operation != MLIL_CONST)
+ {
+ found = false;
+ break;
+ }
- if (param.GetConstant<MLIL_CONST>() != value[j]) {
- found = false;
- break;
- }
- }
+ if (param.GetConstant<MLIL_CONST>() != value[j])
+ {
+ found = false;
+ break;
+ }
+ }
- if (!found)
- continue;
+ if (!found)
+ continue;
- // At this point, we can make sure this instruction fetches EFI_PEI_SERVICES
- auto output = instr.GetOutputVariables();
- if (output.size() > 0) {
- auto pointerType = Type::PointerType(m_view->GetDefaultArchitecture(),
- Type::PointerType(m_view->GetDefaultArchitecture(),
- m_view->GetTypeByName(QualifiedName("EFI_PEI_SERVICES"))));
- func->CreateUserVariable(output[0], pointerType, nonConflictingLocalName(func, "PeiServices"));
- m_view->UpdateAnalysisAndWait();
- }
- }
- }
- }
- return true;
+ // At this point, we can make sure this instruction fetches EFI_PEI_SERVICES
+ auto output = instr.GetOutputVariables();
+ if (output.size() > 0)
+ {
+ auto pointerType = Type::PointerType(m_view->GetDefaultArchitecture(),
+ Type::PointerType(m_view->GetDefaultArchitecture(),
+ m_view->GetTypeByName(QualifiedName("EFI_PEI_SERVICES"))));
+ func->CreateUserVariable(output[0], pointerType, nonConflictingLocalName(func, "PeiServices"));
+ m_view->UpdateAnalysisAndWait();
+ }
+ }
+ }
+ }
+ return true;
}
bool PeiResolver::resolvePeiMrs()
{
- // ideally we don't need this function, but since we don't support type propagation on intrinsic instructions
- // we have to manually propagate it
- auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_PEI_SERVICES"));
- for (auto ref : refs) {
- if (m_task->IsCancelled())
- return false;
+ // ideally we don't need this function, but since we don't support type propagation on intrinsic instructions
+ // we have to manually propagate it
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_PEI_SERVICES"));
+ for (auto ref : refs)
+ {
+ if (m_task->IsCancelled())
+ return false;
- auto mlil = ref.func->GetMediumLevelIL();
- auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
- auto instr = mlil->GetInstruction(instrIdx);
- if (instr.operation == MLIL_INTRINSIC) {
- auto params = instr.GetOutputVariables();
- if (params.size() < 1)
- continue;
+ auto mlil = ref.func->GetMediumLevelIL();
+ auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
+ auto instr = mlil->GetInstruction(instrIdx);
+ if (instr.operation == MLIL_INTRINSIC)
+ {
+ auto params = instr.GetOutputVariables();
+ if (params.size() < 1)
+ continue;
- auto pointerType = Type::PointerType(m_view->GetDefaultArchitecture(),
- Type::PointerType(m_view->GetDefaultArchitecture(),
- m_view->GetTypeByName(QualifiedName("EFI_PEI_SERVICES"))));
- ref.func->CreateUserVariable(params[0],
- pointerType,
- nonConflictingLocalName(ref.func, "EfiPeiServices"));
- m_view->UpdateAnalysisAndWait();
- }
- }
- return true;
+ auto pointerType = Type::PointerType(m_view->GetDefaultArchitecture(),
+ Type::PointerType(
+ m_view->GetDefaultArchitecture(), m_view->GetTypeByName(QualifiedName("EFI_PEI_SERVICES"))));
+ ref.func->CreateUserVariable(params[0], pointerType, nonConflictingLocalName(ref.func, "EfiPeiServices"));
+ m_view->UpdateAnalysisAndWait();
+ }
+ }
+ return true;
}
bool PeiResolver::resolvePlatformPointers()
{
- string archName = m_view->GetDefaultArchitecture()->GetName();
- string intrinsicTypeName;
+ m_task->SetProgressText("Resolving PEI Services Pointers...");
+ string archName = m_view->GetDefaultArchitecture()->GetName();
+ string intrinsicTypeName;
- if (archName == "x86" || archName == "x86-64") {
- return resolvePeiIdt();
- } else if (archName == "arm" || archName == "thumb2") {
- return resolvePeiMrc();
- } else if (archName == "aarch64") {
- return resolvePeiMrs();
- }
- LogError("Not supported arch: %s", archName.c_str());
- return false;
+ if (archName == "x86" || archName == "x86-64")
+ {
+ return resolvePeiIdt();
+ }
+ else if (archName == "arm" || archName == "thumb2")
+ {
+ return resolvePeiMrc();
+ }
+ else if (archName == "aarch64")
+ {
+ return resolvePeiMrs();
+ }
+ LogError("Not supported arch: %s", archName.c_str());
+ return false;
}
bool PeiResolver::resolvePeiDescriptors()
{
- const string descriptorNames[2] = { "EFI_PEI_NOTIFY_DESCRIPTOR", "EFI_PEI_PPI_DESCRIPTOR" };
- for (auto descriptor : descriptorNames) {
- auto refs = m_view->GetCodeReferencesForType(QualifiedName(descriptor));
- for (auto ref : refs) {
- if (m_task->IsCancelled())
- return false;
+ m_task->SetProgressText("Defining PEI Descriptors...");
+ const string descriptorNames[2] = {"EFI_PEI_NOTIFY_DESCRIPTOR", "EFI_PEI_PPI_DESCRIPTOR"};
+ for (auto descriptor : descriptorNames)
+ {
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName(descriptor));
+ for (auto ref : refs)
+ {
+ if (m_task->IsCancelled())
+ return false;
- auto mlil = ref.func->GetMediumLevelIL();
- auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
- auto instr = mlil->GetInstruction(instrIdx);
+ auto mlil = ref.func->GetMediumLevelIL();
+ auto instrIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
+ auto instr = mlil->GetInstruction(instrIdx);
- if (instr.operation != MLIL_CALL && instr.operation != MLIL_TAILCALL)
- continue;
+ if (instr.operation != MLIL_CALL && instr.operation != MLIL_TAILCALL)
+ continue;
- auto destExpr = instr.GetDestExpr();
- if (destExpr.operation != MLIL_LOAD_STRUCT)
- continue;
+ auto destExpr = instr.GetDestExpr();
+ if (destExpr.operation != MLIL_LOAD_STRUCT)
+ continue;
- // at this point this instruction is probably a call to LocatPpi, InstallPpi or NotifyPpi
- if (!mlil->GetExprType(destExpr).GetValue()->IsPointer())
- continue;
+ // at this point this instruction is probably a call to LocatPpi, InstallPpi or NotifyPpi
+ if (!mlil->GetExprType(destExpr).GetValue()->IsPointer())
+ continue;
- auto funcType = mlil->GetExprType(destExpr).GetValue()->GetChildType().GetValue();
- auto params = funcType->GetParameters();
- int targetParamIdx = -1;
- for (int i = 0; i < params.size(); i++) {
- auto param = params[i];
- if (!param.type.GetValue()->IsPointer())
- continue;
- auto paramTypeName = param.type.GetValue()->GetChildType().GetValue()->GetTypeName().GetString();
- if (paramTypeName.find(descriptor) != paramTypeName.npos) {
- // this is the param
- targetParamIdx = i;
- break;
- }
- }
- if (targetParamIdx < 0)
- continue;
+ auto funcType = mlil->GetExprType(destExpr).GetValue()->GetChildType().GetValue();
+ auto params = funcType->GetParameters();
+ int targetParamIdx = -1;
+ for (int i = 0; i < params.size(); i++)
+ {
+ auto param = params[i];
+ if (!param.type.GetValue()->IsPointer())
+ continue;
+ auto paramTypeName = param.type.GetValue()->GetChildType().GetValue()->GetTypeName().GetString();
+ if (paramTypeName.find(descriptor) != paramTypeName.npos)
+ {
+ // this is the param
+ targetParamIdx = i;
+ break;
+ }
+ }
+ if (targetParamIdx < 0)
+ continue;
- // Now we are confident that this position is a call that pass Descriptor as a parameter
- defineTypeAtCallsite(ref.func, ref.addr, descriptor, targetParamIdx, true);
- }
- }
- return true;
+ // Now we are confident that this position is a call that pass Descriptor as a parameter
+ defineTypeAtCallsite(ref.func, ref.addr, descriptor, targetParamIdx, true);
+ }
+ }
+ return true;
}
bool PeiResolver::resolvePeiServices()
{
- auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_PEI_SERVICES"));
+ m_task->SetProgressText("Resolving PPIs...");
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_PEI_SERVICES"));
- for (auto ref : refs) {
- if (m_task->IsCancelled())
- return false;
+ for (auto ref : refs)
+ {
+ if (m_task->IsCancelled())
+ return false;
- auto func = ref.func;
- auto mlil = func->GetMediumLevelIL();
- if (!mlil)
- continue;
+ auto func = ref.func;
+ auto mlil = func->GetMediumLevelIL();
+ if (!mlil)
+ continue;
- auto mlilSsa = mlil->GetSSAForm();
- size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
- auto instr = mlilSsa->GetInstruction(mlil->GetSSAInstructionIndex(mlilIdx));
+ auto mlilSsa = mlil->GetSSAForm();
+ size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
+ auto instr = mlilSsa->GetInstruction(mlil->GetSSAInstructionIndex(mlilIdx));
- if (instr.operation == MLIL_CALL_SSA || instr.operation == MLIL_TAILCALL_SSA) {
- auto dest = instr.GetDestExpr();
- if (dest.operation != MLIL_LOAD_STRUCT_SSA)
- continue;
- auto offset = dest.GetOffset();
+ if (instr.operation == MLIL_CALL_SSA || instr.operation == MLIL_TAILCALL_SSA)
+ {
+ auto dest = instr.GetDestExpr();
+ if (dest.operation != MLIL_LOAD_STRUCT_SSA)
+ continue;
+ auto offset = dest.GetOffset();
- if (offset == 0x18 + m_width * 2) {
- // LocatePpi
- resolveGuidInterface(ref.func, ref.addr, 1, 4);
- } else if (offset == 0x18 || offset == 0x18 + m_width || offset == 0x18 + m_width * 3) {
- // InstallPpi, ReinstallPpi, NotifyPpi
- }
- }
- }
- return true;
+ if (offset == 0x18 + m_width * 2)
+ {
+ // LocatePpi
+ resolveGuidInterface(ref.func, ref.addr, 1, 4);
+ }
+ else if (offset == 0x18 || offset == 0x18 + m_width || offset == 0x18 + m_width * 3)
+ {
+ // InstallPpi, ReinstallPpi, NotifyPpi
+ }
+ }
+ }
+ return true;
}
bool PeiResolver::resolvePei()
{
- if (!setModuleEntry(PEI))
- return false;
+ if (!setModuleEntry(PEI))
+ return false;
- if (!resolvePlatformPointers())
- return false;
+ if (!resolvePlatformPointers())
+ return false;
- if (!resolvePeiDescriptors())
- return false;
+ if (!resolvePeiDescriptors())
+ return false;
- if (!resolvePeiServices())
- return false;
+ if (!resolvePeiServices())
+ return false;
- return true;
+ return true;
}
-PeiResolver::PeiResolver(Ref<BinaryView> view, Ref<BackgroundTask> task)
- : Resolver(view, task)
+PeiResolver::PeiResolver(Ref<BinaryView> view, Ref<BackgroundTask> task) : Resolver(view, task)
{
- initProtocolMapping();
- setModuleEntry(PEI);
+ initProtocolMapping();
+ setModuleEntry(PEI);
}