summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/efi/efi_resolver/include/DxeResolver.h31
-rw-r--r--platform/efi/efi_resolver/include/GuidRenderer.h15
-rw-r--r--platform/efi/efi_resolver/include/ModuleType.h23
-rw-r--r--platform/efi/efi_resolver/include/PeiResolver.h27
-rw-r--r--platform/efi/efi_resolver/include/Resolver.h93
-rw-r--r--platform/efi/efi_resolver/include/TypePropagation.h15
-rw-r--r--platform/efi/efi_resolver/include/Utils.h46
-rw-r--r--platform/efi/efi_resolver/src/DxeResolver.cpp403
-rw-r--r--platform/efi/efi_resolver/src/GuidRenderer.cpp63
-rw-r--r--platform/efi/efi_resolver/src/PeiResolver.cpp444
-rw-r--r--platform/efi/efi_resolver/src/Plugin.cpp69
-rw-r--r--platform/efi/efi_resolver/src/Resolver.cpp1141
-rw-r--r--platform/efi/efi_resolver/src/TypePropagation.cpp303
13 files changed, 1406 insertions, 1267 deletions
diff --git a/platform/efi/efi_resolver/include/DxeResolver.h b/platform/efi/efi_resolver/include/DxeResolver.h
index 3515b94a..eef6e6c2 100644
--- a/platform/efi/efi_resolver/include/DxeResolver.h
+++ b/platform/efi/efi_resolver/include/DxeResolver.h
@@ -2,24 +2,25 @@
#include "Resolver.h"
-class DxeResolver : Resolver {
- bool resolveBootServices();
- bool resolveRuntimeServices();
+class DxeResolver : Resolver
+{
+ bool resolveBootServices();
+ bool resolveRuntimeServices();
- bool resolveSmmTables(string serviceName, string tableName);
- bool resolveSmmServices();
- bool resolveSmiHandlers();
+ bool resolveSmmTables(string serviceName, string tableName);
+ bool resolveSmmServices();
+ bool resolveSmiHandlers();
public:
- /*!
- resolve BootServices and RuntimeServices, define protocol types that loaded by BootServices
- */
- bool resolveDxe();
+ /*!
+ resolve BootServices and RuntimeServices, define protocol types that loaded by BootServices
+ */
+ bool resolveDxe();
- /*!
- Define MMST/SMMST and resolve SMM related protocols
- */
- bool resolveSmm();
+ /*!
+ Define MMST/SMMST and resolve SMM related protocols
+ */
+ bool resolveSmm();
- DxeResolver(Ref<BinaryView> view, Ref<BackgroundTask> task);
+ DxeResolver(Ref<BinaryView> view, Ref<BackgroundTask> task);
}; \ No newline at end of file
diff --git a/platform/efi/efi_resolver/include/GuidRenderer.h b/platform/efi/efi_resolver/include/GuidRenderer.h
index 30bd9126..e30aa880 100644
--- a/platform/efi/efi_resolver/include/GuidRenderer.h
+++ b/platform/efi/efi_resolver/include/GuidRenderer.h
@@ -6,16 +6,15 @@
using namespace BinaryNinja;
using namespace std;
-class EfiGuidRenderer : public BinaryNinja::DataRenderer {
- EfiGuidRenderer() = default;
+class EfiGuidRenderer : public BinaryNinja::DataRenderer
+{
+ EfiGuidRenderer() = default;
public:
- bool IsValidForData(BinaryView*, uint64_t address, Type*,
- vector<pair<Type*, size_t>>&) override;
+ bool IsValidForData(BinaryView*, uint64_t address, Type*, vector<pair<Type*, size_t>>&) override;
- vector<DisassemblyTextLine> GetLinesForData(
- BinaryView*, uint64_t address, Type*, const vector<InstructionTextToken>& prefix,
- size_t width, vector<pair<Type*, size_t>>&) override;
+ vector<DisassemblyTextLine> GetLinesForData(BinaryView*, uint64_t address, Type*,
+ const vector<InstructionTextToken>& prefix, size_t width, vector<pair<Type*, size_t>>&) override;
- static void Register();
+ static void Register();
}; \ No newline at end of file
diff --git a/platform/efi/efi_resolver/include/ModuleType.h b/platform/efi/efi_resolver/include/ModuleType.h
index 81b579b9..187dcc36 100644
--- a/platform/efi/efi_resolver/include/ModuleType.h
+++ b/platform/efi/efi_resolver/include/ModuleType.h
@@ -4,19 +4,20 @@
using namespace BinaryNinja;
-enum EFIModuleType {
- UNKNOWN,
- PEI,
- DXE,
+enum EFIModuleType
+{
+ UNKNOWN,
+ PEI,
+ DXE,
};
static inline EFIModuleType identifyModuleType(BinaryView* bv)
{
- std::string viewType = bv->GetCurrentView();
- if (viewType == "Linear:PE")
- return DXE;
- else if (viewType == "Linear:TE")
- return PEI;
- else
- return UNKNOWN;
+ std::string viewType = bv->GetCurrentView();
+ if (viewType == "Linear:PE")
+ return DXE;
+ else if (viewType == "Linear:TE")
+ return PEI;
+ else
+ return UNKNOWN;
} \ No newline at end of file
diff --git a/platform/efi/efi_resolver/include/PeiResolver.h b/platform/efi/efi_resolver/include/PeiResolver.h
index 76827a1a..2ecf8ace 100644
--- a/platform/efi/efi_resolver/include/PeiResolver.h
+++ b/platform/efi/efi_resolver/include/PeiResolver.h
@@ -2,19 +2,20 @@
#include "Resolver.h"
-class PeiResolver : Resolver {
- bool resolvePeiIdt();
- bool resolvePeiMrc();
- bool resolvePeiMrs();
- bool resolvePlatformPointers();
- bool resolvePeiDescriptors();
- bool resolvePeiServices();
+class PeiResolver : Resolver
+{
+ bool resolvePeiIdt();
+ bool resolvePeiMrc();
+ bool resolvePeiMrs();
+ bool resolvePlatformPointers();
+ bool resolvePeiDescriptors();
+ bool resolvePeiServices();
public:
- /*!
- resolve Pei related types and PPIs, this function will also resolve processor-specific pointers
- and tried to define the EFI_PEI_DESCRIPTORS
- */
- bool resolvePei();
- PeiResolver(Ref<BinaryView> view, Ref<BackgroundTask> task);
+ /*!
+ resolve Pei related types and PPIs, this function will also resolve processor-specific pointers
+ and tried to define the EFI_PEI_DESCRIPTORS
+ */
+ bool resolvePei();
+ PeiResolver(Ref<BinaryView> view, Ref<BackgroundTask> task);
}; \ No newline at end of file
diff --git a/platform/efi/efi_resolver/include/Resolver.h b/platform/efi/efi_resolver/include/Resolver.h
index 7bbd3b99..91bb1862 100644
--- a/platform/efi/efi_resolver/include/Resolver.h
+++ b/platform/efi/efi_resolver/include/Resolver.h
@@ -16,61 +16,60 @@ using namespace std;
typedef array<uint8_t, 16> EFI_GUID;
-class Resolver {
+class Resolver
+{
protected:
- Ref<BinaryView> m_view;
- Ref<BackgroundTask> m_task;
- size_t m_width;
- map<EFI_GUID, pair<string, string>> m_protocol;
- map<EFI_GUID, string> m_user_guids;
+ Ref<BinaryView> m_view;
+ Ref<BackgroundTask> m_task;
+ size_t m_width;
+ map<EFI_GUID, pair<string, string>> m_protocol;
+ map<EFI_GUID, string> m_user_guids;
- vector<pair<uint64_t, string>> m_service_usages;
- vector<pair<uint64_t, string>> m_protocol_usages;
- vector<pair<uint64_t, EFI_GUID>> m_guid_usages;
- vector<pair<uint64_t, string>> m_variable_usages;
+ vector<pair<uint64_t, string>> m_service_usages;
+ vector<pair<uint64_t, string>> m_protocol_usages;
+ vector<pair<uint64_t, EFI_GUID>> m_guid_usages;
+ vector<pair<uint64_t, string>> m_variable_usages;
- bool parseUserGuidIfExists(const string& filePath);
- bool parseProtocolMapping(const string& filePath);
+ bool parseUserGuidIfExists(const string& filePath);
+ bool parseProtocolMapping(const string& filePath);
- /*!
- For backward compatibility, if a user saved a bndb with older version Binary Ninja
- this function will try to retrieve types from Platform Types if it doesn't find one
- in BinaryView
- */
- Ref<Type> GetTypeFromViewAndPlatform(string type_name);
- void initProtocolMapping();
+ /*!
+ For backward compatibility, if a user saved a bndb with older version Binary Ninja
+ this function will try to retrieve types from Platform Types if it doesn't find one
+ in BinaryView
+ */
+ Ref<Type> GetTypeFromViewAndPlatform(string type_name);
+ void initProtocolMapping();
public:
- bool setModuleEntry(EFIModuleType fileType);
- bool resolveGuidInterface(Ref<Function> func, uint64_t addr, int guid_pos, int interface_pos);
- Resolver(Ref<BinaryView> view, Ref<BackgroundTask> task);
+ bool setModuleEntry(EFIModuleType fileType);
+ bool resolveGuidInterface(Ref<Function> func, uint64_t addr, int guid_pos, int interface_pos);
+ Resolver(Ref<BinaryView> view, Ref<BackgroundTask> task);
- pair<string, string> lookupGuid(EFI_GUID guidBytes);
- pair<string, string> defineAndLookupGuid(uint64_t addr);
+ pair<string, string> lookupGuid(EFI_GUID guidBytes);
+ pair<string, string> defineAndLookupGuid(uint64_t addr);
- string nonConflictingName(const string& basename);
- static string nonConflictingLocalName(Ref<Function> func, const string& basename);
+ string nonConflictingName(const string& basename);
+ static string nonConflictingLocalName(Ref<Function> func, const string& basename);
- /*!
- Define the structure used at the callsite with type `typeName`, propagate it to the data section. If it's a structure type, define it fields
- according to the `followFields` parameter. The input `addr` should be a call instruction
- \param func the function that contains the callsite (it's parent function)
- \param addr address of the callsite
- \param typeName the type that need to define
- \param paramIdx the parameter index that want to define
- \param followFields whether to define the structure's fields if they are pointers
- \return False if failed
+ /*!
+ Define the structure used at the callsite with type `typeName`, propagate it to the data section. If it's a
+ structure type, define it fields according to the `followFields` parameter. The input `addr` should be a call
+ instruction \param func the function that contains the callsite (it's parent function) \param addr address of the
+ callsite \param typeName the type that need to define \param paramIdx the parameter index that want to define \param
+ followFields whether to define the structure's fields if they are pointers \return False if failed
- \b Example:
- \code{.cpp}
- refs = bv->GetCodeReferencesForType(QualifiedName("EFI_GET_VARIABLE"));
- for (auto ref : refs)
- {
- // ... some checking, need to make sure is a call instruction
- bool ok = defineTypeAtCallsite(ref.func, ref.addr, "EFI_GUID", 2, false);
- }
- \endcode
- */
- bool defineTypeAtCallsite(Ref<Function> func, uint64_t addr, string typeName, int paramIdx, bool followFields = false);
- vector<HighLevelILInstruction> HighLevelILExprsAt(Ref<Function> func, Ref<Architecture> arch, uint64_t addr);
+ \b Example:
+ \code{.cpp}
+ refs = bv->GetCodeReferencesForType(QualifiedName("EFI_GET_VARIABLE"));
+ for (auto ref : refs)
+ {
+ // ... some checking, need to make sure is a call instruction
+ bool ok = defineTypeAtCallsite(ref.func, ref.addr, "EFI_GUID", 2, false);
+ }
+ \endcode
+ */
+ bool defineTypeAtCallsite(
+ Ref<Function> func, uint64_t addr, string typeName, int paramIdx, bool followFields = false);
+ vector<HighLevelILInstruction> HighLevelILExprsAt(Ref<Function> func, Ref<Architecture> arch, uint64_t addr);
}; \ No newline at end of file
diff --git a/platform/efi/efi_resolver/include/TypePropagation.h b/platform/efi/efi_resolver/include/TypePropagation.h
index 2ba131ba..1985e2ab 100644
--- a/platform/efi/efi_resolver/include/TypePropagation.h
+++ b/platform/efi/efi_resolver/include/TypePropagation.h
@@ -5,13 +5,14 @@
using namespace BinaryNinja;
-class TypePropagation {
- Ref<BinaryView> m_view;
- std::deque<uint64_t> m_queue;
- Ref<Platform> m_platform;
+class TypePropagation
+{
+ Ref<BinaryView> m_view;
+ std::deque<uint64_t> m_queue;
+ Ref<Platform> m_platform;
public:
- TypePropagation(BinaryView* view);
- bool propagateFuncParamTypes(Function* func);
- bool propagateFuncParamTypes(Function* func, SSAVariable ssa_var);
+ TypePropagation(BinaryView* view);
+ bool propagateFuncParamTypes(Function* func);
+ bool propagateFuncParamTypes(Function* func, SSAVariable ssa_var);
}; \ No newline at end of file
diff --git a/platform/efi/efi_resolver/include/Utils.h b/platform/efi/efi_resolver/include/Utils.h
index f2c371a8..981908b2 100644
--- a/platform/efi/efi_resolver/include/Utils.h
+++ b/platform/efi/efi_resolver/include/Utils.h
@@ -6,31 +6,35 @@ using namespace BinaryNinja;
static inline std::string GetOriginalTypeName(Ref<Type> type)
{
- std::string result;
- if (type->IsPointer()) {
- if (type->GetChildType().GetValue()->IsNamedTypeRefer()) {
- return type->GetChildType().GetValue()->GetNamedTypeReference()->GetName().GetString();
- }
- return type->GetTypeName().GetString();
- }
- if (type->IsNamedTypeRefer())
- return type->GetNamedTypeReference()->GetName().GetString();
+ std::string result;
+ if (type->IsPointer())
+ {
+ if (type->GetChildType().GetValue()->IsNamedTypeRefer())
+ {
+ return type->GetChildType().GetValue()->GetNamedTypeReference()->GetName().GetString();
+ }
+ return type->GetTypeName().GetString();
+ }
+ if (type->IsNamedTypeRefer())
+ return type->GetNamedTypeReference()->GetName().GetString();
- return type->GetTypeName().GetString();
+ return type->GetTypeName().GetString();
}
static inline std::string GetVarNameForTypeStr(const std::string typeStr)
{
- std::istringstream iss(typeStr);
- std::string word;
- std::string result;
+ std::istringstream iss(typeStr);
+ std::string word;
+ std::string result;
- while (std::getline(iss, word, '_')) {
- if (!word.empty()) {
- word[0] = std::toupper(word[0]);
- std::transform(word.begin() + 1, word.end(), word.begin() + 1, ::tolower);
- result += word;
- }
- }
- return result;
+ while (std::getline(iss, word, '_'))
+ {
+ if (!word.empty())
+ {
+ word[0] = std::toupper(word[0]);
+ std::transform(word.begin() + 1, word.end(), word.begin() + 1, ::tolower);
+ result += word;
+ }
+ }
+ return result;
}
diff --git a/platform/efi/efi_resolver/src/DxeResolver.cpp b/platform/efi/efi_resolver/src/DxeResolver.cpp
index f801a8e5..f31c42ae 100644
--- a/platform/efi/efi_resolver/src/DxeResolver.cpp
+++ b/platform/efi/efi_resolver/src/DxeResolver.cpp
@@ -2,254 +2,273 @@
bool DxeResolver::resolveBootServices()
{
- auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_BOOT_SERVICES"));
- // search reference of `EFI_BOOT_SERVICES` so that we can easily parse different services
+ m_task->SetProgressText("Resolving Boot Services...");
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_BOOT_SERVICES"));
+ // search reference of `EFI_BOOT_SERVICES` so that we can easily parse different 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 * 16 || offset == 0x18 + m_width * 32) {
- // HandleProtocol, OpenProtocol
- // Guid:1, Interface:2
- resolveGuidInterface(ref.func, ref.addr, 1, 2);
- } else if (offset == 0x18 + m_width * 37) {
- // LocateProtocol
- resolveGuidInterface(ref.func, ref.addr, 0, 2);
- }
- }
- }
- return true;
+ if (offset == 0x18 + m_width * 16 || offset == 0x18 + m_width * 32)
+ {
+ // HandleProtocol, OpenProtocol
+ // Guid:1, Interface:2
+ resolveGuidInterface(ref.func, ref.addr, 1, 2);
+ }
+ else if (offset == 0x18 + m_width * 37)
+ {
+ // LocateProtocol
+ resolveGuidInterface(ref.func, ref.addr, 0, 2);
+ }
+ }
+ }
+ return true;
}
bool DxeResolver::resolveRuntimeServices()
{
- auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_RUNTIME_SERVICES"));
+ m_task->SetProgressText("Resolving Runtime Services...");
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_RUNTIME_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 (offset == 0x18 + m_width * 6 || offset == 0x18 + m_width * 8) {
- // TODO implement this
- // GetVariable and SetVariable
- }
- }
- }
- return true;
+ 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 * 6 || offset == 0x18 + m_width * 8)
+ {
+ // TODO implement this
+ // GetVariable and SetVariable
+ }
+ }
+ }
+ return true;
}
bool DxeResolver::resolveSmmTables(string serviceName, string tableName)
{
- auto refs = m_view->GetCodeReferencesForType(QualifiedName(serviceName));
- // both versions use the same type, so we only need to search for this one
- for (auto &ref : refs) {
- if (m_task->IsCancelled())
- return false;
+ m_task->SetProgressText("Defining MM tables...");
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName(serviceName));
+ // both versions use the same type, so we only need to search for this one
+ 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)
- continue;
+ if (instr.operation != MLIL_CALL_SSA && instr.operation != MLIL_TAILCALL_SSA)
+ continue;
- auto destExpr = instr.GetDestExpr();
- if (destExpr.operation != MLIL_LOAD_STRUCT_SSA)
- continue;
+ auto destExpr = instr.GetDestExpr();
+ if (destExpr.operation != MLIL_LOAD_STRUCT_SSA)
+ continue;
- if (destExpr.GetOffset() != 8)
- continue;
+ if (destExpr.GetOffset() != 8)
+ continue;
- auto params = instr.GetParameterExprs();
- if (params.size() < 2)
- continue;
+ auto params = instr.GetParameterExprs();
+ if (params.size() < 2)
+ continue;
- auto smstAddr = params[1];
- if (smstAddr.operation != MLIL_CONST_PTR)
- continue;
+ auto smstAddr = params[1];
+ if (smstAddr.operation != MLIL_CONST_PTR)
+ continue;
- QualifiedNameAndType result;
- string errors;
- bool ok = m_view->ParseTypeString(tableName, result, errors);
- if (!ok)
- return false;
- m_view->DefineDataVariable(smstAddr.GetValue().value, result.type);
- m_view->DefineUserSymbol(new Symbol(DataSymbol, "gMmst", smstAddr.GetValue().value));
- m_view->UpdateAnalysisAndWait();
- }
- return true;
+ QualifiedNameAndType result;
+ string errors;
+ bool ok = m_view->ParseTypeString(tableName, result, errors);
+ if (!ok)
+ return false;
+ m_view->DefineDataVariable(smstAddr.GetValue().value, result.type);
+ m_view->DefineUserSymbol(new Symbol(DataSymbol, "gMmst", smstAddr.GetValue().value));
+ m_view->UpdateAnalysisAndWait();
+ }
+ return true;
}
bool DxeResolver::resolveSmmServices()
{
- auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_MM_SYSTEM_TABLE"));
- auto refs_smm = m_view->GetCodeReferencesForType(QualifiedName("EFI_SMM_SYSTEM_TABLE2"));
- // These tables have same type information, we can just iterate once
- refs.insert(refs.end(), refs_smm.begin(), refs_smm.end());
+ m_task->SetProgressText("Resolving MM services...");
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_MM_SYSTEM_TABLE"));
+ auto refs_smm = m_view->GetCodeReferencesForType(QualifiedName("EFI_SMM_SYSTEM_TABLE2"));
+ // These tables have same type information, we can just iterate once
+ refs.insert(refs.end(), refs_smm.begin(), refs_smm.end());
- 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 * 0x14) {
- // SmmHandleProtocol
- resolveGuidInterface(ref.func, ref.addr, 1, 2);
- } else if (offset == 0x18 + m_width * 0x17) {
- // SmmLocateProtocol
- resolveGuidInterface(ref.func, ref.addr, 0, 2);
- }
- }
- }
- return true;
+ if (offset == 0x18 + m_width * 0x14)
+ {
+ // SmmHandleProtocol
+ resolveGuidInterface(ref.func, ref.addr, 1, 2);
+ }
+ else if (offset == 0x18 + m_width * 0x17)
+ {
+ // SmmLocateProtocol
+ resolveGuidInterface(ref.func, ref.addr, 0, 2);
+ }
+ }
+ }
+ return true;
}
bool DxeResolver::resolveSmiHandlers()
{
- auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_MM_SW_REGISTER"));
- for (auto &ref : refs)
- {
- if (m_task->IsCancelled())
- return false;
+ m_task->SetProgressText("Resolving SMI Handlers...");
+ auto refs = m_view->GetCodeReferencesForType(QualifiedName("EFI_MM_SW_REGISTER"));
+ auto refs_smm_sw = m_view->GetCodeReferencesForType(QualifiedName("EFI_SMM_SW_REGISTER2"));
+ auto refs_mm_sx = m_view->GetCodeReferencesForType(QualifiedName("EFI_MM_SX_REGISTER"));
+ auto refs_smm_sx = m_view->GetCodeReferencesForType(QualifiedName("EFI_SMM_SX_REGISTER2"));
+ // Define them together
- auto func = ref.func;
- auto mlil = func->GetMediumLevelIL();
- if (!mlil)
- continue;
+ refs.insert(refs.end(), refs_smm_sw.begin(), refs_smm_sw.end());
+ refs.insert(refs.end(), refs_smm_sx.begin(), refs_smm_sw.end());
+ refs.insert(refs.end(), refs_mm_sx.begin(), refs_mm_sx.end());
- auto mlilSsa = mlil->GetSSAForm();
- size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
- auto instr = mlilSsa->GetInstruction(mlil->GetSSAInstructionIndex(mlilIdx));
+ for (auto& ref : refs)
+ {
+ if (m_task->IsCancelled())
+ return false;
- if (instr.operation == MLIL_CALL_SSA || instr.operation == MLIL_TAILCALL_SSA)
- {
- auto dest = instr.GetDestExpr();
- if (dest.operation != MLIL_LOAD_STRUCT_SSA)
- continue;
+ auto func = ref.func;
+ auto mlil = func->GetMediumLevelIL();
+ if (!mlil)
+ continue;
- auto offset = dest.GetOffset();
- if (offset == 0) {
- /* EFI_MM_SW_REGISTER, we want to rename the second parameter according to the third parameter
- typedef enum EFI_STATUS (* EFI_MM_SW_REGISTER)(
- struct EFI_MM_SW_DISPATCH_PROTOCOL* This,
- EFI_MM_HANDLER_ENTRY_POINT DispatchFunction,
- struct EFI_MM_SW_REGISTER_CONTEXT*
- RegisterContext, EFI_HANDLE* DispatchHandle); */
+ auto mlilSsa = mlil->GetSSAForm();
+ size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), ref.addr);
+ auto instr = mlilSsa->GetInstruction(mlil->GetSSAInstructionIndex(mlilIdx));
- auto parameters = instr.GetParameterExprs();
- if (parameters.size() < 3)
- continue;
+ if (instr.operation == MLIL_CALL_SSA || instr.operation == MLIL_TAILCALL_SSA)
+ {
+ auto dest = instr.GetDestExpr();
+ if (dest.operation != MLIL_LOAD_STRUCT_SSA)
+ continue;
- auto dispatchFunction = parameters[1];
- auto registerContext = parameters[2];
+ auto offset = dest.GetOffset();
+ if (offset == 0)
+ {
+ auto parameters = instr.GetParameterExprs();
+ if (parameters.size() < 4)
+ continue;
- // Determine the function name according to the registerContext
- /* struct EFI_MM_SW_REGISTER_CONTEXT
- * {
- * UINTN SwMmiInputValue;
- * };
- */
- string funcName = "SmiHandler";
+ // TODO we should be able to parse registerContext, but it's normally an aliased variable
+ // and we have some issues relate to that
+ auto dispatchFunction = parameters[1];
+ if (dispatchFunction.operation != MLIL_CONST_PTR)
+ continue;
+ auto funcAddr = static_cast<uint64_t>(dispatchFunction.GetConstant());
+ auto targetFunc = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), funcAddr);
+ auto funcType = targetFunc->GetType();
+ std::ostringstream ss;
+ ss << "SmiHandler_" << std::hex << funcAddr;
+ string funcName = ss.str();
- if (dispatchFunction.operation != MLIL_CONST_PTR)
- continue;
- auto funcAddr = static_cast<uint64_t> (dispatchFunction.GetConstant());
- auto targetFunc = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), funcAddr);
- auto funcType = targetFunc->GetType();
- // typedef enum
- string handleTypeStr = "EFI_STATUS SmiHandler(EFI_HANDLE DispatchHandle, VOID* Context, VOID* CommBuffer, UINTN* CommBufferSize);";
- QualifiedNameAndType result;
- string errors;
- bool ok = m_view->ParseTypeString(handleTypeStr, result, errors);
- if (!ok)
- return false;
- targetFunc->SetUserType(result.type);
- m_view->DefineUserSymbol(new Symbol(FunctionSymbol, funcName, funcAddr));
- m_view->UpdateAnalysisAndWait();
+ // typedef enum
+ string handleTypeStr =
+ "EFI_STATUS SmiHandler(EFI_HANDLE DispatchHandle, VOID* Context, VOID* CommBuffer, UINTN* "
+ "CommBufferSize);";
+ QualifiedNameAndType result;
+ string errors;
+ bool ok = m_view->ParseTypeString(handleTypeStr, result, errors);
+ if (!ok)
+ return false;
+ targetFunc->SetUserType(result.type);
+ m_view->DefineUserSymbol(new Symbol(FunctionSymbol, funcName, funcAddr));
+ m_view->UpdateAnalysisAndWait();
- // After setting the type, we want to propagate the parameters' type
- TypePropagation propagator(m_view);
- propagator.propagateFuncParamTypes(targetFunc);
- }
- }
- }
- return true;
+ // After setting the type, we want to propagate the parameters' type
+ TypePropagation propagator(m_view);
+ propagator.propagateFuncParamTypes(targetFunc);
+ }
+ }
+ }
+ return true;
}
bool DxeResolver::resolveDxe()
{
- if (!resolveBootServices())
- return false;
- if (!resolveRuntimeServices())
- return false;
- return true;
+ if (!resolveBootServices())
+ return false;
+ if (!resolveRuntimeServices())
+ return false;
+ return true;
}
bool DxeResolver::resolveSmm()
{
- if (!resolveSmmTables("EFI_SMM_GET_SMST_LOCATION2", "EFI_SMM_SYSTEM_TABLE2*"))
- return false;
- if (!resolveSmmTables("EFI_MM_GET_MMST_LOCATION", "EFI_MM_SYSTEM_TABLE*"))
- return false;
- if (!resolveSmmServices())
- return false;
- if (!resolveSmiHandlers())
- return false;
- return true;
+ if (!resolveSmmTables("EFI_SMM_GET_SMST_LOCATION2", "EFI_SMM_SYSTEM_TABLE2*"))
+ return false;
+ if (!resolveSmmTables("EFI_MM_GET_MMST_LOCATION", "EFI_MM_SYSTEM_TABLE*"))
+ return false;
+ if (!resolveSmmServices())
+ return false;
+ if (!resolveSmiHandlers())
+ return false;
+ return true;
}
-DxeResolver::DxeResolver(Ref<BinaryView> view, Ref<BackgroundTask> task)
- : Resolver(view, task)
+DxeResolver::DxeResolver(Ref<BinaryView> view, Ref<BackgroundTask> task) : Resolver(view, task)
{
- initProtocolMapping();
- setModuleEntry(DXE);
+ initProtocolMapping();
+ setModuleEntry(DXE);
}
diff --git a/platform/efi/efi_resolver/src/GuidRenderer.cpp b/platform/efi/efi_resolver/src/GuidRenderer.cpp
index ef148094..deac0265 100644
--- a/platform/efi/efi_resolver/src/GuidRenderer.cpp
+++ b/platform/efi/efi_resolver/src/GuidRenderer.cpp
@@ -2,55 +2,50 @@
bool isType(const vector<pair<Type*, size_t>>& context, const string& name)
{
- if (context.empty())
- return false;
+ if (context.empty())
+ return false;
- auto [deepestType, size] = context.back();
- if (!deepestType->IsNamedTypeRefer())
- return false;
+ auto [deepestType, size] = context.back();
+ if (!deepestType->IsNamedTypeRefer())
+ return false;
- return deepestType->GetTypeName().GetString() == name;
+ return deepestType->GetTypeName().GetString() == name;
}
-bool EfiGuidRenderer::IsValidForData(BinaryView* bv, uint64_t address, Type* type,
- vector<pair<Type*, size_t>>& context)
+bool EfiGuidRenderer::IsValidForData(BinaryView* bv, uint64_t address, Type* type, vector<pair<Type*, size_t>>& context)
{
- return isType(context, "EFI_GUID");
+ return isType(context, "EFI_GUID");
}
static string formatGuid(uint32_t data1, uint16_t data2, uint16_t data3, uint64_t data4)
{
- std::ostringstream oss;
- oss << std::hex << std::uppercase << std::setfill('0')
- << std::setw(8) << data1 << "-"
- << std::setw(4) << data2 << "-"
- << std::setw(4) << data3 << "-"
- << std::setw(16) << data4;
- return oss.str();
+ std::ostringstream oss;
+ oss << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << data1 << "-" << std::setw(4) << data2
+ << "-" << std::setw(4) << data3 << "-" << std::setw(16) << data4;
+ return oss.str();
}
-vector<DisassemblyTextLine> EfiGuidRenderer::GetLinesForData(
- BinaryView* bv, uint64_t address, Type*, const vector<InstructionTextToken>& prefix,
- size_t, vector<pair<Type*, size_t>>& context)
+vector<DisassemblyTextLine> EfiGuidRenderer::GetLinesForData(BinaryView* bv, uint64_t address, Type*,
+ const vector<InstructionTextToken>& prefix, size_t, vector<pair<Type*, size_t>>& context)
{
- BinaryReader reader(bv);
- reader.Seek(address);
- auto data1 = reader.Read32();
- auto data2 = reader.Read16();
- auto data3 = reader.Read16();
- auto data4 = reader.ReadBE64();
- string guidStr = formatGuid(data1, data2, data3, data4);
+ BinaryReader reader(bv);
+ reader.Seek(address);
+ auto data1 = reader.Read32();
+ auto data2 = reader.Read16();
+ auto data3 = reader.Read16();
+ auto data4 = reader.ReadBE64();
+ string guidStr = formatGuid(data1, data2, data3, data4);
- DisassemblyTextLine line;
- line.addr = address;
- line.tokens = prefix;
- line.tokens.emplace_back(TextToken, "[EFI_GUID(\"");
- line.tokens.emplace_back(StringToken, guidStr);
- line.tokens.emplace_back(TextToken, "\")]");
- return { line };
+ DisassemblyTextLine line;
+ line.addr = address;
+ line.tokens = prefix;
+ line.tokens.emplace_back(TextToken, "[EFI_GUID(\"");
+ line.tokens.emplace_back(StringToken, guidStr);
+ line.tokens.emplace_back(TextToken, "\")]");
+ return {line};
}
void EfiGuidRenderer::Register()
{
- DataRendererContainer::RegisterTypeSpecificDataRenderer(new EfiGuidRenderer());
+ DataRendererContainer::RegisterTypeSpecificDataRenderer(new EfiGuidRenderer());
}
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);
}
diff --git a/platform/efi/efi_resolver/src/Plugin.cpp b/platform/efi/efi_resolver/src/Plugin.cpp
index bfa19a7f..b562975c 100644
--- a/platform/efi/efi_resolver/src/Plugin.cpp
+++ b/platform/efi/efi_resolver/src/Plugin.cpp
@@ -5,60 +5,61 @@
using namespace BinaryNinja;
-extern "C" {
+extern "C"
+{
BN_DECLARE_CORE_ABI_VERSION
BINARYNINJAPLUGIN void CorePluginDependencies()
{
- BinaryNinja::AddOptionalPluginDependency("arch_x86");
- BinaryNinja::AddOptionalPluginDependency("arch_armv7");
- BinaryNinja::AddOptionalPluginDependency("arch_arm64");
- BinaryNinja::AddOptionalPluginDependency("platform_efi");
+ BinaryNinja::AddOptionalPluginDependency("arch_x86");
+ BinaryNinja::AddOptionalPluginDependency("arch_armv7");
+ BinaryNinja::AddOptionalPluginDependency("arch_arm64");
+ BinaryNinja::AddOptionalPluginDependency("platform_efi");
}
static Ref<BackgroundTask> efiBackgroundTask = nullptr;
void Run(Ref<BinaryView> view)
{
- efiBackgroundTask = new BackgroundTask("Loading EFI protocol mappings!", true);
- thread resolverThread([view]() {
- LogInfo("Entering new thread");
+ efiBackgroundTask = new BackgroundTask("Loading EFI protocol mappings!", true);
+ thread resolverThread([view]() {
+ LogInfo("Entering new thread");
- LogInfo("Identifying module type");
- EFIModuleType moduleType = identifyModuleType(view);
+ LogInfo("Identifying module type");
+ EFIModuleType moduleType = identifyModuleType(view);
-#ifdef DEBUG
- auto undo = view->BeginUndoActions();
+#ifndef DEBUG
+ auto undo = view->BeginUndoActions();
#endif
- if (moduleType == PEI) {
- efiBackgroundTask->SetProgressText("Resolving PEIM...");
- auto resolver = PeiResolver(view, efiBackgroundTask);
- resolver.resolvePei();
- } else if (moduleType == DXE) {
- efiBackgroundTask->SetProgressText("Resolving DXE protocols...");
- auto resolver = DxeResolver(view, efiBackgroundTask);
- resolver.resolveDxe();
- efiBackgroundTask->SetProgressText("Resolving MM related protocols...");
- resolver.resolveSmm();
- }
+ if (moduleType == PEI)
+ {
+ efiBackgroundTask->SetProgressText("Resolving PEIM...");
+ auto resolver = PeiResolver(view, efiBackgroundTask);
+ resolver.resolvePei();
+ }
+ else if (moduleType == DXE)
+ {
+ efiBackgroundTask->SetProgressText("Resolving DXE protocols...");
+ auto resolver = DxeResolver(view, efiBackgroundTask);
+ resolver.resolveDxe();
+ efiBackgroundTask->SetProgressText("Resolving MM related protocols...");
+ resolver.resolveSmm();
+ }
-#ifdef DEBUG
- resolver.m_view->CommitUndoActions(undo);
+#ifndef DEBUG
+ view->CommitUndoActions(undo);
#endif
- efiBackgroundTask->Finish();
- });
- resolverThread.detach();
+ efiBackgroundTask->Finish();
+ });
+ resolverThread.detach();
}
BINARYNINJAPLUGIN bool CorePluginInit()
{
- EfiGuidRenderer::Register();
+ EfiGuidRenderer::Register();
- PluginCommand::Register(
- "EFI Resolver\\Resolve EFI Types And Protocols",
- "Resolve EFI Protocols",
- &Run);
+ PluginCommand::Register("EFI Resolver\\Resolve EFI Types And Protocols", "Resolve EFI Protocols", &Run);
- return true;
+ return true;
}
}
diff --git a/platform/efi/efi_resolver/src/Resolver.cpp b/platform/efi/efi_resolver/src/Resolver.cpp
index 94510321..36fa190b 100644
--- a/platform/efi/efi_resolver/src/Resolver.cpp
+++ b/platform/efi/efi_resolver/src/Resolver.cpp
@@ -2,675 +2,752 @@
string Resolver::nonConflictingName(const string& basename)
{
- int idx = 0;
- string name = basename;
- do {
- auto sym = m_view->GetSymbolByRawName(name);
- if (!sym)
- return name;
- else {
- name = basename + to_string(idx);
- idx += 1;
- }
- } while (true);
+ int idx = 0;
+ string name = basename;
+ do
+ {
+ auto sym = m_view->GetSymbolByRawName(name);
+ if (!sym)
+ return name;
+ else
+ {
+ name = basename + to_string(idx);
+ idx += 1;
+ }
+ } while (true);
}
string Resolver::nonConflictingLocalName(Ref<Function> func, const string& basename)
{
- string name = basename;
- int idx = 0;
- while (true) {
- bool ok = true;
- for (const auto& varPair : func->GetVariables()) {
- if (varPair.second.name == name) {
- ok = false;
- break;
- }
- }
- if (ok)
- break;
- name = basename + to_string(idx);
- idx += 1;
- }
- return name;
+ string name = basename;
+ int idx = 0;
+ while (true)
+ {
+ bool ok = true;
+ for (const auto& varPair : func->GetVariables())
+ {
+ if (varPair.second.name == name)
+ {
+ ok = false;
+ break;
+ }
+ }
+ if (ok)
+ break;
+ name = basename + to_string(idx);
+ idx += 1;
+ }
+ return name;
}
static string GetBundledEfiPath()
{
- string path = GetBundledPluginDirectory();
+ string path = GetBundledPluginDirectory();
#if defined(_WIN32)
- return path + "..\\types\\efi.c";
-#elif defined(__linux__)
- return path + "../types/efi.c";
+ return path + "..\\types\\efi.c";
+#elif defined(__APPLE__)
+ return path + "/../../Resources/types/efi.c";
#else
- return path + "/../../Resources/types/efi.c";
+ return path + "../types/efi.c";
#endif
}
static string GetUserGuidPath()
{
- string path = GetUserDirectory();
+ string path = GetUserDirectory();
#if defined(_WIN32)
- return path + "\\types\\efi-guids.json";
-#elif defined(__linux__)
- return path + "/types/efi-guids.json";
+ return path + "\\types\\efi-guids.json";
+#elif defined(__APPLE__)
+ return path + "/types/efi-guids.json";
#else
- return path + "/types/efi-guids.json";
+ return path + "/types/efi-guids.json";
#endif
}
static EFI_GUID parseGuid(const string& guidStr)
{
- EFI_GUID guid;
- istringstream iss(guidStr);
- string token;
- unsigned long value;
+ EFI_GUID guid;
+ istringstream iss(guidStr);
+ string token;
+ unsigned long value;
- getline(iss, token, ',');
- value = stoul(token, nullptr, 16);
- guid[0] = static_cast<uint8_t>(value);
- guid[1] = static_cast<uint8_t>(value >> 8);
- guid[2] = static_cast<uint8_t>(value >> 16);
- guid[3] = static_cast<uint8_t>(value >> 24);
+ getline(iss, token, ',');
+ value = stoul(token, nullptr, 16);
+ guid[0] = static_cast<uint8_t>(value);
+ guid[1] = static_cast<uint8_t>(value >> 8);
+ guid[2] = static_cast<uint8_t>(value >> 16);
+ guid[3] = static_cast<uint8_t>(value >> 24);
- getline(iss, token, ',');
- value = stoul(token, nullptr, 16);
- guid[4] = static_cast<uint8_t>(value);
- guid[5] = static_cast<uint8_t>(value >> 8);
+ getline(iss, token, ',');
+ value = stoul(token, nullptr, 16);
+ guid[4] = static_cast<uint8_t>(value);
+ guid[5] = static_cast<uint8_t>(value >> 8);
- getline(iss, token, ',');
- value = stoul(token, nullptr, 16);
- guid[6] = static_cast<uint8_t>(value);
- guid[7] = static_cast<uint8_t>(value >> 8);
+ getline(iss, token, ',');
+ value = stoul(token, nullptr, 16);
+ guid[6] = static_cast<uint8_t>(value);
+ guid[7] = static_cast<uint8_t>(value >> 8);
- for (int i = 8; i < 16; i++) {
- getline(iss, token, ',');
- value = stoul(token, nullptr, 16);
- guid[i] = static_cast<uint8_t>(value);
- }
- return guid;
+ for (int i = 8; i < 16; i++)
+ {
+ getline(iss, token, ',');
+ value = stoul(token, nullptr, 16);
+ guid[i] = static_cast<uint8_t>(value);
+ }
+ return guid;
}
bool Resolver::parseProtocolMapping(const string& filePath)
{
- vector<pair<EFI_GUID, string>> guids;
- ifstream efiDefs;
- string line;
+ vector<pair<EFI_GUID, string>> guids;
+ ifstream efiDefs;
+ string line;
- m_protocol.clear();
+ m_protocol.clear();
- efiDefs.open(filePath.c_str());
- if (!efiDefs.is_open())
- return false;
+ efiDefs.open(filePath.c_str());
+ if (!efiDefs.is_open())
+ return false;
- while (getline(efiDefs, line)) {
- if (m_task->IsCancelled())
- return false;
+ while (getline(efiDefs, line))
+ {
+ if (m_task->IsCancelled())
+ return false;
- if (line.substr(0, 12) == "///@protocol") {
- string guid = line.substr(12);
- guid.erase(remove_if(guid.begin(), guid.end(), [](char c) { return c == '{' || c == '}' || c == ' '; }), guid.end());
- guids.emplace_back( parseGuid(guid), "" );
- } else if (line.substr(0, 11) == "///@binding") {
- istringstream iss(line.substr(11));
- string guidName, guid;
- iss >> guidName >> guid;
- guid.erase(remove_if(guid.begin(), guid.end(), [](char c) { return c == '{' || c == '}' || c == ' '; }), guid.end());
- guids.emplace_back( parseGuid(guid), guidName );
- } else if (line.substr(0, 6) == "struct") {
- if (guids.empty())
- continue;
- istringstream iss(line.substr(6));
- string name;
- iss >> name;
- for (const auto& guidInfo : guids) {
- if (guidInfo.second.empty()) {
- m_protocol[guidInfo.first] = make_pair(name, name + "_GUID");
- } else {
- m_protocol[guidInfo.first] = make_pair(name, guidInfo.second);
- }
- }
- } else {
- guids.clear();
- }
- }
- efiDefs.close();
+ if (line.substr(0, 12) == "///@protocol")
+ {
+ string guid = line.substr(12);
+ guid.erase(remove_if(guid.begin(), guid.end(), [](char c) { return c == '{' || c == '}' || c == ' '; }),
+ guid.end());
+ guids.emplace_back(parseGuid(guid), "");
+ }
+ else if (line.substr(0, 11) == "///@binding")
+ {
+ istringstream iss(line.substr(11));
+ string guidName, guid;
+ iss >> guidName >> guid;
+ guid.erase(remove_if(guid.begin(), guid.end(), [](char c) { return c == '{' || c == '}' || c == ' '; }),
+ guid.end());
+ guids.emplace_back(parseGuid(guid), guidName);
+ }
+ else if (line.substr(0, 6) == "struct")
+ {
+ if (guids.empty())
+ continue;
+ istringstream iss(line.substr(6));
+ string name;
+ iss >> name;
+ for (const auto& guidInfo : guids)
+ {
+ if (guidInfo.second.empty())
+ {
+ m_protocol[guidInfo.first] = make_pair(name, name + "_GUID");
+ }
+ else
+ {
+ m_protocol[guidInfo.first] = make_pair(name, guidInfo.second);
+ }
+ }
+ }
+ else
+ {
+ guids.clear();
+ }
+ }
+ efiDefs.close();
- return true;
+ return true;
}
bool Resolver::parseUserGuidIfExists(const string& filePath)
{
- ifstream userJson(filePath);
- if (!userJson.is_open())
- return false;
+ ifstream userJson(filePath);
+ if (!userJson.is_open())
+ return false;
- nlohmann::json jsonContent;
- userJson >> jsonContent;
+ nlohmann::json jsonContent;
+ userJson >> jsonContent;
- for (const auto& element : jsonContent.items()) {
- if (m_task->IsCancelled())
- return false;
+ for (const auto& element : jsonContent.items())
+ {
+ if (m_task->IsCancelled())
+ return false;
- const auto& guidName = element.key();
- auto guidBytes = element.value();
- if (guidBytes.size() != 11) {
- LogError("Error: GUID array size is incorrect for %s", guidName.c_str());
- return false;
- }
- EFI_GUID guid;
- guid[0] = static_cast<uint8_t>(int(guidBytes[0]));
- guid[1] = static_cast<uint8_t>(int(guidBytes[0]) >> 8);
- guid[2] = static_cast<uint8_t>(int(guidBytes[0]) >> 16);
- guid[3] = static_cast<uint8_t>(int(guidBytes[0]) >> 24);
+ const auto& guidName = element.key();
+ auto guidBytes = element.value();
+ if (guidBytes.size() != 11)
+ {
+ LogError("Error: GUID array size is incorrect for %s", guidName.c_str());
+ return false;
+ }
+ EFI_GUID guid;
+ guid[0] = static_cast<uint8_t>(int(guidBytes[0]));
+ guid[1] = static_cast<uint8_t>(int(guidBytes[0]) >> 8);
+ guid[2] = static_cast<uint8_t>(int(guidBytes[0]) >> 16);
+ guid[3] = static_cast<uint8_t>(int(guidBytes[0]) >> 24);
- guid[4] = static_cast<uint8_t>(int(guidBytes[1]));
- guid[5] = static_cast<uint8_t>(int(guidBytes[1]) >> 8);
+ guid[4] = static_cast<uint8_t>(int(guidBytes[1]));
+ guid[5] = static_cast<uint8_t>(int(guidBytes[1]) >> 8);
- guid[6] = static_cast<uint8_t>(int(guidBytes[2]));
- guid[7] = static_cast<uint8_t>(int(guidBytes[2]) >> 8);
+ guid[6] = static_cast<uint8_t>(int(guidBytes[2]));
+ guid[7] = static_cast<uint8_t>(int(guidBytes[2]) >> 8);
- for (int i = 8; i < 16; i++)
- guid[i] = static_cast<uint8_t>(int(guidBytes[i-5]));
+ for (int i = 8; i < 16; i++)
+ guid[i] = static_cast<uint8_t>(int(guidBytes[i - 5]));
- // Insert the GUID and its name into the map
- m_user_guids[guid] = guidName;
- }
+ // Insert the GUID and its name into the map
+ m_user_guids[guid] = guidName;
+ }
- return true;
+ return true;
}
void Resolver::initProtocolMapping()
{
- if (!m_protocol.empty())
- return;
- auto fileName = GetBundledEfiPath();
- if (!parseProtocolMapping(fileName))
- LogAlert("Binary Ninja Version Too Low. Please upgrade to a new version.");
+ if (!m_protocol.empty())
+ return;
+ auto fileName = GetBundledEfiPath();
+ if (!parseProtocolMapping(fileName))
+ LogAlert("Binary Ninja Version Too Low. Please upgrade to a new version.");
- fileName = GetUserGuidPath();
- parseUserGuidIfExists(fileName);
+ fileName = GetUserGuidPath();
+ parseUserGuidIfExists(fileName);
}
bool Resolver::setModuleEntry(EFIModuleType fileType)
{
- // Wait until initial analysis is finished
- m_view->UpdateAnalysisAndWait();
+ // Wait until initial analysis is finished
+ m_view->UpdateAnalysisAndWait();
- uint64_t entry = m_view->GetEntryPoint();
- auto entryFunc = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), entry);
- if (!entryFunc)
- {
- LogDebug("Entry func Not found... ");
- return false;
- }
+ uint64_t entry = m_view->GetEntryPoint();
+ auto entryFunc = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), entry);
+ if (!entryFunc)
+ {
+ LogDebug("Entry func Not found... ");
+ return false;
+ }
- // TODO sometimes the parameter at callsite cannot be correctly recognized, #Vector35/binaryninja-api/4529
- // temporary workaround for this issue, adjust callsite types in entry function if it doesn't has parameters
+ // TODO sometimes the parameter at callsite cannot be correctly recognized, #Vector35/binaryninja-api/4529
+ // temporary workaround for this issue, adjust callsite types in entry function if it doesn't has parameters
- // Note: we only adjust the callsite in entry function, this is just a temp fix and it cannot cover all cases
- auto callsites = entryFunc->GetCallSites();
- LogDebug("Checking callsites at 0x%llx", entryFunc->GetStart());
- LogDebug("callsite count : %zu", callsites.size());
- for (auto callsite: entryFunc->GetCallSites())
- {
- auto mlil = entryFunc->GetMediumLevelIL();
- size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), callsite.addr);
- auto instr = mlil->GetInstruction(mlilIdx);
- LogDebug("Checking Callsite at 0x%llx", callsite.addr);
- if(instr.operation == MLIL_CALL || instr.operation == MLIL_TAILCALL)
- {
- auto params = instr.GetParameterExprs();
- if (params.size() == 0)
- {
- // no parameter at call site, check whether it's correctly recognized
- auto constantPtr = instr.GetDestExpr();
- if (constantPtr.operation == MLIL_CONST_PTR)
- {
- auto addr = constantPtr.GetConstant();
- auto funcType = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), addr)->GetType();
- entryFunc->SetUserCallTypeAdjustment(m_view->GetDefaultArchitecture(), callsite.addr, funcType);
- m_view->UpdateAnalysisAndWait();
- }
- else
- LogDebug("Operation not ConstPtr: %d", constantPtr.operation);
- }
- else
- LogDebug("param size not zero");
- }
- }
+ // Note: we only adjust the callsite in entry function, this is just a temp fix and it cannot cover all cases
+ auto callsites = entryFunc->GetCallSites();
+ LogDebug("Checking callsites at 0x%llx", entryFunc->GetStart());
+ LogDebug("callsite count : %zu", callsites.size());
+ for (auto callsite : entryFunc->GetCallSites())
+ {
+ auto mlil = entryFunc->GetMediumLevelIL();
+ size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), callsite.addr);
+ auto instr = mlil->GetInstruction(mlilIdx);
+ LogDebug("Checking Callsite at 0x%llx", callsite.addr);
+ if (instr.operation == MLIL_CALL || instr.operation == MLIL_TAILCALL)
+ {
+ auto params = instr.GetParameterExprs();
+ if (params.size() == 0)
+ {
+ // no parameter at call site, check whether it's correctly recognized
+ auto constantPtr = instr.GetDestExpr();
+ if (constantPtr.operation == MLIL_CONST_PTR)
+ {
+ auto addr = constantPtr.GetConstant();
+ auto funcType = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), addr)->GetType();
+ entryFunc->SetUserCallTypeAdjustment(m_view->GetDefaultArchitecture(), callsite.addr, funcType);
+ m_view->UpdateAnalysisAndWait();
+ }
+ else
+ LogDebug("Operation not ConstPtr: %d", constantPtr.operation);
+ }
+ else
+ LogDebug("param size not zero");
+ }
+ }
- string errors;
- QualifiedNameAndType result;
- bool ok;
+ string errors;
+ QualifiedNameAndType result;
+ bool ok;
- string typeString;
- switch (fileType) {
- case PEI: {
- typeString = "EFI_STATUS _ModuleEntry(EFI_PEI_FILE_HANDLE FileHandle, EFI_PEI_SERVICES **PeiServices)";
- ok = m_view->ParseTypeString(typeString, result, errors, {}, true);
- break;
- }
+ string typeString;
+ switch (fileType)
+ {
+ case PEI:
+ {
+ typeString = "EFI_STATUS _ModuleEntry(EFI_PEI_FILE_HANDLE FileHandle, EFI_PEI_SERVICES **PeiServices)";
+ ok = m_view->ParseTypeString(typeString, result, errors, {}, true);
+ break;
+ }
- case DXE: {
- typeString = "EFI_STATUS _ModuleEntry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable)";
- ok = m_view->ParseTypeString(typeString, result, errors, {}, true);
- break;
- }
+ case DXE:
+ {
+ typeString = "EFI_STATUS _ModuleEntry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable)";
+ ok = m_view->ParseTypeString(typeString, result, errors, {}, true);
+ break;
+ }
- case UNKNOWN: {
- LogAlert("Could not identify EFI module type");
- return false;
- }
- }
+ case UNKNOWN:
+ {
+ LogAlert("Could not identify EFI module type");
+ return false;
+ }
+ }
- if (!ok)
- return false;
+ if (!ok)
+ return false;
- // use UserType so that it would not be overwritten
- entryFunc->SetUserType(result.type);
- m_view->DefineUserSymbol(new Symbol(FunctionSymbol, "_ModuleEntry", entry));
- m_view->UpdateAnalysisAndWait();
+ // use UserType so that it would not be overwritten
+ entryFunc->SetUserType(result.type);
+ m_view->DefineUserSymbol(new Symbol(FunctionSymbol, "_ModuleEntry", entry));
+ m_view->UpdateAnalysisAndWait();
- TypePropagation propagation = TypePropagation(m_view);
- return propagation.propagateFuncParamTypes(entryFunc);
+ TypePropagation propagation = TypePropagation(m_view);
+ return propagation.propagateFuncParamTypes(entryFunc);
}
vector<HighLevelILInstruction> Resolver::HighLevelILExprsAt(Ref<Function> func, Ref<Architecture> arch, uint64_t addr)
{
- auto llil = func->GetLowLevelIL();
- auto mlil = func->GetMediumLevelIL();
- auto hlil = func->GetHighLevelIL();
+ auto llil = func->GetLowLevelIL();
+ auto mlil = func->GetMediumLevelIL();
+ auto hlil = func->GetHighLevelIL();
- size_t llilIdx = func->GetLowLevelILForInstruction(arch, addr);
- size_t llilExprIdx = llil->GetIndexForInstruction(llilIdx);
- auto mlilIdxes = llil->GetMediumLevelILExprIndexes(llilExprIdx);
+ size_t llilIdx = func->GetLowLevelILForInstruction(arch, addr);
+ size_t llilExprIdx = llil->GetIndexForInstruction(llilIdx);
+ auto mlilIdxes = llil->GetMediumLevelILExprIndexes(llilExprIdx);
- vector<HighLevelILInstruction> hlils;
+ vector<HighLevelILInstruction> hlils;
- for (size_t mlilIdx : mlilIdxes) {
- auto hlilIdxes = mlil->GetHighLevelILExprIndexes(mlilIdx);
- for (auto hlilIdx : hlilIdxes) {
- auto hlilExpr = hlil->GetExpr(hlilIdx);
- hlils.push_back(hlilExpr);
- }
- }
- return hlils;
+ for (size_t mlilIdx : mlilIdxes)
+ {
+ auto hlilIdxes = mlil->GetHighLevelILExprIndexes(mlilIdx);
+ for (auto hlilIdx : hlilIdxes)
+ {
+ auto hlilExpr = hlil->GetExpr(hlilIdx);
+ hlils.push_back(hlilExpr);
+ }
+ }
+ return hlils;
}
Ref<Type> Resolver::GetTypeFromViewAndPlatform(string typeName)
{
- QualifiedNameAndType result;
- string errors;
- bool ok = m_view->ParseTypeString(typeName, result, errors);
- if (!ok) {
- // TODO how to retrieve platform types?
- return nullptr;
- }
- return result.type;
+ QualifiedNameAndType result;
+ string errors;
+ bool ok = m_view->ParseTypeString(typeName, result, errors);
+ if (!ok)
+ {
+ // TODO how to retrieve platform types?
+ return nullptr;
+ }
+ return result.type;
}
bool Resolver::resolveGuidInterface(Ref<Function> func, uint64_t addr, int guidPos, int interfacePos)
{
- auto hlils = HighLevelILExprsAt(func, m_view->GetDefaultArchitecture(), addr);
- for (auto hlil : hlils) {
- if (hlil.operation != HLIL_CALL)
- continue;
+ auto hlils = HighLevelILExprsAt(func, m_view->GetDefaultArchitecture(), addr);
+ for (auto hlil : hlils)
+ {
+ if (hlil.operation != HLIL_CALL)
+ continue;
- HighLevelILInstruction instr;
- if (hlil.GetParameterExprs().size() == 1 && hlil.GetParameterExprs()[0].operation == HLIL_CALL)
- instr = hlil.GetParameterExprs()[0];
- else
- instr = hlil;
+ HighLevelILInstruction instr;
+ if (hlil.GetParameterExprs().size() == 1 && hlil.GetParameterExprs()[0].operation == HLIL_CALL)
+ instr = hlil.GetParameterExprs()[0];
+ else
+ instr = hlil;
- auto params = instr.GetParameterExprs();
- if (params.size() <= max(guidPos, interfacePos))
- continue;
+ auto params = instr.GetParameterExprs();
+ if (params.size() <= max(guidPos, interfacePos))
+ continue;
- auto guidAddr = params[guidPos].GetValue();
- EFI_GUID guid;
- if (guidAddr.state == ConstantValue || guidAddr.state == ConstantPointerValue) {
- if (m_view->Read(&guid, guidAddr.value, 16) < 16)
- continue;
- } else if (guidAddr.state == StackFrameOffset) {
- auto mlil = instr.GetMediumLevelIL();
- int64_t offset = 0;
- vector<uint8_t> contentBytes;
- while (offset < 16) {
- auto var = mlil.GetVariableForStackLocation(guidAddr.value + offset);
- if (!func->GetVariableType(var))
- break;
+ auto guidAddr = params[guidPos].GetValue();
+ EFI_GUID guid;
+ if (guidAddr.state == ConstantValue || guidAddr.state == ConstantPointerValue)
+ {
+ if (m_view->Read(&guid, guidAddr.value, 16) < 16)
+ continue;
+ }
+ else if (guidAddr.state == StackFrameOffset)
+ {
+ auto mlil = instr.GetMediumLevelIL();
+ int64_t offset = 0;
+ vector<uint8_t> contentBytes;
+ while (offset < 16)
+ {
+ auto var = mlil.GetVariableForStackLocation(guidAddr.value + offset);
+ if (!func->GetVariableType(var))
+ break;
- auto width = func->GetVariableType(var)->GetWidth();
- if (width == 0 || width > 8)
- break;
+ auto width = func->GetVariableType(var)->GetWidth();
+ if (width == 0 || width > 8)
+ break;
- auto value = mlil.GetStackContents(guidAddr.value + offset, width);
- int64_t content;
- if (value.state == ConstantValue || value.state == ConstantPointerValue)
- content = value.value;
- else
- break;
+ auto value = mlil.GetStackContents(guidAddr.value + offset, width);
+ int64_t content;
+ if (value.state == ConstantValue || value.state == ConstantPointerValue)
+ content = value.value;
+ else
+ break;
- for (auto i = 0; i < width; i++) {
- contentBytes.push_back(static_cast<uint8_t>(content >> (i * 8)));
- }
- }
- if (contentBytes.size() != 16)
- continue;
+ for (auto i = 0; i < width; i++)
+ {
+ contentBytes.push_back(static_cast<uint8_t>(content >> (i * 8)));
+ }
+ }
+ if (contentBytes.size() != 16)
+ continue;
- memcpy(guid.data(), contentBytes.data(), 16);
- } else if (params[guidPos].operation == HLIL_VAR) {
- // want to check whether is a protocol wrapper
- auto ssa = params[guidPos].GetSSAForm();
- HighLevelILInstruction ssaExpr;
- if (ssa.operation != HLIL_VAR_SSA)
- continue;
- if (ssa.GetSSAVariable().version != 0) {
- auto incomming_def = func->GetHighLevelIL()->GetSSAVarDefinition(ssa.GetSSAVariable());
- if (!incomming_def)
- continue;
- auto incomming_def_ssa = func->GetHighLevelIL()->GetSSAForm()->GetExpr(incomming_def);
- if (incomming_def_ssa.operation != HLIL_VAR_INIT_SSA)
- continue;
- if (incomming_def_ssa.GetSourceExpr().operation != HLIL_VAR_SSA)
- continue;
- if (incomming_def_ssa.GetSourceExpr().GetSSAVariable().version != 0)
- continue;
- ssaExpr = incomming_def_ssa.GetSourceExpr();
- } else
- ssaExpr = ssa;
+ memcpy(guid.data(), contentBytes.data(), 16);
+ }
+ else if (params[guidPos].operation == HLIL_VAR)
+ {
+ // want to check whether is a protocol wrapper
+ auto ssa = params[guidPos].GetSSAForm();
+ HighLevelILInstruction ssaExpr;
+ if (ssa.operation != HLIL_VAR_SSA)
+ continue;
+ if (ssa.GetSSAVariable().version != 0)
+ {
+ auto incomming_def = func->GetHighLevelIL()->GetSSAVarDefinition(ssa.GetSSAVariable());
+ if (!incomming_def)
+ continue;
+ auto incomming_def_ssa = func->GetHighLevelIL()->GetSSAForm()->GetExpr(incomming_def);
+ if (incomming_def_ssa.operation != HLIL_VAR_INIT_SSA)
+ continue;
+ if (incomming_def_ssa.GetSourceExpr().operation != HLIL_VAR_SSA)
+ continue;
+ if (incomming_def_ssa.GetSourceExpr().GetSSAVariable().version != 0)
+ continue;
+ ssaExpr = incomming_def_ssa.GetSourceExpr();
+ }
+ else
+ ssaExpr = ssa;
- auto funcParams = func->GetParameterVariables().GetValue();
- bool found = false;
- int incomingGuidIdx;
- for (int i = 0; i < funcParams.size(); i++) {
- if (funcParams[i] == ssaExpr.GetSSAVariable().var) {
- incomingGuidIdx = i;
- found = true;
- break;
- }
- }
- if (!found)
- continue;
+ auto funcParams = func->GetParameterVariables().GetValue();
+ bool found = false;
+ int incomingGuidIdx;
+ for (int i = 0; i < funcParams.size(); i++)
+ {
+ if (funcParams[i] == ssaExpr.GetSSAVariable().var)
+ {
+ incomingGuidIdx = i;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ continue;
- // see if output interface varible is an incoming parameter
- auto interfaceInstrSsa = params[interfacePos].GetSSAForm();
- if (interfaceInstrSsa.operation != HLIL_VAR_SSA)
- continue;
+ // see if output interface varible is an incoming parameter
+ auto interfaceInstrSsa = params[interfacePos].GetSSAForm();
+ if (interfaceInstrSsa.operation != HLIL_VAR_SSA)
+ continue;
- if (interfaceInstrSsa.GetSSAVariable().version != 0) {
- auto incomingDef = func->GetHighLevelIL()->GetSSAForm()->GetSSAVarDefinition(interfaceInstrSsa.GetSSAVariable());
- auto defExpr = func->GetHighLevelIL()->GetSSAForm()->GetExpr(incomingDef);
- if (defExpr.operation != HLIL_VAR_INIT_SSA)
- continue;
- if (defExpr.GetSourceExpr().operation != HLIL_VAR_SSA)
- continue;
- if (defExpr.GetSourceExpr().GetSSAVariable().version != 0)
- continue;
- interfaceInstrSsa = defExpr.GetSourceExpr();
- }
- found = false;
- int incomingInstrIdx;
- for (int i = 0; i < funcParams.size(); i++) {
- if (funcParams[i] == interfaceInstrSsa.GetSSAVariable().var) {
- incomingInstrIdx = i;
- found = true;
- break;
- }
- }
- if (!found)
- continue;
+ if (interfaceInstrSsa.GetSSAVariable().version != 0)
+ {
+ auto incomingDef =
+ func->GetHighLevelIL()->GetSSAForm()->GetSSAVarDefinition(interfaceInstrSsa.GetSSAVariable());
+ auto defExpr = func->GetHighLevelIL()->GetSSAForm()->GetExpr(incomingDef);
+ if (defExpr.operation != HLIL_VAR_INIT_SSA)
+ continue;
+ if (defExpr.GetSourceExpr().operation != HLIL_VAR_SSA)
+ continue;
+ if (defExpr.GetSourceExpr().GetSSAVariable().version != 0)
+ continue;
+ interfaceInstrSsa = defExpr.GetSourceExpr();
+ }
+ found = false;
+ int incomingInstrIdx;
+ for (int i = 0; i < funcParams.size(); i++)
+ {
+ if (funcParams[i] == interfaceInstrSsa.GetSSAVariable().var)
+ {
+ incomingInstrIdx = i;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ continue;
- LogInfo("Found EFI Protocol wrapper at 0x%llx, checking reference to this function", addr);
+ LogInfo("Found EFI Protocol wrapper at 0x%llx, checking reference to this function", addr);
- auto refs = m_view->GetCodeReferences(func->GetStart());
- for (auto &ref : refs)
- resolveGuidInterface(ref.func, ref.addr, incomingGuidIdx, incomingInstrIdx);
- continue;
- }
+ auto refs = m_view->GetCodeReferences(func->GetStart());
+ for (auto& ref : refs)
+ resolveGuidInterface(ref.func, ref.addr, incomingGuidIdx, incomingInstrIdx);
+ continue;
+ }
- if (guid.empty())
- continue;
+ if (guid.empty())
+ continue;
- auto names = lookupGuid(guid);
- string protocol_name = names.first;
- string guidName = names.second;
+ auto names = lookupGuid(guid);
+ string protocol_name = names.first;
+ string guidName = names.second;
- if (protocol_name.empty()) {
- // protocol name is empty
- if (!guidName.empty()) {
- // user added guid, check whether the user has added the protocol type
- string possible_protocol_type = guidName;
- size_t pos = possible_protocol_type.rfind("_GUID");
- if (pos != string::npos)
- possible_protocol_type.erase(pos, 5);
+ if (protocol_name.empty())
+ {
+ // protocol name is empty
+ if (!guidName.empty())
+ {
+ // user added guid, check whether the user has added the protocol type
+ string possible_protocol_type = guidName;
+ size_t pos = possible_protocol_type.rfind("_GUID");
+ if (pos != string::npos)
+ possible_protocol_type.erase(pos, 5);
- // check whether `possible_protocol_type` is in bv.types
- QualifiedNameAndType result;
- string errors;
- bool ok = m_view->ParseTypeString(possible_protocol_type, result, errors);
- if (ok)
- protocol_name = possible_protocol_type;
- } else {
- // use UnknownProtocol as defult
- LogWarn("Unknown EFI Protocol referenced at 0x%llx", addr);
- guidName = nonConflictingName("UnknownProtocolGuid");
- }
- }
+ // check whether `possible_protocol_type` is in bv.types
+ QualifiedNameAndType result;
+ string errors;
+ bool ok = m_view->ParseTypeString(possible_protocol_type, result, errors);
+ if (ok)
+ protocol_name = possible_protocol_type;
+ }
+ else
+ {
+ // use UnknownProtocol as defult
+ LogWarn("Unknown EFI Protocol referenced at 0x%llx", addr);
+ guidName = nonConflictingName("UnknownProtocolGuid");
+ }
+ }
- // now we just need to rename the GUID and apply the protocol type
- auto sym = m_view->GetSymbolByAddress(guidAddr.value);
- auto guidVarName = guidName;
- if (sym)
- guidVarName = sym->GetRawName();
+ // now we just need to rename the GUID and apply the protocol type
+ auto sym = m_view->GetSymbolByAddress(guidAddr.value);
+ auto guidVarName = guidName;
+ if (sym)
+ guidVarName = sym->GetRawName();
- QualifiedNameAndType result;
- string errors;
- bool ok = m_view->ParseTypeString("EFI_GUID", result, errors);
- if (!ok)
- return false;
- m_view->DefineDataVariable(guidAddr.value, result.type);
- m_view->DefineUserSymbol(new Symbol(DataSymbol, guidVarName, guidAddr.value));
+ QualifiedNameAndType result;
+ string errors;
+ bool ok = m_view->ParseTypeString("EFI_GUID", result, errors);
+ if (!ok)
+ return false;
+ m_view->DefineDataVariable(guidAddr.value, result.type);
+ m_view->DefineUserSymbol(new Symbol(DataSymbol, guidVarName, guidAddr.value));
- if (protocol_name.empty()) {
- LogWarn("Found unknown protocol at 0x%llx", addr);
- protocol_name = "VOID*";
- }
+ if (protocol_name.empty())
+ {
+ LogWarn("Found unknown protocol at 0x%llx", addr);
+ protocol_name = "VOID*";
+ }
- auto protocolType = GetTypeFromViewAndPlatform(protocol_name);
- if (!protocolType)
- continue;
- protocolType = Type::PointerType(m_view->GetDefaultArchitecture(), protocolType);
- auto interfaceParam = params[interfacePos];
- if (interfaceParam.operation == HLIL_ADDRESS_OF) {
- interfaceParam = interfaceParam.GetSourceExpr();
- if (interfaceParam.operation == HLIL_VAR) {
- string interfaceName = guidName;
- if (guidName.substr(0, 19) == "UnknownProtocolGuid") {
- interfaceName.replace(0, 19, "UnknownProtocolInterface");
- interfaceName = nonConflictingLocalName(func, interfaceName);
- } else {
- interfaceName = nonConflictingLocalName(func, GetVarNameForTypeStr(guidName));
- }
- func->CreateUserVariable(interfaceParam.GetVariable(),
- protocolType,
- interfaceName);
- }
- } else if (interfaceParam.operation == HLIL_CONST_PTR) {
- auto dataVarAddr = interfaceParam.GetValue().value;
- m_view->DefineDataVariable(dataVarAddr, protocolType);
- string interfaceName = guidName;
- if (interfaceName.find("GUID") != interfaceName.npos) {
- interfaceName.replace(interfaceName.find("GUID"), 4, "INTERFACE");
- interfaceName = GetVarNameForTypeStr(interfaceName);
- } else if (guidName.substr(0, 19) == "UnknownProtocolGuid") {
- interfaceName.replace(15, 4, "Interface");
- }
- m_view->DefineUserSymbol(new Symbol(DataSymbol, interfaceName, dataVarAddr));
- }
- m_view->UpdateAnalysisAndWait();
- }
+ auto protocolType = GetTypeFromViewAndPlatform(protocol_name);
+ if (!protocolType)
+ continue;
+ protocolType = Type::PointerType(m_view->GetDefaultArchitecture(), protocolType);
+ auto interfaceParam = params[interfacePos];
- return true;
+ // TODO we need to check whether it is an aliased var, or it can probably overwrite the other interfaces
+
+ if (interfaceParam.operation == HLIL_ADDRESS_OF)
+ {
+ interfaceParam = interfaceParam.GetSourceExpr();
+ if (interfaceParam.operation == HLIL_VAR)
+ {
+ string interfaceName = guidName;
+ if (guidName.substr(0, 19) == "UnknownProtocolGuid")
+ {
+ interfaceName.replace(0, 19, "UnknownProtocolInterface");
+ interfaceName = nonConflictingLocalName(func, interfaceName);
+ }
+ else
+ {
+ interfaceName = nonConflictingLocalName(func, GetVarNameForTypeStr(guidName));
+ }
+ func->CreateUserVariable(interfaceParam.GetVariable(), protocolType, interfaceName);
+ }
+ }
+ else if (interfaceParam.operation == HLIL_CONST_PTR)
+ {
+ auto dataVarAddr = interfaceParam.GetValue().value;
+ m_view->DefineDataVariable(dataVarAddr, protocolType);
+ string interfaceName = guidName;
+ if (interfaceName.find("GUID") != interfaceName.npos)
+ {
+ interfaceName = interfaceName.replace(interfaceName.find("GUID"), 4, "INTERFACE");
+ interfaceName = GetVarNameForTypeStr(interfaceName);
+ }
+ else if (guidName.substr(0, 19) == "UnknownProtocolGuid")
+ {
+ interfaceName.replace(15, 4, "Interface");
+ }
+ m_view->DefineUserSymbol(new Symbol(DataSymbol, interfaceName, dataVarAddr));
+ }
+ m_view->UpdateAnalysisAndWait();
+ }
+
+ return true;
}
-bool Resolver::defineTypeAtCallsite(Ref<Function> func, uint64_t addr, const string typeName, int paramIdx, bool followFields)
+bool Resolver::defineTypeAtCallsite(
+ Ref<Function> func, uint64_t addr, const string typeName, int paramIdx, bool followFields)
{
- auto mlil = func->GetMediumLevelIL();
- size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), addr);
- auto instr = mlil->GetInstruction(mlilIdx);
+ auto mlil = func->GetMediumLevelIL();
+ size_t mlilIdx = mlil->GetInstructionStart(m_view->GetDefaultArchitecture(), addr);
+ auto instr = mlil->GetInstruction(mlilIdx);
- auto params = instr.GetParameterExprs();
- if (params.size() < paramIdx + 1)
- return false;
+ auto params = instr.GetParameterExprs();
+ if (params.size() < paramIdx + 1)
+ return false;
- auto param = params[paramIdx];
- if (param.operation != MLIL_CONST_PTR)
- return false;
+ auto param = params[paramIdx];
+ if (param.operation != MLIL_CONST_PTR)
+ return false;
- uint64_t varAddr = param.GetConstant();
- DataVariable datavar;
- auto ok = m_view->GetDataVariableAtAddress(varAddr, datavar);
- if (ok) {
- string datavarTypeName = datavar.type.GetValue()->GetTypeName().GetString();
- if (datavarTypeName.find(typeName) != datavarTypeName.npos)
- // the variable already has this type, return
- return false;
- }
+ uint64_t varAddr = param.GetConstant();
+ DataVariable datavar;
+ auto ok = m_view->GetDataVariableAtAddress(varAddr, datavar);
+ if (ok)
+ {
+ string datavarTypeName = datavar.type.GetValue()->GetTypeName().GetString();
+ if (datavarTypeName.find(typeName) != datavarTypeName.npos)
+ // the variable already has this type, return
+ return false;
+ }
- // Now we want to define the type at varAddr
+ // Now we want to define the type at varAddr
- if (typeName == "EFI_GUID") {
- // If it's GUID, we want to define it with name
- defineAndLookupGuid(varAddr);
- // defining a GUID should never fail. Also it can not have fields
- return true;
- }
+ if (typeName == "EFI_GUID")
+ {
+ // If it's GUID, we want to define it with name
+ defineAndLookupGuid(varAddr);
+ // defining a GUID should never fail. Also it can not have fields
+ return true;
+ }
- QualifiedNameAndType result;
- string errors;
- ok = m_view->ParseTypeString(typeName, result, errors);
- if (!ok) {
- LogError("Cannot parse type %s when trying to define type at 0x%llx", typeName.c_str(), addr);
- return false;
- }
+ QualifiedNameAndType result;
+ string errors;
+ ok = m_view->ParseTypeString(typeName, result, errors);
+ if (!ok)
+ {
+ LogError("Cannot parse type %s when trying to define type at 0x%llx", typeName.c_str(), addr);
+ return false;
+ }
- m_view->DefineDataVariable(varAddr, result.type);
+ m_view->DefineDataVariable(varAddr, result.type);
- if (!followFields)
- return true;
+ if (!followFields)
+ return true;
- // We want to define the Guid field and the Notify field, which are both pointers
- DataVariable structVar;
- ok = m_view->GetDataVariableAtAddress(varAddr, structVar);
- if (!ok)
- return false;
+ // We want to define the Guid field and the Notify field, which are both pointers
+ DataVariable structVar;
+ ok = m_view->GetDataVariableAtAddress(varAddr, structVar);
+ if (!ok)
+ return false;
- if (!structVar.type.GetValue()->IsNamedTypeRefer())
- return false;
+ if (!structVar.type.GetValue()->IsNamedTypeRefer())
+ return false;
- auto structTypeId = structVar.type.GetValue()->GetNamedTypeReference()->GetTypeId();
- auto structStructureType = m_view->GetTypeById(structTypeId)->GetStructure();
+ auto structTypeId = structVar.type.GetValue()->GetNamedTypeReference()->GetTypeId();
+ auto structStructureType = m_view->GetTypeById(structTypeId)->GetStructure();
- if (!structStructureType)
- return false;
- auto members = structStructureType->GetMembers();
+ if (!structStructureType)
+ return false;
+ auto members = structStructureType->GetMembers();
- // we want to keep this name for renaming NotifyFunction
- string guidName;
- for (auto member : members) {
- auto memberOffset = member.offset;
- auto memberType = member.type.GetValue();
- auto memberName = member.name;
+ // we want to keep this name for renaming NotifyFunction
+ string guidName;
+ for (auto member : members)
+ {
+ auto memberOffset = member.offset;
+ auto memberType = member.type.GetValue();
+ auto memberName = member.name;
- // we only want to define pointers
- if (!memberType->IsPointer() && !(memberType->IsNamedTypeRefer() && memberName == "Notify"))
- continue;
+ // we only want to define pointers
+ if (!memberType->IsPointer() && !(memberType->IsNamedTypeRefer() && memberName == "Notify"))
+ continue;
- if (memberName == "Guid") {
- uint64_t guidAddr = 0;
- m_view->Read(&guidAddr, varAddr + memberOffset, m_view->GetAddressSize());
- auto name = defineAndLookupGuid(guidAddr);
- guidName = name.second;
- } else if (memberName == "Notify") {
- // Notify has the type EFI_NOTIFY_ENTRY_POINT
- // which is a NamedTypeRefer
- uint64_t funcAddr;
- m_view->Read(&funcAddr, varAddr + memberOffset, m_view->GetAddressSize());
- auto notifyFunc = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), funcAddr);
- if (!notifyFunc)
- continue;
+ if (memberName == "Guid")
+ {
+ uint64_t guidAddr = 0;
+ m_view->Read(&guidAddr, varAddr + memberOffset, m_view->GetAddressSize());
+ auto name = defineAndLookupGuid(guidAddr);
+ guidName = name.second;
+ }
+ else if (memberName == "Notify")
+ {
+ // Notify has the type EFI_NOTIFY_ENTRY_POINT
+ // which is a NamedTypeRefer
+ uint64_t funcAddr;
+ m_view->Read(&funcAddr, varAddr + memberOffset, m_view->GetAddressSize());
+ auto notifyFunc = m_view->GetAnalysisFunction(m_view->GetDefaultPlatform(), funcAddr);
+ if (!notifyFunc)
+ continue;
- string funcName = guidName;
- if (guidName.empty())
- funcName = nonConflictingName("UnknownNotify");
- else
- funcName = "Notify" + funcName.replace(funcName.find("GUID"), 4, "");
+ string funcName = guidName;
+ if (guidName.empty())
+ funcName = nonConflictingName("UnknownNotify");
+ else
+ funcName = "Notify" + funcName.replace(funcName.find("GUID"), 4, "");
- string notifyTypeStr = "EFI_STATUS Notify(EFI_PEI_SERVICES **PeiServices, EFI_PEI_NOTIFY_DESCRIPTOR* NotifyDescriptor, VOID* Ppi)";
- ok = m_view->ParseTypeString(notifyTypeStr, result, errors);
- notifyFunc->SetUserType(result.type);
- m_view->DefineUserSymbol(new Symbol(FunctionSymbol, funcName, funcAddr));
- m_view->UpdateAnalysisAndWait();
+ string notifyTypeStr =
+ "EFI_STATUS Notify(EFI_PEI_SERVICES **PeiServices, EFI_PEI_NOTIFY_DESCRIPTOR* NotifyDescriptor, VOID* "
+ "Ppi)";
+ ok = m_view->ParseTypeString(notifyTypeStr, result, errors);
+ notifyFunc->SetUserType(result.type);
+ m_view->DefineUserSymbol(new Symbol(FunctionSymbol, funcName, funcAddr));
+ m_view->UpdateAnalysisAndWait();
- TypePropagation propagator(m_view);
- propagator.propagateFuncParamTypes(notifyFunc);
- }
- }
- return true;
+ TypePropagation propagator(m_view);
+ propagator.propagateFuncParamTypes(notifyFunc);
+ }
+ }
+ return true;
}
Resolver::Resolver(Ref<BinaryView> view, Ref<BackgroundTask> task)
{
- m_view = view;
- m_task = task;
- m_width = m_view->GetAddressSize();
+ m_view = view;
+ m_task = task;
+ m_width = m_view->GetAddressSize();
}
pair<string, string> Resolver::lookupGuid(EFI_GUID guidBytes)
{
- auto it = m_protocol.find(guidBytes);
- if (it != m_protocol.end())
- return it->second;
+ auto it = m_protocol.find(guidBytes);
+ if (it != m_protocol.end())
+ return it->second;
- auto user_it = m_user_guids.find(guidBytes);
- if (user_it != m_user_guids.end())
- return make_pair(string(), user_it->second);
+ auto user_it = m_user_guids.find(guidBytes);
+ if (user_it != m_user_guids.end())
+ return make_pair(string(), user_it->second);
- return {};
+ return {};
}
pair<string, string> Resolver::defineAndLookupGuid(uint64_t addr)
{
- EFI_GUID guidBytes;
- try {
- auto readSize = m_view->Read(&guidBytes, addr, 16);
- if (readSize != 16)
- return make_pair(string(), string());
- } catch (ReadException) {
- LogError("Read GUID failed at 0x%llx", addr);
- return make_pair(string(), string());
- }
- auto namePair = lookupGuid(guidBytes);
- string protocolName = namePair.first;
- string guidName = namePair.second;
+ EFI_GUID guidBytes;
+ try
+ {
+ auto readSize = m_view->Read(&guidBytes, addr, 16);
+ if (readSize != 16)
+ return make_pair(string(), string());
+ }
+ catch (ReadException)
+ {
+ LogError("Read GUID failed at 0x%llx", addr);
+ return make_pair(string(), string());
+ }
+ auto namePair = lookupGuid(guidBytes);
+ string protocolName = namePair.first;
+ string guidName = namePair.second;
- QualifiedNameAndType result;
- string errors;
- // must use ParseTypeString,
- // m_view->GetTypeByName() doesn't return a NamedTypeReference and the DataRenderer doesn't applied
- bool ok = m_view->ParseTypeString("EFI_GUID", result, errors);
- if (!ok)
- return make_pair(string(""), string(""));
- m_view->DefineDataVariable(addr, result.type);
- if (guidName.empty()) {
- m_view->DefineUserSymbol(new Symbol(DataSymbol, nonConflictingName("UnknownGuid"), addr));
- LogDebug("Found UnknownGuid at 0x%llx", addr);
- } else {
- m_view->DefineUserSymbol(new Symbol(DataSymbol, guidName, addr));
- LogDebug("Define %s at 0x%llx", guidName.c_str(), addr);
- }
+ QualifiedNameAndType result;
+ string errors;
+ // must use ParseTypeString,
+ // m_view->GetTypeByName() doesn't return a NamedTypeReference and the DataRenderer doesn't applied
+ bool ok = m_view->ParseTypeString("EFI_GUID", result, errors);
+ if (!ok)
+ return make_pair(string(""), string(""));
+ m_view->DefineDataVariable(addr, result.type);
+ if (guidName.empty())
+ {
+ m_view->DefineUserSymbol(new Symbol(DataSymbol, nonConflictingName("UnknownGuid"), addr));
+ LogDebug("Found UnknownGuid at 0x%llx", addr);
+ }
+ else
+ {
+ m_view->DefineUserSymbol(new Symbol(DataSymbol, guidName, addr));
+ LogDebug("Define %s at 0x%llx", guidName.c_str(), addr);
+ }
- return namePair;
+ return namePair;
}
diff --git a/platform/efi/efi_resolver/src/TypePropagation.cpp b/platform/efi/efi_resolver/src/TypePropagation.cpp
index 4b4fac6c..ff0d43b9 100644
--- a/platform/efi/efi_resolver/src/TypePropagation.cpp
+++ b/platform/efi/efi_resolver/src/TypePropagation.cpp
@@ -3,181 +3,196 @@
TypePropagation::TypePropagation(BinaryView* view)
{
- m_view = view;
- m_queue.clear();
- m_platform = view->GetDefaultPlatform();
+ m_view = view;
+ m_queue.clear();
+ m_platform = view->GetDefaultPlatform();
}
-const std::map<std::string, std::string> defaultName = {
- { "EFI_SYSTEM_TABLE", "gST" },
- { "EFI_BOOT_SERVICES", "gBS" },
- { "EFI_RUNTIME_SERVICES", "gRT" },
- { "EFI_MM_SYSTEM_TABLE", "gMmst" },
- { "EFI_SMM_SYSTEM_TABLE2", "gSmmst" },
- { "EFI_HANDLE", "gHandle" }
-};
+const std::map<std::string, std::string> defaultName = {{"EFI_SYSTEM_TABLE", "gST"}, {"EFI_BOOT_SERVICES", "gBS"},
+ {"EFI_RUNTIME_SERVICES", "gRT"}, {"EFI_MM_SYSTEM_TABLE", "gMmst"}, {"EFI_SMM_SYSTEM_TABLE2", "gSmmst"},
+ {"EFI_HANDLE", "gHandle"}};
bool TypePropagation::propagateFuncParamTypes(Function* func)
{
- m_queue.push_back(func->GetStart());
+ m_queue.push_back(func->GetStart());
- LogDebug("Start Type propagation from 0x%llx", func->GetStart());
+ LogDebug("Start Type propagation from 0x%llx", func->GetStart());
- while (!m_queue.empty()) {
- uint64_t addr = m_queue.front();
- m_queue.pop_front();
+ while (!m_queue.empty())
+ {
+ uint64_t addr = m_queue.front();
+ m_queue.pop_front();
- Ref<Function> target_func = m_view->GetAnalysisFunction(m_platform, addr);
- auto params = target_func->GetType()->GetParameters();
- bool update = false;
+ Ref<Function> target_func = m_view->GetAnalysisFunction(m_platform, addr);
+ auto params = target_func->GetType()->GetParameters();
+ bool update = false;
- auto param_vars = target_func->GetParameterVariables().GetValue();
- for (auto var : param_vars) {
- bool propagate = false;
- auto var_type = target_func->GetVariableType(var).GetValue();
+ auto param_vars = target_func->GetParameterVariables().GetValue();
+ for (auto var : param_vars)
+ {
+ bool propagate = false;
+ auto var_type = target_func->GetVariableType(var).GetValue();
- if (var_type->IsPointer()) {
- Ref<Type> target_type = var_type->GetChildType().GetValue();
- if (target_type->IsPointer() || target_type->IsNamedTypeRefer())
- propagate = true;
- } else if (var_type->IsNamedTypeRefer()) {
- Ref<Type> target_type = m_view->GetTypeById(var_type->GetNamedTypeReference()->GetTypeId());
- if (target_type->IsPointer())
- propagate = true;
- }
- if (!propagate)
- continue;
+ if (var_type->IsPointer())
+ {
+ Ref<Type> target_type = var_type->GetChildType().GetValue();
+ if (target_type->IsPointer() || target_type->IsNamedTypeRefer())
+ propagate = true;
+ }
+ else if (var_type->IsNamedTypeRefer())
+ {
+ Ref<Type> target_type = m_view->GetTypeById(var_type->GetNamedTypeReference()->GetTypeId());
+ if (target_type->IsPointer())
+ propagate = true;
+ }
+ if (!propagate)
+ continue;
- // Check whether the param is an aliased var. If it's an aliased var, it may not be directly used in the function
- Ref<HighLevelILFunction> hlil_func_ssa = target_func->GetHighLevelIL()->GetSSAForm();
- std::set<Variable> aliased_vars = target_func->GetHighLevelILAliasedVariables();
+ // Check whether the param is an aliased var. If it's an aliased var, it may not be directly used in the
+ // function
+ Ref<HighLevelILFunction> hlil_func_ssa = target_func->GetHighLevelIL()->GetSSAForm();
+ std::set<Variable> aliased_vars = target_func->GetHighLevelILAliasedVariables();
- auto it = aliased_vars.find(var);
- if (it == aliased_vars.end()) {
- // not an aliaed var, use version 0
- update |= propagateFuncParamTypes(target_func, SSAVariable(var, 0));
- } else {
- // this param is an aliased var, get the ssa_var
- auto uses = target_func->GetHighLevelIL()->GetVariableUses(var);
- for (auto use : uses) {
- auto hlil_instr = target_func->GetHighLevelIL()->GetExpr(use);
- hlil_instr = hlil_instr.GetParent();
- if (hlil_instr.operation != HLIL_VAR_INIT)
- continue;
- SSAVariable ssa_var = hlil_instr.GetSSAForm().GetDestSSAVariable();
- update |= propagateFuncParamTypes(target_func, ssa_var);
- }
- }
- }
+ auto it = aliased_vars.find(var);
+ if (it == aliased_vars.end())
+ {
+ // not an aliaed var, use version 0
+ update |= propagateFuncParamTypes(target_func, SSAVariable(var, 0));
+ }
+ else
+ {
+ // this param is an aliased var, get the ssa_var
+ auto uses = target_func->GetHighLevelIL()->GetVariableUses(var);
+ for (auto use : uses)
+ {
+ auto hlil_instr = target_func->GetHighLevelIL()->GetExpr(use);
+ hlil_instr = hlil_instr.GetParent();
+ if (hlil_instr.operation != HLIL_VAR_INIT)
+ continue;
+ SSAVariable ssa_var = hlil_instr.GetSSAForm().GetDestSSAVariable();
+ update |= propagateFuncParamTypes(target_func, ssa_var);
+ }
+ }
+ }
- if (update)
- m_view->UpdateAnalysisAndWait();
- }
- return true;
+ if (update)
+ m_view->UpdateAnalysisAndWait();
+ }
+ return true;
}
bool TypePropagation::propagateFuncParamTypes(Function* func, SSAVariable ssa_var)
{
- bool update = false;
- auto mlil_func_ssa = func->GetMediumLevelIL()->GetSSAForm();
- auto uses = mlil_func_ssa->GetSSAVarUses(ssa_var);
- for (auto use : uses) {
- auto instr = mlil_func_ssa->GetInstruction(use);
- switch (instr.operation) {
- case MLIL_CALL_SSA:
- case MLIL_TAILCALL_SSA: {
- // propagate variable type to sub function
- auto dest = instr.GetDestExpr();
- if (!dest.GetValue().IsConstant())
- continue;
- Ref<Function> subfunc = m_view->GetAnalysisFunction(m_platform, dest.GetValue().value);
+ bool update = false;
+ auto mlil_func_ssa = func->GetMediumLevelIL()->GetSSAForm();
+ auto uses = mlil_func_ssa->GetSSAVarUses(ssa_var);
+ for (auto use : uses)
+ {
+ auto instr = mlil_func_ssa->GetInstruction(use);
+ switch (instr.operation)
+ {
+ case MLIL_CALL_SSA:
+ case MLIL_TAILCALL_SSA:
+ {
+ // propagate variable type to sub function
+ auto dest = instr.GetDestExpr();
+ if (!dest.GetValue().IsConstant())
+ continue;
+ Ref<Function> subfunc = m_view->GetAnalysisFunction(m_platform, dest.GetValue().value);
- if (!subfunc)
- continue;
+ if (!subfunc)
+ continue;
- auto subfunc_type = subfunc->GetType();
- auto subfunc_params = subfunc->GetType()->GetParameters();
+ auto subfunc_type = subfunc->GetType();
+ auto subfunc_params = subfunc->GetType()->GetParameters();
- auto instr_params = instr.GetParameterExprs();
- for (int i = 0; i < instr_params.size(); i++) {
- if (instr_params[i].operation != MLIL_VAR_SSA)
- continue;
- if (instr_params[i].GetSourceSSAVariable() != ssa_var)
- continue;
- if (i >= subfunc_params.size())
- break;
- auto ssa_var_type = func->GetVariableType(ssa_var.var).GetValue();
- auto typeName = GetOriginalTypeName(ssa_var_type);
+ auto instr_params = instr.GetParameterExprs();
+ for (int i = 0; i < instr_params.size(); i++)
+ {
+ if (instr_params[i].operation != MLIL_VAR_SSA)
+ continue;
+ if (instr_params[i].GetSourceSSAVariable() != ssa_var)
+ continue;
+ if (i >= subfunc_params.size())
+ break;
+ auto ssa_var_type = func->GetVariableType(ssa_var.var).GetValue();
+ auto typeName = GetOriginalTypeName(ssa_var_type);
- auto changeFuncType = [](BinaryView* bv, Ref<Type> funcType, std::string paramName, Ref<Type> paramType, int paramIdx) {
- auto newFuncType = TypeBuilder(funcType);
- auto adjustedParams = newFuncType.GetParameters();
- adjustedParams.at(paramIdx) = FunctionParameter(paramName, paramType);
- newFuncType.SetParameters(adjustedParams);
- return newFuncType.Finalize();
- };
+ auto changeFuncType =
+ [](BinaryView* bv, Ref<Type> funcType, std::string paramName, Ref<Type> paramType, int paramIdx) {
+ auto newFuncType = TypeBuilder(funcType);
+ auto adjustedParams = newFuncType.GetParameters();
+ adjustedParams.at(paramIdx) = FunctionParameter(paramName, paramType);
+ newFuncType.SetParameters(adjustedParams);
+ return newFuncType.Finalize();
+ };
- subfunc->SetUserType(changeFuncType(m_view, subfunc_type, GetVarNameForTypeStr(typeName), ssa_var_type, i));
- m_view->UpdateAnalysisAndWait();
+ subfunc->SetUserType(
+ changeFuncType(m_view, subfunc_type, GetVarNameForTypeStr(typeName), ssa_var_type, i));
+ m_view->UpdateAnalysisAndWait();
- if (std::find(m_queue.begin(), m_queue.end(), subfunc->GetStart()) == m_queue.end())
- m_queue.push_back(subfunc->GetStart());
- update = true;
- break;
- }
- break;
- }
+ if (std::find(m_queue.begin(), m_queue.end(), subfunc->GetStart()) == m_queue.end())
+ m_queue.push_back(subfunc->GetStart());
+ update = true;
+ break;
+ }
+ break;
+ }
- case MLIL_STORE_SSA: {
- auto target = instr.GetDestExpr<MLIL_STORE_SSA>();
- if (!target.GetValue().IsConstant())
- continue;
- auto constant = target.GetValue().value;
- auto ssa_var_type = func->GetVariableType(ssa_var.var).GetValue();
- auto typeName = GetOriginalTypeName(ssa_var_type);
+ case MLIL_STORE_SSA:
+ {
+ auto target = instr.GetDestExpr<MLIL_STORE_SSA>();
+ if (!target.GetValue().IsConstant())
+ continue;
+ auto constant = target.GetValue().value;
+ auto ssa_var_type = func->GetVariableType(ssa_var.var).GetValue();
+ auto typeName = GetOriginalTypeName(ssa_var_type);
- auto it = defaultName.find(typeName);
- if (it != defaultName.end())
- typeName = it->second;
+ auto it = defaultName.find(typeName);
+ if (it != defaultName.end())
+ typeName = it->second;
- m_view->DefineDataVariable(constant, ssa_var_type);
- m_view->DefineUserSymbol(new Symbol(DataSymbol, typeName, constant));
+ m_view->DefineDataVariable(constant, ssa_var_type);
+ m_view->DefineUserSymbol(new Symbol(DataSymbol, typeName, constant));
- update = true;
- break;
- }
+ update = true;
+ break;
+ }
- case MLIL_SET_VAR_SSA: {
- auto src = instr.GetSourceExpr<MLIL_SET_VAR_SSA>();
- auto dest = instr.GetDestSSAVariable<MLIL_SET_VAR_SSA>();
+ case MLIL_SET_VAR_SSA:
+ {
+ auto src = instr.GetSourceExpr<MLIL_SET_VAR_SSA>();
+ auto dest = instr.GetDestSSAVariable<MLIL_SET_VAR_SSA>();
- auto dest_type = func->GetVariableType(dest.var);
- Confidence<Ref<Type>> src_type;
- switch (src.operation) {
- case MLIL_VAR_SSA:
- src_type = func->GetVariableType(src.GetSourceSSAVariable().var);
- break;
+ auto dest_type = func->GetVariableType(dest.var);
+ Confidence<Ref<Type>> src_type;
+ switch (src.operation)
+ {
+ case MLIL_VAR_SSA:
+ src_type = func->GetVariableType(src.GetSourceSSAVariable().var);
+ break;
- case MLIL_LOAD_SSA:
- case MLIL_LOAD_STRUCT_SSA:
- src_type = src.GetType();
- break;
+ case MLIL_LOAD_SSA:
+ case MLIL_LOAD_STRUCT_SSA:
+ src_type = src.GetType();
+ break;
- default:
- continue;
- }
+ default:
+ continue;
+ }
- if (src_type.GetValue() && src_type.GetValue() != dest_type.GetValue()) {
- func->CreateUserVariable(dest.var, src_type, func->GetVariableName(dest.var));
- update |= propagateFuncParamTypes(func, SSAVariable(dest.var, dest.version));
- }
- break;
- }
+ if (src_type.GetValue() && src_type.GetValue() != dest_type.GetValue())
+ {
+ func->CreateUserVariable(dest.var, src_type, func->GetVariableName(dest.var));
+ update |= propagateFuncParamTypes(func, SSAVariable(dest.var, dest.version));
+ }
+ break;
+ }
- default:
- LogInfo("Not handled case during type propagation. At %llx: %d", instr.address, instr.operation);
- break;
- }
- }
- return update;
+ default:
+ LogInfo("Not handled case during type propagation. At %llx: %d", instr.address, instr.operation);
+ break;
+ }
+ }
+ return update;
}