Reverse Engineering Asked on August 8, 2021
I am trying to automate analysis of instructions within exported functions for a .DLL and need to be able to lift the first few instructions for the entry point of each exported function statically from disk without using a debugger.
I retrieve the correct RVA for each exported function (verified by objdump’s results):
$objdump -p examples/MathLibrary.dll
...
Export Table:
DLL name: MathLibrary.dll
Ordinal base: 1
Ordinal RVA Name
1 0x11212 fibonacci_current
2 0x1118b fibonacci_index
3 0x1104b fibonacci_init
4 0x11307 fibonacci_next
Then calculate what seems like the correct file offset using:
fo = exports.address - section.VirtualAddress + section.PointerToRawData
Section refers to .text. Which gives me:
1 RVA 0x11212 'fibonacci_current' file offset: 1554
Seeking to offset: 1554 to read 48 bytes.
Read 14 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
2 0x1118b 'fibonacci_index' file offset: 1419
Seeking to offset: 1419 to read 48 bytes.
Read 5 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
3 0x1104b 'fibonacci_init' file offset: 1099
Seeking to offset: 1099 to read 48 bytes.
Read 37 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
4 0x11307 'fibonacci_next' file offset: 1799
Seeking to offset: 1799 to read 48 bytes.
Read 9 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
I’m getting what looks like valid offsets that are located within the .text section however, the bytes there are all 00. This is verified by objdump.
0001420 0000 0000 0000 0000 0000 0000 0040 4000
0001440 722e 6c65 636f 0000 05bb 0000 f000 0001
0001460 0600 0000 9200 0000 0000 0000 0000 0000
0001500 0000 0000 0040 4200 0000 0000 0000 0000
0001520 0000 0000 0000 0000 0000 0000 0000 0000
*
0002000 cccc cccc e9cc 4173 0000 71e9 002e e900
What am I doing wrong? Is this not where the code is actually located? They aren’t being forwarded, so the code is there somewhere. Thanks for your help.
An RVA is a relative virtual address, it’s not a file offset.
You need to parse the section table to determine how file offsets map to RVAs and use that mapping to find your bytes on disk.
Answered by Igor Skochinsky on August 8, 2021
if using win32 apis are an option you can try something along this line
the first example command uses cdb to gets rva and bytes for counter checking (something like you do with objdump)
the second is a python script which you can use as refernce to adapt in your language of choice
the third is actual execution and bytes fetched from address
:>cdb -c "? ntdll!ZwYieldExecution-ntdll;db ntdll!ZwYieldExecution l10;q" cdb | awk "/Reading/,/quit/"
0:000> cdb: Reading initial command '? ntdll!ZwYieldExecution-ntdll;db ntdll!ZwYieldExecution l10;q'
Evaluate expression: 289512 = 00046ae8
77366ae8 b8 90 01 00 00 ba 00 03-fe 7f ff 12 c3 90 90 90 ................
quit:
:>cat expbyte.py
import ctypes
import sys
if(len(sys.argv) == 3):
ntstart = ctypes.windll.kernel32.LoadLibraryExW(sys.argv[1],0,2)
rva = int(sys.argv[2],16)
buff =[]
for i in range(0,16,1):
buff.append(ctypes.c_ubyte.from_address((ntstart+rva+i)).value)
for i in buff:
print("%02x " % i, end ="")
else:
print("usage this script path rva")
:>expbyte.py c:WindowsSystem32ntdll.dll 46ae8
b8 90 01 00 00 ba 00 03 fe 7f ff 12 c3 90 90 90
:>
Answered by blabb on August 8, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP