Log in

View Full Version : LINK: Three Ways to Inject Your Code into Another Process


Kayaker
August 9th, 2003, 02:19
A new link to a very interesting topic, discussions to follow?


Three Ways to Inject Your Code into Another Process
By Robert Kuster

How to inject code into another processes address space, and then execute it in the context of this process.

http://www.thecodeproject.com/useritems/winspy.asp

Cheers,
Kayaker

nikolatesla20
August 9th, 2003, 13:07
Great article, thanks for the link


For DilloDumper, I used WriteProcessMemory, but I didn't bother with CreateRemoteThread - I simply SuspendProcess and move the EIP to where I want it.

I notice the author talks about interprocess communication, in that if you inject a DLL, you will need to get info back from it somehow, for example, a password. The solution I use is a Mutex. I create a Mutex and flag it, then inject the DLL or WriteProcessMemory code, and then when it's done doing its work it triggers the Mutex. I then know that the variable I want is valid, and can simply do a ReadProcessMemory (especially with the WriteProcessMemory injection, since I'll know the exact location of the variable I wish to look at).

However, in some ways I disagree with the author that the WriteProcessMemory method is more flexible. It IS more "flexible" in terms that you can be more under control where it goes in memory, but it's a bitch if you have to recode it somehow. Writing alternate code versions is much easier to do with an injected DLL. Of course, using an injected DLL makes it hard to grab values you want. You could always use a shared file map of course

I like the "pop ecx" after a function call to get the EIP. I never though of doing it that way. I've learned a new thing


Just my 2 cents

-nt20

disavowed
August 10th, 2003, 00:55
Quote:
Originally posted by nikolatesla20
I like the "pop ecx" after a function call to get the EIP. I never though of doing it that way. I've learned a new thing

same here. i don't do much coding these days, but i thought it was a clever trick. good link, kayaker.

doug
August 10th, 2003, 11:13
this trick has been used for a long time; it is particularly effective when you want your code relocatable.

Same idea applies when u try this:

call dummy
db "kernel32.dll",0
dummy:
call _LoadLibraryA

