0

I'm trying to essentially patch in a dll a far call to my own address instead of the one compiled already.

Here is the bytes I am trying to patch :

{ 0xFF, 0x15, 0x30, 0x20, 0x00, 0x10 }

Which should translate to : call DWORD PTR ds:0x10002030

Which I believe means the same thing as : call [0x10002030]

Yes, I am trying to patch an actual call to an IAT function to something else. Because the iat is essentially storing a integer that gets later assigned to the actual address of the api function, to call the function we have to dereference the address given to us from the IAT.

Now because I want to patch this to go to my own function, I am not going to be needing to dereference anything. Now the issue is the original dereference call is 6 bytes long, so I need to stay at 6 bytes or lower.

I'm trying to essentially find a way to do a call to an address, which is not relative (important!) and is not inside the current module I am in, and finally do it in less than or equal to 6 bytes.

I want something like so :

call 0xDEADBEEF

but I don't want 0xDEADBEEF to be a relative address. I want to directly call 0xDEADBEEF

To reiterate, I need to specifically patch this call, there is no other way around it. A normal IAT hook will not do in this situation.

Edit :

I've been looking into it some more and it seems that

push 0xdeadbeef

ret

might work, but I have found an issue. Because I have to handle the return myself, I can not do that in 6 bytes. But I think I know a way I can.

Original call goes from : call [0x10002030] to :

push jFunction 

ret

And jFunction would be essentially a stub of sorts :

mov eax, 0xDEADBEEF
call eax

But now the issue is how do I get back to my original execution?

Using a simple

pop ebx
ret

causes it to jmp back to the original main function, not to the instruction after the ret.

As I stated before because of the packer I am using, I can not use relative offsets, so again in this situation I cannot determine the relative offset between the start of the main function and the instruction I would like to go to. And I cannot push the wanted address to the "jFunction" because I only have 6 bytes to deal with.

I'm starting to think this is impossible without relative addresses.

Here is my current test code : x86 (debug) MSVC 2015 I am using inline assembly and __declspec(naked) to easily debug the solution instead of patching what I need and testing.

Current Testing Code

  • I don't see the problem here. Why can't you place the indirect jump vector in the absolute memory block which you apparently have control over? Alternatively I suppose a PUSH immediate+RET would do, assuming you can handle the return, but I don't see the need. – doynax Sep 11 '16 at 09:46
  • @doynax There is even enough space for that! Consider posting that as an answer. – fuz Sep 11 '16 at 09:54
  • @FUZxxl: Because frankly I suspect that the OP's confusion runs deeper than what might be solved by squeezing in the call. At least would like some background on why the original jump table entry, or a custom one in the custom target function block, can't be used before suggesting to mess with the return sequence. – doynax Sep 11 '16 at 10:03
  • @doynax technically patching in the iat would work, but it would not do what I need it to do. I am trying to fully remove dependence of the iat on any program. Essentially I want to take all calls that use the iat as a reference and convert it to just a normal call to the function address, completely removing use of the iat. I'm doing this as a small project, and I do nor have the best knowledge of assembly. If you could more in depth explain the methods you were talking about, it would be appreciated. –  Sep 11 '16 at 10:52
  • @Max Kunes: Perhaps you might elaborate a little on what it is that you actually want to achieve by dropping the import tables? In the general case this is finicky since some applications directly twiddle the table, such as when using delay loaded DLLs. Still, assuming you are massaging the executable offline and both the caller and callee modules are fixed then I suppose you might patch in a direct call, but if so why not compute the relative offset and be done with it? All you'd gain is about a cycle and a couple of paged out bytes in the relocation section. – doynax Sep 11 '16 at 11:38
  • @doynax I have been thinking and I have concluded that because of the packer I am using a relative call will not do. I need to do a call directly to an address. –  Sep 13 '16 at 04:37
  • @doynax I have been thinking about the push immediate + ret, but I was wondering how would I handle the return? I would assume I need to jmp back to the original push immediate + ret, but how would I figure the address at run-time to do so? I need to essentially do something specific, please check the bottom of the main post to understand what I need to accomplish. –  Sep 13 '16 at 05:53
  • @doynax Updated bottom of original post! –  Sep 13 '16 at 06:00
  • What OS are you using? How are you applying the patch? At runtime, or statically (in the image file)? If at runtime, are there any restrictions on your patcher code? (E.g. code size, access to APIs, running inside locks, etc.) – Cauterite Sep 13 '16 at 08:04
  • @Cauterite I am on windows 10 x64 and am trying to statically apply the patch before vmprotecting a file. –  Sep 13 '16 at 08:08
  • Wait, that's confusing. Are you just patching the file in memory, or are you saving the patched exe/dll to disk? I ask because depending on your situation I may have a great solution for you – Cauterite Sep 13 '16 at 08:36
  • @Cauterite I am reading a DLL file off of disk, parsing the instructions using capstone, trying to change all iat calls (6 byte) to not go though the iat. After changes I am writing the DLL back to disk. –  Sep 13 '16 at 09:03
  • Hmm, in that case my idea would involve patching the code statically and also patching it at runtime, so it might not be a suitable solution for you. – Cauterite Sep 14 '16 at 10:16
  • By the way, it's not possible to statically find all IAT calls in general, because the DLL could generate new code at runtime, or have self-modifying code, or otherwise (intentionally or incidentally) obfuscated code. But it should work for common cases. – Cauterite Sep 14 '16 at 10:19
  • @Cauterite, I'm not too woried about finding all calls. Im just trying to obfuscate as many as possible for security reasons. Could you explain more about the method of patching statically and on runtime? –  Sep 15 '16 at 06:58
  • The closest solution I can see is to create my own seudo iat. And to remove as many original hat functions that I can. –  Sep 15 '16 at 07:00
  • Sure, I'll post it as an answer shortly; if it's not a suitable solution for you, no worries. – Cauterite Sep 15 '16 at 08:47
  • As an update, help is still appreciated, I have not figured out how to do it properly yet. –  Sep 19 '16 at 17:42

1 Answers1

0

You know the address of the call instruction you're patching, so calculate 0xdeadbeef - start_of_next_insn to get the right rel32 displacement for a normal near direct relative call (5 bytes).

The other not-crazy options are to replace the function pointer in memory, or to change the addressing mode to load the pointer from somewhere else, but making it a simple direct call is obviously best.

This always works in 32-bit mode, but in 64-bit mode it's possible for two addresses to be more than +-2GiB away (out of range for a rel32). But we know you're in 32-bit mode because FF 15 4bytes decodes as an absolute addressing mode. In 64-bit mode, that would be a RIP-relative function pointer. RIP-relative took over the no-SIB encoding for a [disp32] addressing mode.

This is almost a duplicate of Call an absolute pointer in x86 machine code, answering mostly to address padding efficiently instead of putting a NOP before or after the call.

Pad it with a 0x67 address-size prefix (which will have no effect) to make it 6 bytes. GNU ld already does this when relaxing an indirect call to a near direct call, with objdump -d /bin/ls I can see some addr32 call ... instructions, so this is safe (CPU vendors can't change the meaning of 67 E8 into some new instruction without breaking lots of existing binaries).

In general it's not safe to assume that a prefix will have no effect in the future (e.g. rep bsr runs as lzcnt on CPUs that support it), but this case is safe because of existing usage, like rep ret.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847