Skip to content

Commit 5953d08

Browse files
committed
Add support for multiple global pointer registers
1 parent 68215ea commit 5953d08

12 files changed

Lines changed: 431 additions & 79 deletions

binaryninjaapi.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8249,10 +8249,20 @@ namespace BinaryNinja {
82498249
Ref<ExternalLocation> GetExternalLocation(Ref<Symbol> sourceSymbol);
82508250
std::vector<Ref<ExternalLocation>> GetExternalLocations();
82518251

8252+
/*! \deprecated Use GetGlobalPointerValues instead. */
82528253
Confidence<RegisterValue> GetGlobalPointerValue() const;
8254+
std::vector<std::pair<uint32_t, Confidence<RegisterValue>>> GetGlobalPointerValues() const;
8255+
std::vector<std::pair<uint32_t, Confidence<RegisterValue>>> GetDefaultGlobalPointerValues() const;
8256+
std::vector<std::pair<uint32_t, Confidence<RegisterValue>>> GetUserGlobalPointerValues() const;
8257+
/*! \deprecated Use UserGlobalPointerValuesSet instead. */
82538258
bool UserGlobalPointerValueSet() const;
8259+
bool UserGlobalPointerValuesSet() const;
8260+
/*! \deprecated Use ClearUserGlobalPointerValues instead. */
82548261
void ClearUserGlobalPointerValue();
8262+
void ClearUserGlobalPointerValues();
8263+
/*! \deprecated Use SetUserGlobalPointerValues instead. */
82558264
void SetUserGlobalPointerValue(const Confidence<RegisterValue>& value);
8265+
void SetUserGlobalPointerValues(const std::vector<std::pair<uint32_t, Confidence<RegisterValue>>>& values);
82568266

82578267
std::optional<std::pair<std::string, BNStringType>> StringifyUnicodeData(Architecture* arch, const DataBuffer& buffer, bool nullTerminates = true, bool allowShortStrings = false);
82588268

@@ -13650,7 +13660,9 @@ namespace BinaryNinja {
1365013660

1365113661
std::vector<DisassemblyTextLine> GetTypeTokens(DisassemblySettings* settings = nullptr);
1365213662

13663+
/*! \deprecated Use GetGlobalPointerValues instead. */
1365313664
Confidence<RegisterValue> GetGlobalPointerValue() const;
13665+
std::vector<std::pair<uint32_t, Confidence<RegisterValue>>> GetGlobalPointerValues() const;
1365413666
bool UsesIncomingGlobalPointer() const;
1365513667
Confidence<RegisterValue> GetRegisterValueAtExit(uint32_t reg) const;
1365613668

@@ -17972,7 +17984,7 @@ namespace BinaryNinja {
1797217984
static uint32_t GetIntegerReturnValueRegisterCallback(void* ctxt);
1797317985
static uint32_t GetHighIntegerReturnValueRegisterCallback(void* ctxt);
1797417986
static uint32_t GetFloatReturnValueRegisterCallback(void* ctxt);
17975-
static uint32_t GetGlobalPointerRegisterCallback(void* ctxt);
17987+
static uint32_t* GetGlobalPointerRegistersCallback(void* ctxt, size_t* count);
1797617988

1797717989
static uint32_t* GetImplicitlyDefinedRegistersCallback(void* ctxt, size_t* count);
1797817990
static void GetIncomingRegisterValueCallback(
@@ -18124,11 +18136,13 @@ namespace BinaryNinja {
1812418136
*/
1812518137
virtual uint32_t GetFloatReturnValueRegister();
1812618138

18127-
/*! Gets the register that holds the global pointer, if the calling convention defines one.
18139+
/*! \deprecated Use GetGlobalPointerRegisters instead. New calling convention implementations
18140+
should override GetGlobalPointerRegisters.
1812818141

1812918142
\return The global pointer register index, or BN_INVALID_REGISTER if there is none
1813018143
*/
1813118144
virtual uint32_t GetGlobalPointerRegister();
18145+
virtual std::vector<uint32_t> GetGlobalPointerRegisters();
1813218146

1813318147
/*! Gets the registers that are implicitly given a known value on function entry by this
1813418148
calling convention.
@@ -18455,7 +18469,11 @@ namespace BinaryNinja {
1845518469
virtual uint32_t GetIntegerReturnValueRegister() override;
1845618470
virtual uint32_t GetHighIntegerReturnValueRegister() override;
1845718471
virtual uint32_t GetFloatReturnValueRegister() override;
18472+
/*! \deprecated Use GetGlobalPointerRegisters instead. New calling convention implementations
18473+
should override GetGlobalPointerRegisters.
18474+
*/
1845818475
virtual uint32_t GetGlobalPointerRegister() override;
18476+
virtual std::vector<uint32_t> GetGlobalPointerRegisters() override;
1845918477

1846018478
virtual std::vector<uint32_t> GetImplicitlyDefinedRegisters() override;
1846118479
virtual RegisterValue GetIncomingRegisterValue(uint32_t reg, Function* func) override;

binaryninjacore.h

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 171
40+
#define BN_CURRENT_CORE_ABI_VERSION 172
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 171
47+
#define BN_MINIMUM_CORE_ABI_VERSION 172
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -1323,6 +1323,12 @@ extern "C"
13231323
uint8_t confidence;
13241324
} BNRegisterValueWithConfidence;
13251325

1326+
typedef struct BNRegisterValueWithConfidenceAndRegister
1327+
{
1328+
uint32_t reg;
1329+
BNRegisterValueWithConfidence value;
1330+
} BNRegisterValueWithConfidenceAndRegister;
1331+
13261332
typedef struct BNValueRange
13271333
{
13281334
uint64_t start, end, step;
@@ -2956,7 +2962,7 @@ extern "C"
29562962
uint32_t (*getIntegerReturnValueRegister)(void* ctxt);
29572963
uint32_t (*getHighIntegerReturnValueRegister)(void* ctxt);
29582964
uint32_t (*getFloatReturnValueRegister)(void* ctxt);
2959-
uint32_t (*getGlobalPointerRegister)(void* ctxt);
2965+
uint32_t* (*getGlobalPointerRegisters)(void* ctxt, size_t* count);
29602966

29612967
uint32_t* (*getImplicitlyDefinedRegisters)(void* ctxt, size_t* count);
29622968
void (*getIncomingRegisterValue)(void* ctxt, uint32_t reg, BNFunction* func, BNRegisterValue* result);
@@ -4889,10 +4895,13 @@ extern "C"
48894895
BINARYNINJACOREAPI BNNameSpace BNGetInternalNameSpace(void);
48904896
BINARYNINJACOREAPI void BNFreeNameSpace(BNNameSpace* name);
48914897

4892-
BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetGlobalPointerValue(BNBinaryView* view);
4893-
BINARYNINJACOREAPI bool BNUserGlobalPointerValueSet(BNBinaryView* view);
4894-
BINARYNINJACOREAPI void BNClearUserGlobalPointerValue(BNBinaryView* view);
4895-
BINARYNINJACOREAPI void BNSetUserGlobalPointerValue(BNBinaryView* view, BNRegisterValueWithConfidence value);
4898+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetGlobalPointerValues(BNBinaryView* view, size_t* count);
4899+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetDefaultGlobalPointerValues(BNBinaryView* view, size_t* count);
4900+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetUserGlobalPointerValues(BNBinaryView* view, size_t* count);
4901+
BINARYNINJACOREAPI void BNFreeRegisterValueWithConfidenceAndRegisterList(BNRegisterValueWithConfidenceAndRegister* values);
4902+
BINARYNINJACOREAPI bool BNUserGlobalPointerValuesSet(BNBinaryView* view);
4903+
BINARYNINJACOREAPI void BNClearUserGlobalPointerValues(BNBinaryView* view);
4904+
BINARYNINJACOREAPI void BNSetUserGlobalPointerValues(BNBinaryView* view, const BNRegisterValueWithConfidenceAndRegister* values, size_t count);
48964905

48974906
BINARYNINJACOREAPI bool BNStringifyUnicodeData(BNBinaryView* data, BNArchitecture* arch, const BNDataBuffer* buffer, bool nullTerminates, bool allowShortStrings, char** string, BNStringType* type);
48984907

@@ -5446,7 +5455,7 @@ extern "C"
54465455
BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetFunctionTypeTokens(
54475456
BNFunction* func, BNDisassemblySettings* settings, size_t* count);
54485457

5449-
BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetFunctionGlobalPointerValue(BNFunction* func);
5458+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetFunctionGlobalPointerValues(BNFunction* func, size_t* count);
54505459
BINARYNINJACOREAPI bool BNFunctionUsesIncomingGlobalPointer(BNFunction* func);
54515460
BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetFunctionRegisterValueAtExit(BNFunction* func, uint32_t reg);
54525461

@@ -7764,7 +7773,7 @@ extern "C"
77647773
BINARYNINJACOREAPI uint32_t BNGetIntegerReturnValueRegister(BNCallingConvention* cc);
77657774
BINARYNINJACOREAPI uint32_t BNGetHighIntegerReturnValueRegister(BNCallingConvention* cc);
77667775
BINARYNINJACOREAPI uint32_t BNGetFloatReturnValueRegister(BNCallingConvention* cc);
7767-
BINARYNINJACOREAPI uint32_t BNGetGlobalPointerRegister(BNCallingConvention* cc);
7776+
BINARYNINJACOREAPI uint32_t* BNGetGlobalPointerRegisters(BNCallingConvention* cc, size_t* count);
77687777

77697778
BINARYNINJACOREAPI uint32_t* BNGetImplicitlyDefinedRegisters(BNCallingConvention* cc, size_t* count);
77707779
BINARYNINJACOREAPI BNRegisterValue BNGetIncomingRegisterValue(

binaryview.cpp

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5795,32 +5795,102 @@ std::vector<Ref<ExternalLocation>> BinaryView::GetExternalLocations()
57955795

57965796
Confidence<RegisterValue> BinaryView::GetGlobalPointerValue() const
57975797
{
5798-
BNRegisterValueWithConfidence value = BNGetGlobalPointerValue(m_object);
5799-
return Confidence<RegisterValue>(RegisterValue::FromAPIObject(value.value), value.confidence);
5798+
auto values = GetGlobalPointerValues();
5799+
if (values.empty())
5800+
return Confidence<RegisterValue>();
5801+
return values[0].second;
5802+
}
5803+
5804+
5805+
static vector<pair<uint32_t, Confidence<RegisterValue>>> ConvertGlobalPointerValues(
5806+
BNRegisterValueWithConfidenceAndRegister* values, size_t count)
5807+
{
5808+
vector<pair<uint32_t, Confidence<RegisterValue>>> result;
5809+
result.reserve(count);
5810+
for (size_t i = 0; i < count; i++)
5811+
result.emplace_back(values[i].reg,
5812+
Confidence<RegisterValue>(RegisterValue::FromAPIObject(values[i].value.value), values[i].value.confidence));
5813+
BNFreeRegisterValueWithConfidenceAndRegisterList(values);
5814+
return result;
5815+
}
5816+
5817+
5818+
vector<pair<uint32_t, Confidence<RegisterValue>>> BinaryView::GetGlobalPointerValues() const
5819+
{
5820+
size_t count;
5821+
BNRegisterValueWithConfidenceAndRegister* values = BNGetGlobalPointerValues(m_object, &count);
5822+
return ConvertGlobalPointerValues(values, count);
5823+
}
5824+
5825+
5826+
vector<pair<uint32_t, Confidence<RegisterValue>>> BinaryView::GetDefaultGlobalPointerValues() const
5827+
{
5828+
size_t count;
5829+
BNRegisterValueWithConfidenceAndRegister* values = BNGetDefaultGlobalPointerValues(m_object, &count);
5830+
return ConvertGlobalPointerValues(values, count);
5831+
}
5832+
5833+
5834+
vector<pair<uint32_t, Confidence<RegisterValue>>> BinaryView::GetUserGlobalPointerValues() const
5835+
{
5836+
size_t count;
5837+
BNRegisterValueWithConfidenceAndRegister* values = BNGetUserGlobalPointerValues(m_object, &count);
5838+
return ConvertGlobalPointerValues(values, count);
58005839
}
58015840

58025841

58035842
bool BinaryView::UserGlobalPointerValueSet() const
58045843
{
5805-
return BNUserGlobalPointerValueSet(m_object);
5844+
return UserGlobalPointerValuesSet();
5845+
}
5846+
5847+
5848+
bool BinaryView::UserGlobalPointerValuesSet() const
5849+
{
5850+
return BNUserGlobalPointerValuesSet(m_object);
58065851
}
58075852

58085853

58095854
void BinaryView::ClearUserGlobalPointerValue()
58105855
{
5811-
return BNClearUserGlobalPointerValue(m_object);
5856+
ClearUserGlobalPointerValues();
5857+
}
5858+
5859+
5860+
void BinaryView::ClearUserGlobalPointerValues()
5861+
{
5862+
return BNClearUserGlobalPointerValues(m_object);
58125863
}
58135864

58145865

58155866
void BinaryView::SetUserGlobalPointerValue(const Confidence<RegisterValue>& value)
58165867
{
5817-
BNRegisterValueWithConfidence v;
5818-
v.confidence = value.GetConfidence();
5819-
v.value.value = value.GetValue().value;
5820-
v.value.state = value.GetValue().state;
5821-
v.value.size = value.GetValue().size;
5822-
v.value.offset = value.GetValue().offset;
5823-
BNSetUserGlobalPointerValue(m_object, v);
5868+
vector<pair<uint32_t, Confidence<RegisterValue>>> values;
5869+
for (auto& [reg, _] : GetGlobalPointerValues())
5870+
if (reg != BN_INVALID_REGISTER)
5871+
values.emplace_back(reg, value);
5872+
if (values.empty())
5873+
values.emplace_back(BN_INVALID_REGISTER, value);
5874+
SetUserGlobalPointerValues(values);
5875+
}
5876+
5877+
5878+
void BinaryView::SetUserGlobalPointerValues(const vector<pair<uint32_t, Confidence<RegisterValue>>>& values)
5879+
{
5880+
vector<BNRegisterValueWithConfidenceAndRegister> apiValues;
5881+
apiValues.reserve(values.size());
5882+
for (auto& [reg, value] : values)
5883+
{
5884+
BNRegisterValueWithConfidenceAndRegister v;
5885+
v.reg = reg;
5886+
v.value.confidence = value.GetConfidence();
5887+
v.value.value.value = value.GetValue().value;
5888+
v.value.value.state = value.GetValue().state;
5889+
v.value.value.size = value.GetValue().size;
5890+
v.value.value.offset = value.GetValue().offset;
5891+
apiValues.push_back(v);
5892+
}
5893+
BNSetUserGlobalPointerValues(m_object, apiValues.data(), apiValues.size());
58245894
}
58255895

58265896

callingconvention.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ CallingConvention::CallingConvention(Architecture* arch, const string& name)
105105
cc.getIntegerReturnValueRegister = GetIntegerReturnValueRegisterCallback;
106106
cc.getHighIntegerReturnValueRegister = GetHighIntegerReturnValueRegisterCallback;
107107
cc.getFloatReturnValueRegister = GetFloatReturnValueRegisterCallback;
108-
cc.getGlobalPointerRegister = GetGlobalPointerRegisterCallback;
108+
cc.getGlobalPointerRegisters = GetGlobalPointerRegistersCallback;
109109
cc.getImplicitlyDefinedRegisters = GetImplicitlyDefinedRegistersCallback;
110110
cc.getIncomingRegisterValue = GetIncomingRegisterValueCallback;
111111
cc.getIncomingFlagValue = GetIncomingFlagValueCallback;
@@ -282,10 +282,16 @@ uint32_t CallingConvention::GetFloatReturnValueRegisterCallback(void* ctxt)
282282
}
283283

284284

285-
uint32_t CallingConvention::GetGlobalPointerRegisterCallback(void* ctxt)
285+
uint32_t* CallingConvention::GetGlobalPointerRegistersCallback(void* ctxt, size_t* count)
286286
{
287287
CallbackRef<CallingConvention> cc(ctxt);
288-
return cc->GetGlobalPointerRegister();
288+
vector<uint32_t> regs = cc->GetGlobalPointerRegisters();
289+
*count = regs.size();
290+
291+
uint32_t* result = new uint32_t[regs.size()];
292+
for (size_t i = 0; i < regs.size(); i++)
293+
result[i] = regs[i];
294+
return result;
289295
}
290296

291297

@@ -695,6 +701,15 @@ uint32_t CallingConvention::GetGlobalPointerRegister()
695701
}
696702

697703

704+
vector<uint32_t> CallingConvention::GetGlobalPointerRegisters()
705+
{
706+
uint32_t reg = GetGlobalPointerRegister();
707+
if (reg == BN_INVALID_REGISTER)
708+
return vector<uint32_t>();
709+
return vector<uint32_t> { reg };
710+
}
711+
712+
698713
vector<uint32_t> CallingConvention::GetImplicitlyDefinedRegisters()
699714
{
700715
return vector<uint32_t>();
@@ -1141,7 +1156,21 @@ uint32_t CoreCallingConvention::GetFloatReturnValueRegister()
11411156

11421157
uint32_t CoreCallingConvention::GetGlobalPointerRegister()
11431158
{
1144-
return BNGetGlobalPointerRegister(m_object);
1159+
vector<uint32_t> regs = GetGlobalPointerRegisters();
1160+
if (regs.empty())
1161+
return BN_INVALID_REGISTER;
1162+
return regs[0];
1163+
}
1164+
1165+
1166+
vector<uint32_t> CoreCallingConvention::GetGlobalPointerRegisters()
1167+
{
1168+
size_t count;
1169+
uint32_t* regs = BNGetGlobalPointerRegisters(m_object, &count);
1170+
vector<uint32_t> result;
1171+
result.insert(result.end(), regs, &regs[count]);
1172+
BNFreeRegisterList(regs);
1173+
return result;
11451174
}
11461175

11471176

examples/triage/analysisinfo.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ AnalysisInfoWidget::~AnalysisInfoWidget()
4444

4545
void AnalysisInfoWidget::timerExpired()
4646
{
47-
auto gpValue = m_data->GetGlobalPointerValue();
48-
if (gpValue == m_lastGPValue)
47+
auto gpValues = m_data->GetGlobalPointerValues();
48+
if (gpValues == m_lastGPValues)
4949
return;
5050

51-
m_lastGPValue = gpValue;
51+
m_lastGPValues = gpValues;
5252
updateDisplay();
5353
}
5454

@@ -61,14 +61,36 @@ void AnalysisInfoWidget::updateDisplay()
6161
auto callingConvention = defaultPlatform->GetDefaultCallingConvention();
6262
if (callingConvention)
6363
{
64-
auto gpRegister = callingConvention->GetGlobalPointerRegister();
65-
if (gpRegister != BN_INVALID_REGISTER)
64+
auto gpValues = m_data->GetGlobalPointerValues();
65+
if (!gpValues.empty())
6666
{
67-
auto gpValue = m_data->GetGlobalPointerValue();
68-
std::string gpString = getStringForRegisterValue(m_data->GetDefaultArchitecture(), gpValue);
69-
std::string gpExtraString = std::string(" @ ") + m_data->GetDefaultArchitecture()->GetRegisterName(gpRegister);
67+
std::vector<std::string> gpStrings;
68+
auto arch = m_data->GetDefaultArchitecture();
69+
for (auto& [reg, value] : gpValues)
70+
{
71+
if (reg == BN_INVALID_REGISTER)
72+
continue;
73+
gpStrings.push_back(arch->GetRegisterName(reg) + "=" + getStringForRegisterValue(arch, value));
74+
}
75+
76+
if (gpStrings.empty())
77+
{
78+
m_gpLabel->setText("N/A");
79+
m_gpExtraLabel->setText("");
80+
return;
81+
}
82+
83+
std::string gpString;
84+
for (size_t i = 0; i < gpStrings.size(); i++)
85+
{
86+
if (i != 0)
87+
gpString += ", ";
88+
gpString += gpStrings[i];
89+
}
90+
91+
std::string gpExtraString;
7092
if (m_data->UserGlobalPointerValueSet())
71-
gpExtraString += " (*)";
93+
gpExtraString = " (*)";
7294

7395
m_gpLabel->setText(QString::fromStdString(gpString));
7496
m_gpExtraLabel->setText(QString::fromStdString(gpExtraString));
@@ -78,4 +100,5 @@ void AnalysisInfoWidget::updateDisplay()
78100
}
79101

80102
m_gpLabel->setText("N/A");
103+
m_gpExtraLabel->setText("");
81104
}

examples/triage/analysisinfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class AnalysisInfoWidget : public QWidget
1616
NavigationAddressLabel* m_gpLabel;
1717
QLabel* m_gpExtraLabel;
1818

19-
BinaryNinja::Confidence<BinaryNinja::RegisterValue> m_lastGPValue;
19+
std::vector<std::pair<uint32_t, BinaryNinja::Confidence<BinaryNinja::RegisterValue>>> m_lastGPValues;
2020

2121
void updateDisplay();
2222

0 commit comments

Comments
 (0)