return address for dummy is pushed on stack.. it also happens to be the address for the kernel32 string. (of course that example still isn't relocatable, some more code would be needed to resolve LoadLibraryA..)

nikolatesla20
August 10th, 2003, 22:19
I would like to see more posts here about making code relocatable - virus writers have been doing those tricks for a long time. Maybe it should be a new thread.

-nt20

squidge
August 11th, 2003, 03:29
I have used this trick before in attacking a sentinel license manager. Rather than create a valid license, I attacked the weakest point - the license manager itself, which was statically linked to the program. Since the program itself used the challenge response of the library, I had to create a good page-full of assembler to ensure that the response is faked perfectly, as parts of the response from the challenge are used throughout the program. Having little space to code, I used a POP EAX/PUSH EAX to find out where I was in memory before trying to access my lookup tables (since the patch was inside a DLL).

The fun part was jumping over the parts of the code which are pointed to by the relocation section - I didn't want to modify the relocation section, but didn't want my own code modified. I did this by hand, but I think it would be a useful addition to my RTA project to point out these fixup addresses for this kind of code modifying.

Now, is there any tools for directly modifying a targets relocation section in a dll?

nikolatesla20
August 11th, 2003, 08:10
Thats a similar problem I am going to have soon. I wish to patch , at runtime, a DLL of a game, to inject my own code to add more "functionality" (i.e., options). The issue here with DLL's becomes the relocation factor. Now, on one particular computer the addresses will usually remain the same every time, (very rare they will change) so I can code the whole thing to work on this PC only but I lose portablility of course.

I will end up with some Jump instructions of course, and as long as these are local jumps I'm ok, but I WILL need to somehow get to my new code, and to do that I'll have to do some sort of CALL of PUSH RET, which means I'll need to know the relocation.

Here is the thing: if my entire code blocks are injected at run time, this is not a big problem, since my injector can calculate most differences (get a list of modules in the process, and their base addresses, and then allocate some memory, calculate differences, work from there). But I wish to add this code statically eventually. In other words, as a permanent part of the DLL package. So in this case I will either need to edit the relocations section to add my new variables and calls and jumps, or I can use some smart techniques of avoiding non relocatable code.

Just like squidge asked, a relocation editor might be the only tool that I don't believe exists right now...haven't seen one off the top of my head anyway.

-nt20

doug
August 11th, 2003, 12:15
the main problem I have with injected code that must be executed from anywhere is the source can easily can unreadable.

- Something I have used against some protections & that I have seen in some viriis:

some_data db "blablah",0

call delta
delta:
pop ecx

; after this point, all offsets are calculated from delta.
; for example, to reference some_data, you would do something like
lea eax, [ecx+offset some_data - offset delta]

There are a few guildelines to follow, but essentially you want your code to have as few absolute addresses as possible. Therefore you must avoid some addressing modes and all instructions using them.
with some equ's you can probably make it a lot more readable.
lea eax, [ecx+SOME_DATA]
so you see, this really isn't doing much more than setting up another 'frame' pointer (ecx). call dword ptr [ecx+SOME_API] isn't impossible either.

Or if your code is big,

- To your injected code, include a small loader that will relocate the rest of your code (parse the .reloc, build yourself a reloc table, use the call/pop trick, ...), that way only a small part of the actual injected code will have to be coded using special techniques.

doug
August 11th, 2003, 12:24
forget last comment,
I didn't get that you two were looking for ways to change the relocation table to avoid your code being incorrectly relocated by the pe loader.

nikolatesla20
August 11th, 2003, 12:38
No, it's ok, that was the kinda of info I was looking for as well, thank you However, it would be nice to get more relocation info too, but I know I've read about it and actually walked thru a relocation table before, so I could probably do it manually, it's just that I'm surprised there's not a tool in existence for it yet.


Actually, now that I look at my DLL hook project, the entire code sequence that I wish to inject happens to be code based off all register offsets (i.e., call dword ptr [ebx + 0x174]), hence it will not need to be relocated. However, the PUSH RET will need to be, which calls to it. Looks like for now I may be better off to inject the code live, since I can calculate the correct offsets then. Otherwise I would need to add entries to the relocation table. Reason is I am getting to my new code block with a "PUSH XXXXXXXX, RET", which leaves more flexibility. Of course, if I can find a nice cave closer, I could use a local JMP which would also not need relocating, but I don't think I'll find such a cave in this DLL.

So far, I've always used the loader method, and for now I might need to continue using it for this project.

-nt20

evaluator
August 11th, 2003, 13:53
nikolatesla20

of course, DLL-inject is normal-good way.

>>using an injected DLL makes it hard to grab values you want.
why?

in simple, DLL is also somewhere allocated memory..
when you inject it with loadlibrary, you then have base.
so from control process you will calculate adresses via this base.

nikolatesla20
August 11th, 2003, 14:09
You are correct evaluator, in that you will get the base from LoadLibrary. However, when you inject the process, you normally would use "CreateRemoteThread" WITH "LoadLibrary" API to inject the DLL into the other process. Well then, this doesn't help you much because the return from LoadLibrary will be in the other process, not yours (Since the thread is in the other process). Hence, you still have a hard time getting the Loaded Base address. But yes, if you had the base you could calculate everything from there. Using the above technique however, will not allow you to easily get the base. You'd still have to use "Module32Next" on the processId to get it...which is what I'm going to end up doing I think for my little project...

-nt20

evaluator
August 11th, 2003, 14:16
I don't learn, how works this "CreateRemoteThread".

way I know:
1. Create suspended.
2. VirtualAllocEx
3. WriteProcessMemory on VirtualAllocEx-ed:
little code call loadlibrarya & save base here (on VirtualAllocEx-ed)
4. ReadProcessMemory for saved base, so we know base.

doug
August 11th, 2003, 14:46
Quote:
. However, the PUSH RET will need to be, which calls to it. Looks like for now I may be better off to inject the code live, since I can calculate the correct offsets then


Ok, so you are interested in statically patching your code into the new DLL, while not modifying the reloc table. I.e you are trying to avoid to use an external loader to do the dirty work & inject your code, right?

In that case, why not include a new section in the DLL add your code and modify the entrypoint, and from there do the same job your external loader would do.

Or, if you have space at the injected location to add a couple more lines of code.. you could get your PUSH/ret sequence to call the right place in memory without having to push the absolute (VA) location.

doug
August 11th, 2003, 14:49
you could use a 4bytes memory mapped file with a name both process know, where you would store the DLL loaded base.

Synchronize both things with a event maybe.

(edit: I meant event, not mutex)

Pyrae
June 29th, 2004, 01:54
It's even easier:
Simply use the exit value of your remote thread to hand over the base to the control process.