Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Quickly find references to the specified Immediate number, or find the function call of specifies offset, and generate C++ functions call backtrace, The disassembly framework used is Capstone

Contact build license paypal

This tool does not support iOS, its used to analyze kext of Macos

When you statically analyze a kernel extension of a Mac to look for vulnerabilities, you may want to find out where this might exploitable C++ function call come from. It may come from a call from a function call from a very complicated ::externalMethod, if it does, then you may get a way to influence or control something about that function.

C ++ function calls essentially are jump to a function address that get from vtable with an offset. The address of vtable is fixed relative to the program code, the fixed address will be saved in memory of allocation of the instance, get the vtable address from the instance, and then add an offset to the vtable to get the function address, finally use the instruction jump to there.

The principle of this tool is very simple, scan the entire __text section of binary to match specified offset, get the location and print it together with the respective C ++ functions, so can be clear at a glance.

Let's see demo


Usage: maclook4ref <target Mac kext path> <hexadecimal offset of seek> [-p <index>] [-s] [-l]
	-p try to generate functions call backtrace
	-s print vtable offsets and results, its slow
	-l list all vtable offsets, its slow

Tool demo

Lists the vtable offsets for all functions

maclook4ref "IOThunderboltFamily" - -l
2642 [0x360]IOThunderboltTransmitCommand::_RESERVEDIOThunderboltTransmitCommand31
2643 [0x960]IOThunderboltFamilyUserClient::checkArguments
2644 [0xbd0]IOThunderboltSwitchType1::resetMessagedArray
2645 [?]IOThunderboltConfigWriteQuadletCommand::withController
2646 [0x158]IOThunderboltDispatchContext::getUInt64Parameter
2647 [0xd20]IOThunderboltSwitch::wakeLocalPorts

[?] mean didn't found, The reason usually is the class isn't defined in this binary

::checkArguments is used to parse the user state parameter, which is mean that place where the call to this function, can be affected from the userland

###Then looking for references to 0x960 immediate numbers

maclook4ref "IOThunderboltFamily" 0x960 IOThunderboltFamilyUserClient::plugEvent
0x455B:	xor		r9d, r9d
0x455E:	mov		rdi, r12
0x4561:	mov		rsi, rbx
0x4564:	call	qword ptr [rax + 0x960]
0x456A:	mov		r14d, eax
0x456D:	test	r14d, r14d IOThunderboltFamilyUserClient::configWriteAction
0x48F2:	xor		ecx, ecx
0x48F4:	xor		r8d, r8d
0x48F7:	xor		r9d, r9d
0x48FA:	call	qword ptr [rax + 0x960]
0x4900:	mov		r13d, eax
0x4903:	test	r13d, r13d IOThunderboltFamilyUserClient::xDomainRequestAction
0x4AFE:	xor		r9d, r9d
0x4B01:	mov		rdi, r12
0x4B04:	mov		rsi, rbx
0x4B07:	call	qword ptr [rax + 0x960]
0x4B0D:	test	eax, eax
0x4B0F:	je		0x4b28

With the Instruction address you can quickly jump there in IDA, and start analysis

###Or you want to search for backtracking, list all possible places where function call from ###Example: Lists all possible calls to ::configWriteAction

maclook4ref "IOThunderboltFamily" 0x960 -p 1
|- [0x988]IOThunderboltFamilyUserClient::configWrite(0x48bd)
|- - [0x850]IOThunderboltFamilyUserClient::externalMethod(0x3fe2)
|- - [0x970]IOThunderboltSwitch::createResources (0x16c8a)
|- - [0x978]IOThunderboltSwitchType2::destroyResources (0x50fa9)
|- - [0x978]IOThunderboltSwitchType1::destroyResources (0x58178)
|- [0x978]IOThunderboltSwitch::destroyResources (0x17126)
|- - [0x860]IOThunderboltController::incrementScanCount (0x2909)
|- - [0x868]IOThunderboltController::decrementScanCount (0x2a45)

Correct backtrace in example are: ::configWriteAction<- ::configWrite <- ::externalMethod

The horizontal line on the left indicates the depth, I set the depth limit to 2. The right side is the instruction address.
Data will lose meaning if depth over than 2, it's may fall into a loop. So the most credible data is the first line, better belong to the same class

This tool may help you save some time, hope it will help some
Thank you for read

Compile and install to /usr/local/bin/

git clone \
&& cd maclook4ref && make && make install


Quickly find references to the specified Immediate number, or find the function call of specifies offset, and generate C++ functions call backtrace







No releases published


No packages published