Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


[C] Inline Hooking via WPM instead of DLL Injection

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Thu Apr 22, 2010 10:18 am    Post subject: [C] Inline Hooking via WPM instead of DLL Injection Reply with quote

The main problem presented when creating a solution to implement the above is the need to manually resolve pointers. Essentially we must mimic the behaviour of the PE loader when it relocates pointers. Most API calls usually work via an IAT ( sometimes through a JMP thunk table ). Clearly, this IAT will not exist in the target process.

In the case of API calls I have decided to take the route of determining what bytes are needed at runtime and editing them at that point, representing calls and jumps to absolute addresses instead of references to memory. For example, I would have :
Code:
jmp 0x0BADF00D


As opposed to:
Code:
jmp dword ptr ds:[0x0BADB01]


Where you would assume 0x0BADB01 holds 0x0BADF00D. I have already done the POC code that writes 2 jumps. The hook jump in the procedure to be hooked and also the return jump at the end of my hook procedure which returns code flow to 'hookedfunc + 5'.

WriteHook() is described as :
Code:
void WriteHook( HANDLE hProcess, LPVOID from, LPVOID to ) {
  DWORD flOldProtect;
  BYTE  arrHookBytes[5];

  arrHookBytes[0] = 0xe9;
  *( DWORD * )( &arrHookBytes[1] ) = JMP( from, to );

  VirtualProtect( from, _countof( arrHookBytes ), PAGE_EXECUTE_READWRITE, &flOldProtect );
  WriteProcessMemory( hProcess, from, arrHookBytes, _countof( arrHookBytes ), NULL );
  VirtualProtect( from, _countof( arrHookBytes ), flOldProtect, &flOldProtect );
}


I assume the rest of the code should be easy to read, it's not long :
http://pastebin.com/eKtGGzkA

I have some questions regarding the rest of the code though.

1 ) Is there a way to determine dwRetOffset instead of counting bytes and hardcoding it ? A label could easily be declared before the first instance of _emit but its scope is then local and I'm not sure how I'd go about getting it.
2 ) Is there a way to get the size of a given routine ? At the moment I'm copying the entire distance between the location of main() and HookFunc(). This is not ideal since extra bytes are copied ( padding between functions ) and there is no guarantee the compiler would place those functions in the order given in code ( although for the time being it seems to work ).
3 ) Why am I needing to put the -6 at line 48 ? I have a feeling it is to do with typecasting, I had a similar problem in the past.
4 ) Is there a better way of doing the relocations than what I'm doing right now ? I can see it getting really messy if I started adding a lot of API calls into the HookFunc.

This is an image of the current progress of the solution :
http://img220.imageshack.us/img220/6119/18355735.png

As you can see, I have successfully placed an empty hook and fixed up the two pointers. Calling MessageBoxW() in the target will execute as expected.

And uhhh yes messy code.. it's not tidied yet. And please no suggestions of using a DLL, I'm trying to do this without DLL injection.
Back to top
View user's profile Send private message
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Thu Apr 22, 2010 1:33 pm    Post subject: Reply with quote

I heard using a driver would be easier
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Thu Apr 22, 2010 2:02 pm    Post subject: Reply with quote

I don't want a workaround or to solve another problem. Just answers to the 4 questions I have.
Back to top
View user's profile Send private message
Flyte
Peanuts!!!!
Reputation: 6

Joined: 19 Apr 2006
Posts: 1887
Location: Canada

PostPosted: Thu Apr 22, 2010 2:05 pm    Post subject: Re: [C] Inline Hooking via WPM instead of DLL Injection Reply with quote

Slugsnack wrote:
1 ) Is there a way to determine dwRetOffset instead of counting bytes and hardcoding it ? A label could easily be declared before the first instance of _emit but its scope is then local and I'm not sure how I'd go about getting it.


You could scan for it.

Slugsnack wrote:
2 ) Is there a way to get the size of a given routine ? At the moment I'm copying the entire distance between the location of main() and HookFunc(). This is not ideal since extra bytes are copied ( padding between functions ) and there is no guarantee the compiler would place those functions in the order given in code ( although for the time being it seems to work ).


The really hackish way it to start at the start of a function and scan till you find a ret. There is a disassembling library that will do this for you, though it does do a little more in finding the function length. Its name escapes me at the moment, but it does exist.

Slugsnack wrote:
3 ) Why am I needing to put the -6 at line 48 ? I have a feeling it is to do with typecasting, I had a similar problem in the past.


