Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to get entrypoint from mach-o header #13

Open
ronaldoussoren opened this issue Jun 12, 2014 · 0 comments
Open

Add function to get entrypoint from mach-o header #13

ronaldoussoren opened this issue Jun 12, 2014 · 0 comments
Labels
enhancement New feature or request minor

Comments

@ronaldoussoren
Copy link
Owner

Original report by Asger Hautop Drewsen (Bitbucket: tyilo, GitHub: tyilo).


It would be neat to have a function that could calculate the entrypoint in the executable from the mach-o header.

I have made a function get_entrypoint that tries to find the entrypoint, based on LC_MAIN or LC_UNIXTHREAD load commands.
It probably doesn't cover all corner cases.

#!python

def get_load_cmd(header, kind, properties={}):
	for c in header.commands:
		if isinstance(c[1], kind):
			correct_cmd = True
			p = c[1].__dict__['_objects_']
			for k in properties:
				if properties[k] != p[k]:
					correct_cmd = False
					break
			
			if correct_cmd:
				return c
	
	return None

def get_entrypoint(header):	
	if header.MH_MAGIC == macholib.mach_o.MH_MAGIC_64:
		is64bit = True
	elif header.MH_MAGIC == macholib.mach_o.MH_MAGIC:
		is64bit = False
	else:
		raise Exception('Unknown MH_MAGIC in header!')
	
	thread_command = get_load_cmd(header, macholib.mach_o.thread_command)
	if thread_command:
		if is64bit:
			rip_offset = 2 * 4 + 16 * 8
			return struct.unpack(header.endian + 'Q', thread_command[2][rip_offset:rip_offset+8])[0]
		else:
			eip_offset = 2 * 4 + 10 * 4
			return struct.unpack(header.endian + 'L', thread_command[2][eip_offset:eip_offset+4])[0]
	
	entry_point_command = get_load_cmd(header, macholib.mach_o.entry_point_command)
	if entry_point_command:
		offset = entry_point_command[1].entryoff
		
		segment_kind =  macholib.mach_o.segment_command_64 if is64bit else  macholib.mach_o.segment_command
		text_segment = get_load_cmd(header, segment_kind, {'segname': '__TEXT' + 10 * '\x00'})
		
		return offset + text_segment[1].vmaddr
	
	return None
@ronaldoussoren ronaldoussoren added minor enhancement New feature or request labels Jan 5, 2020
ronaldoussoren added a commit that referenced this issue Jan 5, 2020
fix procesing DSYM file from XCODE 6.x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request minor
Projects
None yet
Development

No branches or pull requests

1 participant