BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

DLL injection and code patching

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM
View previous topic :: View next topic  
Author Message
Nicholas Sherlock
Guest





PostPosted: Wed May 11, 2005 9:20 am    Post subject: DLL injection and code patching Reply with quote



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





PostPosted: Wed May 11, 2005 9:57 am    Post subject: Re: DLL injection and code patching Reply with quote



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





PostPosted: Wed May 11, 2005 10:10 am    Post subject: Re: DLL injection and code patching Reply with quote



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 Wink

Oh... no kidding! Smile. That would have been fun to debug! Smile. What should
my total list look like?

Cheers,
NIcholas Sherlock

Back to top
Bruno Lovatti
Guest





PostPosted: Wed May 11, 2005 12:34 pm    Post subject: Re: DLL injection and code patching Reply with quote

You can find very smart delphi code here:

http://iamaphex.net

Bruno


Back to top
Eric Grange
Guest





PostPosted: Wed May 11, 2005 12:41 pm    Post subject: Re: DLL injection and code patching Reply with quote

Quote:
Oh... no kidding! Smile. That would have been fun to debug! Smile. 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





PostPosted: Thu May 12, 2005 4:09 am    Post subject: Re: DLL injection and code patching Reply with quote

Eric Grange wrote:
Quote:
Oh... no kidding! Smile. That would have been fun to debug! Smile. 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





PostPosted: Thu May 12, 2005 9:46 am    Post subject: Re: DLL injection and code patching Reply with quote

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





PostPosted: Thu May 12, 2005 10:30 am    Post subject: Re: DLL injection and code patching Reply with quote

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 Smile

Good idea! I'll have to look into it.

Cheers,
Nicholas Sherlock

Back to top
Nicholas Sherlock
Guest





PostPosted: Fri May 13, 2005 10:35 am    Post subject: Re: DLL injection and code patching Reply with quote

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 Smile.

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





PostPosted: Wed May 18, 2005 10:03 pm    Post subject: Re: DLL injection and code patching Reply with quote

"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 Smile.

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





PostPosted: Thu May 19, 2005 6:41 am    Post subject: Re: DLL injection and code patching Reply with quote

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
Smile. 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





PostPosted: Thu May 19, 2005 8:24 am    Post subject: Re: DLL injection and code patching Reply with quote

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





PostPosted: Thu May 19, 2005 11:48 am    Post subject: Re: DLL injection and code patching Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.