This is why using #define is so dangerous, when a function will do what you want. You are treating your macro like it is a function, which is incorrect. See:

Code:
JMP( lpBaseAddress + dwRetOffset, lpRealFunc + 5 - 6 );


This expands to:
Code:
( ( ( int )lpRealFunc + 5 - 6 - ( int )lpBaseAddress + dwRetOffset ) - 5 )


Which is surely not what you meant. I'm sure you see the error.

Slugsnack wrote:
4 ) Is there a better way of doing the relocations than what I'm doing right now ? I can see it getting really messy if I started adding a lot of API calls into the HookFunc.


Yes. Compile your executable with a .reloc section. To inject the code you just map the exe with the function in question to your process, processes it like the PE loader would (but obviously the use code offsets you want), then copy the relevant stuff over. You could even generate a small IAT to copy over as well.

I did this some years ago, so I don't have the code anymore, but it is definitely possible.
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Thu Apr 22, 2010 3:51 pm    Post subject: Reply with quote

Thanks for your reply, Flyte. I don't feel scanning is a very solid way of getting the offset or size of the hook procedure. It requires a lot of work to make that into a reliable method ( disassembling seems overkill ). For the size of a retn instruction ( potentially just one byte ), a scan method seems unreliable. On top of this, the hook procedure does not actually end with a ret, but an empty jump ( which relocates to point to the hook + 5 ).

loool okay you get the last shout on the #define, point noted Laughing However I believe this is a bad case and does not show that #define are inherently bad. But let's not go there..

The reloc answer is just what I was looking for. I knew something existed, but forgot the name of it. Thanks for that, will look into it Wink
Back to top
View user's profile Send private message
Flyte
Peanuts!!!!
Reputation: 6

Joined: 19 Apr 2006
Posts: 1887
Location: Canada

PostPosted: Thu Apr 22, 2010 4:03 pm    Post subject: Reply with quote

Slugsnack wrote:
Thanks for your reply, Flyte. I don't feel scanning is a very solid way of getting the offset or size of the hook procedure. It requires a lot of work to make that into a reliable method ( disassembling seems overkill ). For the size of a retn instruction ( potentially just one byte ), a scan method seems unreliable. On top of this, the hook procedure does not actually end with a ret, but an empty jump ( which relocates to point to the hook + 5 ).


You don't have to scan for the instruction itself. You could, for example, __emit a sentinel that you are reasonably sure will be unique (could be more than one byte) at the end of the function, and scan for it.
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Thu Apr 22, 2010 4:11 pm    Post subject: Reply with quote

Flyte wrote:
Slugsnack wrote:
Thanks for your reply, Flyte. I don't feel scanning is a very solid way of getting the offset or size of the hook procedure. It requires a lot of work to make that into a reliable method ( disassembling seems overkill ). For the size of a retn instruction ( potentially just one byte ), a scan method seems unreliable. On top of this, the hook procedure does not actually end with a ret, but an empty jump ( which relocates to point to the hook + 5 ).


You don't have to scan for the instruction itself. You could, for example, __emit a sentinel that you are reasonably sure will be unique (could be more than one byte) at the end of the function, and scan for it.

Are you aware of any way it can be done with a compiler directive or something ? I'm sort of looking for a neat/elegant solution Confused
Back to top
View user's profile Send private message
Flyte
Peanuts!!!!
Reputation: 6

Joined: 19 Apr 2006
Posts: 1887
Location: Canada

PostPosted: Thu Apr 22, 2010 4:19 pm    Post subject: Reply with quote

Slugsnack wrote:
Are you aware of any way it can be done with a compiler directive or something ? I'm sort of looking for a neat/elegant solution Confused


There is no way to find the size of a function in a truly elegant way. This is because functions are not guaranteed to look like the code in question. They can be inlined, have functions inlined into them, etc. Some people like to add a function right after, and use it to find the size, but not even this is guaranteed as some compiler options can cause the functions in the source code to not be in the same order when it is linked.

The 'best' way, if you're looking for elegant, is to move the function you want to inject into its own section (there is a #pragma for that, I believe). You could then just fix this section and copy the entire section over. You could even take it a step further and scan backwards from the end of the section until you reach a byte that isn't 0 and make the assumption that it is the end of the function (if I did this, I would copy over some of the extra 0s just in case).
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Fri Apr 23, 2010 10:04 am    Post subject: Reply with quote

Thanks, I'll look into this and .reloc section
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
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
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites