 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Nicholas Sherlock Guest
|
Posted: Wed May 11, 2005 9:20 am Post subject: DLL injection and code patching |
|
|
Hey everyone,
I want to execute code in the middle of a procedure in a program for
which I do not have the source. So, I use Madshi's madCodeHook to inject
my DLL into the target process. From my DLL, I make a copy of the code
at the site where I will inject my code, then write something like this
over the top:
push injectionsite
push newcode
ret
When ret is called, execution jumps to the procedure in my DLL
identified by "newcode". So "Injectionsite" is the place that execution
will return to once newcode calls 'ret'.
I run my newcode, then before I ret, I copy what used to be at the
injection site back to it, so execution of the .exe can continue as if
nothing was ever changed.
The problem is that I need to preserve every register that might be
modified by the delphi code I call inside newcode, so that the original
application isn't affected. My newcode (which does nothing useful) looks
something like this:
procedure psconc;
asm
push eax
push ecx
push edx
push edi
push esi
push esp
push ebp
push ebx
mov eax, psconc
call cleanup
pop ebx
pop ebp
pop esp
pop esi
pop edi
pop edx
pop ecx
pop eax
end;
Cleanup is declared like this: "procedure cleanup(newaddress:pointer);"
The cleanup procedure needs a pointer to the start of psconc, but all I
get is an "Operand size mismatch". How can I get the address of psconc
into eax so I can call cleanup?
Cheers,
Nicholas Sherlock
|
|
| Back to top |
|
 |
Per Larsen Guest
|
Posted: Wed May 11, 2005 9:57 am Post subject: Re: DLL injection and code patching |
|
|
Use an OFFSET directive to get the address of the procedure.
Note that this bit:
| Quote: | pop ebp
pop esp <--------------
pop esi
|
might not work the way you think ;)
- Per
|
|
| Back to top |
|
 |
Nicholas Sherlock Guest
|
Posted: Wed May 11, 2005 10:10 am Post subject: Re: DLL injection and code patching |
|
|
Per Larsen wrote:
| Quote: | Use an OFFSET directive to get the address of the procedure.
Note that this bit:
pop ebp
pop esp <--------------
pop esi
might not work the way you think
|
Oh... no kidding! . That would have been fun to debug! . What should
my total list look like?
Cheers,
NIcholas Sherlock
|
|
| Back to top |
|
 |
Bruno Lovatti Guest
|
Posted: Wed May 11, 2005 12:34 pm Post subject: Re: DLL injection and code patching |
|
|
You can find very smart delphi code here:
http://iamaphex.net
Bruno
|
|
| Back to top |
|
 |
Eric Grange Guest
|
Posted: Wed May 11, 2005 12:41 pm Post subject: Re: DLL injection and code patching |
|
|
| Quote: | Oh... no kidding! . That would have been fun to debug! . What should
my total list look like?
|
If you want to save and restore all registers, pushad/popad should be
all you need.
Eric
|
|
| Back to top |
|
 |
Nicholas Sherlock Guest
|
Posted: Thu May 12, 2005 4:09 am Post subject: Re: DLL injection and code patching |
|
|
Eric Grange wrote:
| Quote: | Oh... no kidding! . That would have been fun to debug! . What
should my total list look like?
If you want to save and restore all registers, pushad/popad should be
all you need.
|
Thanks, very tidy! Now I just have one more problem. The injection
method I described works great, I can inject at *any* part of the code.
But it's a one-shot injection: It removes itself so that the original
code can be run. How can I keep my hook installed? I can't simply copy
the original code to a new location to run it, because that would run
the risk of slicing instructions in half. Do I have to write something
to parse all the instructions to stop splits, or is there a better way?
Cheers,
Nicholas Sherlock
|
|
| Back to top |
|
 |
Per Larsen Guest
|
Posted: Thu May 12, 2005 9:46 am Post subject: Re: DLL injection and code patching |
|
|
| Quote: | But it's a one-shot injection: It removes itself so that the original code
can be run. How can I keep my hook installed?
|
If you know for sure that the patched site is never called by a secondary
thread while it's active, and if it's an entire routine, and if you know the
calling convention, you can restore the original code image, then _call_ it
(as opposed to jump to it) from your hook, and then, when control returns to
your hooked routine, restore the hooking code. This might require some stack
fiddling/copying to get the parameters in the order and locations expected
by the hooked routine - but that's what makes this sort of thing so
entertaining :)
- Per
|
|
| Back to top |
|
 |
Nicholas Sherlock Guest
|
Posted: Thu May 12, 2005 10:30 am Post subject: Re: DLL injection and code patching |
|
|
Per Larsen wrote:
| Quote: | But it's a one-shot injection: It removes itself so that the original code
can be run. How can I keep my hook installed?
If you know for sure that the patched site is never called by a secondary
thread while it's active, and if it's an entire routine, and if you know the
calling convention, you can restore the original code image, then _call_ it
(as opposed to jump to it) from your hook, and then, when control returns to
your hooked routine, restore the hooking code. This might require some stack
fiddling/copying to get the parameters in the order and locations expected
by the hooked routine - but that's what makes this sort of thing so
entertaining
|
Good idea! I'll have to look into it.
Cheers,
Nicholas Sherlock
|
|
| Back to top |
|
 |
