Skip to content

Commit f01ab64

Browse files
committed
Add support for multiple global pointer registers
1 parent 39201de commit f01ab64

12 files changed

Lines changed: 402 additions & 21 deletions

binaryninjaapi.h

Lines changed: 20 additions & 1 deletion
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

@@ -17973,6 +17985,7 @@ namespace BinaryNinja {
1797317985
static uint32_t GetHighIntegerReturnValueRegisterCallback(void* ctxt);
1797417986
static uint32_t GetFloatReturnValueRegisterCallback(void* ctxt);
1797517987
static uint32_t GetGlobalPointerRegisterCallback(void* ctxt);
17988+
static uint32_t* GetGlobalPointerRegistersCallback(void* ctxt, size_t* count);
1797617989

1797717990
static uint32_t* GetImplicitlyDefinedRegistersCallback(void* ctxt, size_t* count);
1797817991
static void GetIncomingRegisterValueCallback(
@@ -18124,11 +18137,13 @@ namespace BinaryNinja {
1812418137
*/
1812518138
virtual uint32_t GetFloatReturnValueRegister();
1812618139

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

1812918143
\return The global pointer register index, or BN_INVALID_REGISTER if there is none
1813018144
*/
1813118145
virtual uint32_t GetGlobalPointerRegister();
18146+
virtual std::vector<uint32_t> GetGlobalPointerRegisters();
1813218147

1813318148
/*! Gets the registers that are implicitly given a known value on function entry by this
1813418149
calling convention.
@@ -18455,7 +18470,11 @@ namespace BinaryNinja {
1845518470
virtual uint32_t GetIntegerReturnValueRegister() override;
1845618471
virtual uint32_t GetHighIntegerReturnValueRegister() override;
1845718472
virtual uint32_t GetFloatReturnValueRegister() override;
18473+
/*! \deprecated Use GetGlobalPointerRegisters instead. New calling convention implementations
18474+
should override GetGlobalPointerRegisters.
18475+
*/
1845818476
virtual uint32_t GetGlobalPointerRegister() override;
18477+
virtual std::vector<uint32_t> GetGlobalPointerRegisters() override;
1845918478

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

binaryninjacore.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
@@ -2957,6 +2963,7 @@ extern "C"
29572963
uint32_t (*getHighIntegerReturnValueRegister)(void* ctxt);
29582964
uint32_t (*getFloatReturnValueRegister)(void* ctxt);
29592965
uint32_t (*getGlobalPointerRegister)(void* ctxt);
2966+
uint32_t* (*getGlobalPointerRegisters)(void* ctxt, size_t* count);
29602967

29612968
uint32_t* (*getImplicitlyDefinedRegisters)(void* ctxt, size_t* count);
29622969
void (*getIncomingRegisterValue)(void* ctxt, uint32_t reg, BNFunction* func, BNRegisterValue* result);
@@ -4889,9 +4896,16 @@ extern "C"
48894896
BINARYNINJACOREAPI void BNFreeNameSpace(BNNameSpace* name);
48904897

48914898
BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetGlobalPointerValue(BNBinaryView* view);
4899+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetGlobalPointerValues(BNBinaryView* view, size_t* count);
4900+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetDefaultGlobalPointerValues(BNBinaryView* view, size_t* count);
4901+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetUserGlobalPointerValues(BNBinaryView* view, size_t* count);
4902+
BINARYNINJACOREAPI void BNFreeRegisterValueWithConfidenceAndRegisterList(BNRegisterValueWithConfidenceAndRegister* values);
48924903
BINARYNINJACOREAPI bool BNUserGlobalPointerValueSet(BNBinaryView* view);
4904+
BINARYNINJACOREAPI bool BNUserGlobalPointerValuesSet(BNBinaryView* view);
48934905
BINARYNINJACOREAPI void BNClearUserGlobalPointerValue(BNBinaryView* view);
4906+
BINARYNINJACOREAPI void BNClearUserGlobalPointerValues(BNBinaryView* view);
48944907
BINARYNINJACOREAPI void BNSetUserGlobalPointerValue(BNBinaryView* view, BNRegisterValueWithConfidence value);
4908+
BINARYNINJACOREAPI void BNSetUserGlobalPointerValues(BNBinaryView* view, const BNRegisterValueWithConfidenceAndRegister* values, size_t count);
48954909

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

@@ -5446,6 +5460,7 @@ extern "C"
54465460
BNFunction* func, BNDisassemblySettings* settings, size_t* count);
54475461

54485462
BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetFunctionGlobalPointerValue(BNFunction* func);
5463+
BINARYNINJACOREAPI BNRegisterValueWithConfidenceAndRegister* BNGetFunctionGlobalPointerValues(BNFunction* func, size_t* count);
54495464
BINARYNINJACOREAPI bool BNFunctionUsesIncomingGlobalPointer(BNFunction* func);
54505465
BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetFunctionRegisterValueAtExit(BNFunction* func, uint32_t reg);
54515466

@@ -7764,6 +7779,7 @@ extern "C"
77647779
BINARYNINJACOREAPI uint32_t BNGetHighIntegerReturnValueRegister(BNCallingConvention* cc);
77657780
BINARYNINJACOREAPI uint32_t BNGetFloatReturnValueRegister(BNCallingConvention* cc);
77667781
BINARYNINJACOREAPI uint32_t BNGetGlobalPointerRegister(BNCallingConvention* cc);
7782+
BINARYNINJACOREAPI uint32_t* BNGetGlobalPointerRegisters(BNCallingConvention* cc, size_t* count);
77677783

77687784
BINARYNINJACOREAPI uint32_t* BNGetImplicitlyDefinedRegisters(BNCallingConvention* cc, size_t* count);
77697785
BINARYNINJACOREAPI BNRegisterValue BNGetIncomingRegisterValue(

binaryview.cpp

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5800,15 +5800,64 @@ Confidence<RegisterValue> BinaryView::GetGlobalPointerValue() const
58005800
}
58015801

58025802

5803+
static vector<pair<uint32_t, Confidence<RegisterValue>>> ConvertGlobalPointerValues(
5804+
BNRegisterValueWithConfidenceAndRegister* values, size_t count)
5805+
{
5806+
vector<pair<uint32_t, Confidence<RegisterValue>>> result;
5807+
result.reserve(count);
5808+
for (size_t i = 0; i < count; i++)
5809+
result.emplace_back(values[i].reg,
5810+
Confidence<RegisterValue>(RegisterValue::FromAPIObject(values[i].value.value), values[i].value.confidence));
5811+
BNFreeRegisterValueWithConfidenceAndRegisterList(values);
5812+
return result;
5813+
}
5814+
5815+
5816+
vector<pair<uint32_t, Confidence<RegisterValue>>> BinaryView::GetGlobalPointerValues() const
5817+
{
5818+
size_t count;
5819+
BNRegisterValueWithConfidenceAndRegister* values = BNGetGlobalPointerValues(m_object, &count);
5820+
return ConvertGlobalPointerValues(values, count);
5821+
}
5822+
5823+
5824+
vector<pair<uint32_t, Confidence<RegisterValue>>> BinaryView::GetDefaultGlobalPointerValues() const
5825+
{
5826+
size_t count;
5827+
BNRegisterValueWithConfidenceAndRegister* values = BNGetDefaultGlobalPointerValues(m_object, &count);
5828+
return ConvertGlobalPointerValues(values, count);
5829+
}
5830+
5831+
5832+
vector<pair<uint32_t, Confidence<RegisterValue>>> BinaryView::GetUserGlobalPointerValues() const
5833+
{
5834+
size_t count;
5835+
BNRegisterValueWithConfidenceAndRegister* values = BNGetUserGlobalPointerValues(m_object, &count);
5836+
return ConvertGlobalPointerValues(values, count);
5837+
}
5838+
5839+
58035840
bool BinaryView::UserGlobalPointerValueSet() const
58045841
{
5805-
return BNUserGlobalPointerValueSet(m_object);
5842+
return UserGlobalPointerValuesSet();
5843+
}
5844+
5845+
5846+
bool BinaryView::UserGlobalPointerValuesSet() const
5847+
{
5848+
return BNUserGlobalPointerValuesSet(m_object);
58065849
}
58075850

58085851

58095852
void BinaryView::ClearUserGlobalPointerValue()
58105853
{
5811-
return BNClearUserGlobalPointerValue(m_object);
5854+
ClearUserGlobalPointerValues();
5855+
}
5856+
5857+
5858+
void BinaryView::ClearUserGlobalPointerValues()
5859+
{
5860+
return BNClearUserGlobalPointerValues(m_object);
58125861
}
58135862

58145863

@@ -5824,6 +5873,25 @@ void BinaryView::SetUserGlobalPointerValue(const Confidence<RegisterValue>& valu
58245873
}
58255874

58265875

5876+
void BinaryView::SetUserGlobalPointerValues(const vector<pair<uint32_t, Confidence<RegisterValue>>>& values)
5877+
{
5878+
vector<BNRegisterValueWithConfidenceAndRegister> apiValues;
5879+
apiValues.reserve(values.size());
5880+
for (auto& [reg, value] : values)
5881+
{
5882+
BNRegisterValueWithConfidenceAndRegister v;
5883+
v.reg = reg;
5884+
v.value.confidence = value.GetConfidence();
5885+
v.value.value.value = value.GetValue().value;
5886+
v.value.value.state = value.GetValue().state;
5887+
v.value.value.size = value.GetValue().size;
5888+
v.value.value.offset = value.GetValue().offset;
5889+
apiValues.push_back(v);
5890+
}
5891+
BNSetUserGlobalPointerValues(m_object, apiValues.data(), apiValues.size());
5892+
}
5893+
5894+
58275895
optional<pair<string, BNStringType>> BinaryView::StringifyUnicodeData(Architecture* arch, const DataBuffer& buffer, bool nullTerminates, bool allowShortStrings)
58285896
{
58295897
char* str = nullptr;

callingconvention.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ CallingConvention::CallingConvention(Architecture* arch, const string& name)
106106
cc.getHighIntegerReturnValueRegister = GetHighIntegerReturnValueRegisterCallback;
107107
cc.getFloatReturnValueRegister = GetFloatReturnValueRegisterCallback;
108108
cc.getGlobalPointerRegister = GetGlobalPointerRegisterCallback;
109+
cc.getGlobalPointerRegisters = GetGlobalPointerRegistersCallback;
109110
cc.getImplicitlyDefinedRegisters = GetImplicitlyDefinedRegistersCallback;
110111
cc.getIncomingRegisterValue = GetIncomingRegisterValueCallback;
111112
cc.getIncomingFlagValue = GetIncomingFlagValueCallback;
@@ -289,6 +290,19 @@ uint32_t CallingConvention::GetGlobalPointerRegisterCallback(void* ctxt)
289290
}
290291

291292

293+
uint32_t* CallingConvention::GetGlobalPointerRegistersCallback(void* ctxt, size_t* count)
294+
{
295+
CallbackRef<CallingConvention> cc(ctxt);
296+
vector<uint32_t> regs = cc->GetGlobalPointerRegisters();
297+
*count = regs.size();
298+
299+
uint32_t* result = new uint32_t[regs.size()];
300+
for (size_t i = 0; i < regs.size(); i++)
301+
result[i] = regs[i];
302+
return result;
303+
}
304+
305+
292306
uint32_t* CallingConvention::GetImplicitlyDefinedRegistersCallback(void* ctxt, size_t* count)
293307
{
294308
CallbackRef<CallingConvention> cc(ctxt);
@@ -695,6 +709,15 @@ uint32_t CallingConvention::GetGlobalPointerRegister()
695709
}
696710

697711

712+
vector<uint32_t> CallingConvention::GetGlobalPointerRegisters()
713+
{
714+
uint32_t reg = GetGlobalPointerRegister();
715+
if (reg == BN_INVALID_REGISTER)
716+
return vector<uint32_t>();
717+
return vector<uint32_t> { reg };
718+
}
719+
720+
698721
vector<uint32_t> CallingConvention::GetImplicitlyDefinedRegisters()
699722
{
700723
return vector<uint32_t>();
@@ -1145,6 +1168,17 @@ uint32_t CoreCallingConvention::GetGlobalPointerRegister()
11451168
}
11461169

11471170

1171+
vector<uint32_t> CoreCallingConvention::GetGlobalPointerRegisters()
1172+
{
1173+
size_t count;
1174+
uint32_t* regs = BNGetGlobalPointerRegisters(m_object, &count);
1175+
vector<uint32_t> result;
1176+
result.insert(result.end(), regs, &regs[count]);
1177+
BNFreeRegisterList(regs);
1178+
return result;
1179+
}
1180+
1181+
11481182
vector<uint32_t> CoreCallingConvention::GetImplicitlyDefinedRegisters()
11491183
{
11501184
size_t count;

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

function.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,6 +2433,20 @@ Confidence<RegisterValue> Function::GetGlobalPointerValue() const
24332433
}
24342434

24352435

2436+
vector<pair<uint32_t, Confidence<RegisterValue>>> Function::GetGlobalPointerValues() const
2437+
{
2438+
size_t count;
2439+
BNRegisterValueWithConfidenceAndRegister* values = BNGetFunctionGlobalPointerValues(m_object, &count);
2440+
vector<pair<uint32_t, Confidence<RegisterValue>>> result;
2441+
result.reserve(count);
2442+
for (size_t i = 0; i < count; i++)
2443+
result.emplace_back(values[i].reg,
2444+
Confidence<RegisterValue>(RegisterValue::FromAPIObject(values[i].value.value), values[i].value.confidence));
2445+
BNFreeRegisterValueWithConfidenceAndRegisterList(values);
2446+
return result;
2447+
}
2448+
2449+
24362450
bool Function::UsesIncomingGlobalPointer() const
24372451
{
24382452
return BNFunctionUsesIncomingGlobalPointer(m_object);

0 commit comments

Comments
 (0)