Skip to content

Instantly share code, notes, and snippets.

@a1ext
Last active December 5, 2022 03:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a1ext/da52923749dab229fd0de1026fd7798e to your computer and use it in GitHub Desktop.
Save a1ext/da52923749dab229fd0de1026fd7798e to your computer and use it in GitHub Desktop.
Log and scripts used in the following video [Resolving APIs dynamically with Labeless & x64dbg] https://youtu.be/hMWuWVRkpB0

Resolving APIs dynamically with Labeless & x64dbg

Previous part Resolving APIs dynamically with Labeless & OllyDbg2

Hi, now we try to do the same things using x64dbg with x64-bit target application...

Let's try to find out the difference we need to make in IDA python script...

As the base, I use the previous script (see video how to do the same in OllyDbg 2)

Fix the remote base first... 00007FF7FFB40000

and the local base is 140000000 the fmfu_GetProcAddr is located at 00000001400011F0

Ok, the rest - implement tracing in x64dbg using script api we need the equivalent APIs:

  • set rip - Register_SetRIP(unsigned long long value)
  • step over - Debug_StepOver()
  • get RAX - Register_GetRAX()
  • get label at VA - DbgGetLabelAt(duint addr, SEGMENTREG segment, char * text)
  • get module - Module_NameFromAddr(duint addr, char * name)

Let's sync the labels and trace to load required libraries... Good :) Let's add the module name That's ok, but the name has non-needed part .dll - kernel32.dll.VirtualAllocEx Let's remove it Cool ) Transfer the resolved names back to IDA... Ok, transferred. Now propagate the labels (like in previous video)

Goooood :) Mission complete :3 Thanks for watching

IDA-side script

# let's prepare trace points...
from idautils import CodeRefsTo, FuncItems

fn_ea = 0x00000001400011F0
base = 0x140000000
remote = 0x00007FF7FFB40000

refs = list(CodeRefsTo(fn_ea, 0))
print 'found %d refs' % len(refs)

__extern__ = list()

for ref in refs:
	items = list(FuncItems(ref))
	# there we have all EAs (addresses) of function where ref is

	# use only three of them (ea of push, ea of push, ea of call)
	idx = items.index(ref)
	EAs = items[idx - 2: idx + 1]

	EAs = [remote + (ea - base) for ea in EAs]
    # for example ea = 0x401324
	# the remote ea = F00000 + (401324 - 400000)

	# print [hex(int(ea)) for ea in EAs]
	__extern__.append({'eas': EAs})

x64dbg-side script

import ctypes as C

buff_lbl = C.create_string_buffer(ll.api.MAX_LABEL_SIZE)
buff_mod = C.create_string_buffer(ll.api.MAX_MODULE_SIZE)

__result__ = list()

for item in __extern__:
	EAs = item['eas']

	for ea in EAs:
		ll.api.Register_SetRIP(ea)
		ll.api.Debug_StepOver()

	# at this point we have the context after 'call' insn
	rax = ll.api.Register_GetRAX()

	if ll.api.DbgGetLabelAt(rax, ll.api.SEG_DEFAULT, buff_lbl):
		name = buff_lbl.value.replace('\0', '')

		if ll.api.Module_NameFromAddr(rax, buff_mod):
			modname = buff_mod.value.replace('\0', '')
			modname = modname.replace('.dll', '')
			name = '%s.%s' % (modname, name)
		print '%x - %s' % (rax, name)
		__result__.append({'ea': EAs[-1], 'name': name})
	else:
		print '[-] unable to get name for VA: %x' % rax
		__result__.append({'ea': EAs[-1], 'name': None})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment