Find an instruction in an executable file, given its address in a running process?

别等时光非礼了梦想. 提交于 2019-11-29 02:44:59

There's a "formula" but you'll actually need to look inside the executable file (although this formula can be simplified based on some assumptions).

  1. Get the in memory address (Virtual Address) of the instruction / data you are interested in. [VA]
  2. Get the base address of the module where the instruction / data lies. [MODBASE]
  3. Subtract MODBASE from VA, you obtain what is called a Relative Virtual Address [RVA]:
    • VA - MODBASE = RVA
  4. Open the binary file (e.g. *.exe or *.dll) with a PE file parser / editor and look at the section headers.
  5. Find in which section your RVA lies.
  6. Once you have found the section in which the RVA is, obtain the section Relative Virtual Address. [SECRVA].
  7. Subtract SECRVA from RVA, you then obtain an [OFFSET].
    • RVA - SECRVA = OFFSET
  8. Get the RawAddress [SECRAWADDR] of the section you found at 5.
  9. Add [OFFSET] to [SECRAWADDR], the result is the offset of the instruction / data you are searching for in the binary file.
    • OFFSET + SECRAWADDR = INSDATAOFFSET (offset of the instruction or data in the file on disk).

Assumption

Usually (I insist on usually, sometimes it is not the case), [SECRVA] will be 0x1000 for the first section - which happens to be the code section - and its [SECRAWADDR] will be 0x400.

So if you are searching for the offset of an instruction based on its address in memory, you can usually assume that:

  • SECRVA = 0x1000
  • SECRAWADDR = 0x400

Example

Example based on cmd.exe.

Let's say I'm searching for this code at 0x1C34B0 when the program is loaded into memory:

CPU Disasm
Address   Hex dump          Command                                  Comments
001C34B0  /$  E8 B3040000   CALL 001C3968
001C34B5  \.^ E9 2EFEFFFF   JMP 001C32E8

Notice the instruction opcodes (bytes) are: 0xE8B3040000

  1. VA = 0x1C34B0
  2. Searching for the module base in memory (use a debugger or ProcessExplorer; the interesting column here is simply called "Base" in process explorer.):

  • MODBASE = 0x1B0000

    1. VA - MODBASE = RVA ; 0x1C34B0 - 0x1B0000 = 0x134B0; RVA = 0x134B0

    2. Opening binary file in PE editor (I use CFF explorer):

  1. Let see in which section 0x134B0 lies:

first section is .text, its Virtual Address is 0x1000 and its Virtual Size is 0x23E4C (so the end of the section is at 0x1000 + 0x23E4C = 0x24E4C).

Is 0x134B0 between 0x1000 and 0x24E4C?

  • 0x1000 >= 0x134B0 < 0x24E4C -> True: so the address lies in the .text section.

Note: repeat the same process for each section until you have found the right one.

  1. SECRVA = 0x1000 (section Virtual Address)

  2. RVA - SECRVA = OFFSET ; 0x134B0 - 0x1000 = 0x124B0

  3. SECRAWADDR = 0x400 (section Raw Address)

  4. OFFSET + SECRAWADDR = INSDATAOFFSET ; 0x124B0 + 0x400 = 0x128B0

If we look at 0x128B0 in the file we have:

So we have found exactly the same bytes in file (0xE8B3040000) than in memory.

Yuni Mj

Of course there is a formula.
We just need to reverse what the PE loader do:

  1. Locate where the PE sections begin into the file.
    These numbers are called file offset.
  2. Locate where the PE sections must be loaded into memory, relative to a base address.
    These addresses are called RVAs (Relative Virtual Addresses)
  3. Choose1 an available base address and add it to the RVAs.
    These addresses are called VAs (Virtual Addresses) and are the final addresses of the file offsets.

To help understand the steps below keep in mind that every PE section has, among others, the following properties:

  • A starting file offset, where the section starts in the file.
  • A length inside the file.
  • A starting memory address, where the section should be loaded in memory (relative to the base address)
  • A length once loaded into memory (this may differ from the file length).

So for a given memory address X, you have to:

  1. Subtract the base address, for legacy Windows programs this is often 40 0000h.
  2. You now have a RVA, find the first PE section with its starting memory address below the RVA and ending memory address2 after it.
  3. Subtract the section starting memory address, you now have a section offset.
  4. Add the section starting file offset, you now have a file offset.

There is a tool called PEEditor 1.7 that can do this for you.
For some reason it is now harder to find it, but it should still be there on the Internet. Remember: It is free.


Found PE editor: Here , use the password tuts4you to unpack the RAR archive.

Load a file (by dragging into the window or using Browse button) and than hit FLC (File Location Calculator). In the new window, enter the address.


1 Mostly this is actually means that the base address set in the PE header is used, thanks to paging.
2 Computed as memory starting address+memory length-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!