Nicholas Sherlock Guest
|
Posted: Fri May 13, 2005 10:35 am Post subject: Re: DLL injection and code patching |
|
|
Nicholas Sherlock wrote:
| Quote: | If you know for sure that the patched site is never called by a
secondary thread while it's active, and if it's an entire routine, and
if you know the calling convention, you can restore the original code
image, then _call_ it (as opposed to jump to it)...
Good idea! I'll have to look into it.
|
I decided that this method would be too complex, and require too much
knowledge of the code being patched. Instead, I wrote a two-patch system
(All that is needed is the address of the site where you want to patch,
and the address of a site at least 10 bytes further down inside the
target function):
Patch 1 is installed to begin with, in the target area. When patch 1
executes, it copies the original code back onto the patch site, installs
a second patch further down in the function, then returns to the function.
When patch 2 executes, it reinstalls patch 1, copies the original code
back onto its patch site, then returns to the function.
End result: The target code never knows what hit it .
I added another layer on top to manage multiple class instances in a
target C++ application. I add hooks in the constructors and destructors
of the target, then maintain a list of class instance pointers which I
can use to call the target functions.
Cheers,
Nicholas Sherlock
|
|
| Back to top |
|
 |
Dennis Landi Guest
|
Posted: Wed May 18, 2005 10:03 pm Post subject: Re: DLL injection and code patching |
|
|
"Nicholas Sherlock" <N_sherlock (AT) hotmail (DOT) com> wrote
| Quote: | I decided that this method would be too complex, and require too much
knowledge of the code being patched. Instead, I wrote a two-patch system
(All that is needed is the address of the site where you want to patch,
and the address of a site at least 10 bytes further down inside the
target function):
Patch 1 is installed to begin with, in the target area. When patch 1
executes, it copies the original code back onto the patch site, installs
a second patch further down in the function, then returns to the function.
When patch 2 executes, it reinstalls patch 1, copies the original code
back onto its patch site, then returns to the function.
End result: The target code never knows what hit it .
I added another layer on top to manage multiple class instances in a
target C++ application. I add hooks in the constructors and destructors
of the target, then maintain a list of class instance pointers which I
can use to call the target functions.
|
Yikes! Care to post an example to attachments?
-- d
---------------------------------------------------
Need to see what's happening?
Check out the Delphi Community Blog Aggregator
http://delphi.flashblogger.com
|
|
| Back to top |
|
 |
Nicholas Sherlock Guest
|
Posted: Thu May 19, 2005 6:41 am Post subject: Re: DLL injection and code patching |
|
|
Dennis Landi wrote:
| Quote: | "Nicholas Sherlock" <N_sherlock (AT) hotmail (DOT) com> wrote in message
news:4284831b$3 (AT) newsgroups (DOT) borland.com...
I decided that this method would be too complex, and require too much
knowledge of the code being patched. Instead, I wrote a two-patch system
(All that is needed is the address of the site where you want to patch,
and the address of a site at least 10 bytes further down inside the
target function):
Yikes! Care to post an example to attachments?
|
It'll be there shortly. If you want the C++ class management code, I can
post it, but I'll have to untangle it from the program I'm writing first
. The unit in attachments is dllpatch.pas, it contains some routines
for patching code in applications.
You call patchcustom() if you want to handle all the saving/restoring of
registers yourself (Give it the address of where you want to patch, and
an address at least 10 bytes down of where the restoring code should
sit. Not reccomended). The easy one is patchgeneric, you can give it a
handler which will be called along with some data from the injection
site. Patchthiscall is for totally replacing whole thiscall routines in
an application, your handler will be called and control will not be
given back to the routine being replaced.
Cheers,
Nicholas Sherlock
|
|
| Back to top |
|
 |
Nicholas Sherlock Guest
|
Posted: Thu May 19, 2005 8:24 am Post subject: Re: DLL injection and code patching |
|
|
Nicholas Sherlock wrote:
| Quote: | Patchthiscall is for totally replacing whole thiscall routines in
an application, your handler will be called and control will not be
given back to the routine being replaced.
|
Ah, little note on this one, your handler for it should be declared
stdcall, with the leftmost parameter being the class instance pointer.
So replacing a thiscall procedure with the signature
myproc(i1,i2:integer), your handler should be:
procedure replacedmyproc(classinstance:pointer; i1,i2:integer); stdcall;
Cheers,
Nicholas Sherlock
|
|
| Back to top |
|
 |
Dennis Landi Guest
|
Posted: Thu May 19, 2005 11:48 am Post subject: Re: DLL injection and code patching |
|
|
I see it in attachments.
I'll check it out in the next few days.
-- d
---------------------------------------------------
Need to see what's happening?
Check out the Delphi Community Blog Aggregator
http://delphi.flashblogger.com
"Nicholas Sherlock" <N_sherlock (AT) hotmail (DOT) com> wrote
| Quote: | Nicholas Sherlock wrote:
Patchthiscall is for totally replacing whole thiscall routines in
an application, your handler will be called and control will not be
given back to the routine being replaced.
Ah, little note on this one, your handler for it should be declared
stdcall, with the leftmost parameter being the class instance pointer.
So replacing a thiscall procedure with the signature
myproc(i1,i2:integer), your handler should be:
procedure replacedmyproc(classinstance:pointer; i1,i2:integer); stdcall;
Cheers,
Nicholas Sherlock
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|