Skip to content
This repository was archived by the owner on Jul 11, 2022. It is now read-only.

Commit f34a46f

Browse files
committed
Add relative offset type & data renderer
Resolves: https://github.com/jonpalmisc/ObjectiveNinja/issues/21
1 parent 4c14ccf commit f34a46f

5 files changed

Lines changed: 99 additions & 25 deletions

File tree

source/CustomTypes.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ struct tptr_t {
3535
uint64_t raw;
3636
};
3737
38+
struct rptr_t {
39+
int32_t raw;
40+
};
41+
3842
typedef void* id;
3943
typedef char* SEL;
4044
@@ -46,9 +50,9 @@ struct CFString {
4650
};
4751
4852
struct objc_small_method_t {
49-
int32_t name;
50-
int32_t types;
51-
int32_t imp;
53+
rptr_t name;
54+
rptr_t types;
55+
rptr_t imp;
5256
};
5357
5458
struct objc_method_t {

source/CustomTypes.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
namespace CustomTypes {
3737

3838
const std::string TaggedPointer = "tptr_t";
39+
const std::string RelativePointer = "rptr_t";
3940
const std::string ID = "id";
4041
const std::string Selector = "SEL";
4142
const std::string CFString = "CFString";

source/DataRenderers.cpp

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,38 +36,39 @@
3636

3737
using namespace BinaryNinja;
3838

39-
bool TaggedPointerDataRenderer::IsValidForData(BinaryView* bv, uint64_t,
40-
Type* type, std::vector<std::pair<Type*, size_t>>&)
39+
/// Get the appropriate token type for a pointer to a given symbol.
40+
BNInstructionTextTokenType tokenTypeForSymbol(Ref<Symbol> symbol)
4141
{
42-
auto taggedPointerType = bv->GetTypeByName(CustomTypes::TaggedPointer);
43-
if (!taggedPointerType)
44-
return false;
42+
auto tokenType = CodeRelativeAddressToken;
4543

46-
return type->GetRegisteredName() == taggedPointerType->GetRegisteredName();
44+
switch (symbol->GetType()) {
45+
case DataSymbol:
46+
tokenType = DataSymbolToken;
47+
break;
48+
case FunctionSymbol:
49+
tokenType = CodeSymbolToken;
50+
break;
51+
default:
52+
break;
53+
}
54+
55+
return tokenType;
4756
}
4857

49-
std::vector<DisassemblyTextLine> TaggedPointerDataRenderer::GetLinesForData(
50-
BinaryView* bv, uint64_t addr, Type*,
51-
const std::vector<InstructionTextToken>& prefix, size_t,
52-
std::vector<std::pair<Type*, size_t>>&)
58+
/// Get a line for a given pointer.
59+
DisassemblyTextLine lineForPointer(BinaryView* bv, uint64_t pointer,
60+
uint64_t addr, const std::vector<InstructionTextToken>& prefix)
5361
{
54-
BinaryReader reader(bv);
55-
reader.Seek(addr);
56-
57-
auto pointer = (reader.Read64() & 0xFFFFFFFF) + bv->GetStart();
62+
std::string tokenText = "???";
63+
auto tokenType = CodeRelativeAddressToken;
5864

59-
std::string tokenText;
60-
BNInstructionTextTokenType tokenType;
61-
62-
// If this tagged pointer points to a symbol, use its name as the token
63-
// text, otherwise format the address it points to as a hex string.
6465
Ref<Symbol> symbol = bv->GetSymbolByAddress(pointer);
65-
if (pointer - bv->GetStart() == 0) {
66+
if (pointer == 0 || pointer == bv->GetStart()) {
6667
tokenText = "NULL";
6768
tokenType = KeywordToken;
6869
} else if (symbol) {
6970
tokenText = symbol->GetFullName();
70-
tokenType = DataSymbolToken;
71+
tokenType = tokenTypeForSymbol(symbol);
7172
} else {
7273
char addressBuffer[32];
7374
sprintf(addressBuffer, "0x%llx", pointer);
@@ -76,7 +77,6 @@ std::vector<DisassemblyTextLine> TaggedPointerDataRenderer::GetLinesForData(
7677
tokenType = CodeRelativeAddressToken;
7778
}
7879

79-
// Create a line using the prefix tokens passed in.
8080
DisassemblyTextLine line;
8181
line.addr = addr;
8282
line.tokens = prefix;
@@ -85,7 +85,60 @@ std::vector<DisassemblyTextLine> TaggedPointerDataRenderer::GetLinesForData(
8585
return { line };
8686
}
8787

88+
// Tells if a type is a given type.
89+
bool isType(BinaryView* bv, Type* type, const std::string& name)
90+
{
91+
auto targetType = bv->GetTypeByName(name);
92+
if (!targetType)
93+
return false;
94+
95+
return type->GetRegisteredName() == targetType->GetRegisteredName();
96+
}
97+
98+
bool TaggedPointerDataRenderer::IsValidForData(BinaryView* bv, uint64_t,
99+
Type* type, std::vector<std::pair<Type*, size_t>>&)
100+
{
101+
return isType(bv, type, CustomTypes::TaggedPointer);
102+
}
103+
104+
std::vector<DisassemblyTextLine> TaggedPointerDataRenderer::GetLinesForData(
105+
BinaryView* bv, uint64_t addr, Type*,
106+
const std::vector<InstructionTextToken>& prefix, size_t,
107+
std::vector<std::pair<Type*, size_t>>&)
108+
{
109+
BinaryReader reader(bv);
110+
reader.Seek(addr);
111+
112+
auto pointer = (reader.Read64() & 0xFFFFFFFF) + bv->GetStart();
113+
114+
return { lineForPointer(bv, pointer, addr, prefix) };
115+
}
116+
88117
void TaggedPointerDataRenderer::Register()
89118
{
90119
DataRendererContainer::RegisterTypeSpecificDataRenderer(new TaggedPointerDataRenderer());
91120
}
121+
122+
bool RelativePointerDataRenderer::IsValidForData(BinaryView* bv, uint64_t,
123+
Type* type, std::vector<std::pair<Type*, size_t>>&)
124+
{
125+
return isType(bv, type, CustomTypes::RelativePointer);
126+
}
127+
128+
std::vector<DisassemblyTextLine> RelativePointerDataRenderer::GetLinesForData(
129+
BinaryView* bv, uint64_t addr, Type*,
130+
const std::vector<InstructionTextToken>& prefix, size_t,
131+
std::vector<std::pair<Type*, size_t>>&)
132+
{
133+
BinaryReader reader(bv);
134+
reader.Seek(addr);
135+
136+
auto pointer = (int32_t)reader.Read32() + addr;
137+
138+
return { lineForPointer(bv, pointer, addr, prefix) };
139+
}
140+
141+
void RelativePointerDataRenderer::Register()
142+
{
143+
DataRendererContainer::RegisterTypeSpecificDataRenderer(new RelativePointerDataRenderer());
144+
}

source/DataRenderers.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,18 @@ class TaggedPointerDataRenderer : public BinaryNinja::DataRenderer {
4949

5050
static void Register();
5151
};
52+
53+
class RelativePointerDataRenderer : public BinaryNinja::DataRenderer {
54+
RelativePointerDataRenderer() = default;
55+
56+
public:
57+
bool IsValidForData(BinaryViewPtr, uint64_t addr,
58+
TypePtr, std::vector<std::pair<TypePtr, size_t>>& context) override;
59+
60+
std::vector<BinaryNinja::DisassemblyTextLine> GetLinesForData(
61+
BinaryViewPtr, uint64_t addr, TypePtr,
62+
const std::vector<BinaryNinja::InstructionTextToken>& prefix,
63+
size_t width, std::vector<std::pair<TypePtr, size_t>>& context) override;
64+
65+
static void Register();
66+
};

source/Plugin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ BN_DECLARE_CORE_ABI_VERSION
3939
BINARYNINJAPLUGIN bool CorePluginInit()
4040
{
4141
TaggedPointerDataRenderer::Register();
42+
RelativePointerDataRenderer::Register();
4243

4344
Workflow::registerActivities();
4445
OneShot::registerCommands();

0 commit comments

Comments
 (0)