2

English is not my first language, so I'm sorry if my text isn't so clear.

I'm trying to program an automatic patcher for a PE binary that should work for multiple versions of this executable. For that to work, I need to find the bytes of the instruction which references a specific static string. I need to find the bytes in file for the LEA instruction highlighted in red below:

enter image description here

I can't simply do a pattern search for "48 8D 15 C8 50 DA 00", because the last four bytes of the opcode change between executable versions, as the string address varies.

Finding the string offset in the file is pretty easy with an hex editor, and translating that offset into a virtual address is also very straightforward and I got that working already (converting from file offset to VA is yielding the 0x140FDE580 correctly).

The problem is actually going from this virtual address into the binary opcode of the LEA address operand (C8 50 DA 00). Since this address is relative to the current instruction position, is there any more optimized way of searching for this instruction other than iterate between each instruction, calculate the distance between EIP and the string VA and see if the current instruction address this VA offset?

Thanks in advance!

2
  • What about doing a sig-scan on the 4-5 opcodes before and then adding an offset? Commented Oct 3, 2019 at 21:29
  • Tried that, but that yielded more than 2 thousand possible references. I had to make a 20 byte signature for it to narrow down to the instruction I'm interested in, but that also made it incompatible with different versions of the executable. I ended up scanning the whole executable for 48 8D 15 and checking if string offset - EIP matched the instruction operand
    – Fergo
    Commented Oct 14, 2019 at 1:17

2 Answers 2

2

Searching for RVA as bytes works for x86 code since RVA is encoded directly in the instruction. However, as you noticed, it does not work on x64 where you instead have a RIP-relative offset which obviously changes depending on the address of the instruction.

I don't see any tricks you could use here but I think that unless your binary is multi-gigabyte, a simple brute-force of the .text section at every byte boundary should be fast enough. If it's still too slow in practice, post your code with explanation to Stack Overflow or Code Golf so other programmers can suggest you ideas on speeding it up.

2
  • IDApython may help. But OP didn't mention it.
    – Biswapriyo
    Commented Oct 4, 2019 at 8:54
  • Ended up with this approach. It indeed takes less than 300ms to find the right instruction. Instead of searching for every byte, I started by pattern scanning for "48 8D 15" on .text , which narrows down to only ~15.000 checks on a 20MB executable.
    – Fergo
    Commented Oct 14, 2019 at 1:22
1

Sure, just mask the dynamic bytes and increase the size of your pattern.

48 8D 15 C8 50 DA 00 [Original]
C8 8D 15 ? ? ? ? ... [New]

Obviously your pattern will have to be longer to remain unique, but it will stay consistent over most updates unless a compiler setting was changed for the most part. Simply have your pattern ignore dynamic offsets. Well, that's your pattern issue anyway.

In terms of your RIP Relative issue, it's pretty simple.
Target = (RIP + InstrLen + InstrImm).

Target is simply the next instruction (RIP + InstrLen) with offset being (NextInstr - ImmSize). All you need to know is instruction length and immediate size to follow the branch. Lots of libraries like DiStorm have macros to follow the current instruction as well, if you wanted to use one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.