Need some help regarding VirtualProtect or VirtualProtectEx.

I need to change the memory of a running process, method I'm opting for is by incjecting my own code thru createprocess, virtualprotect, and writeprocessmemory.
Thing is, what I need to do is hook an api the process will call. So, I'm wondering if VirtualProtect will let me change the protection of the api, so I can inject my own code, or if perhaps it will only let me change the protection of the process that I'm creating itself.

The reason for posting this problem stems from an experience I had with VirtualProtect: I managed to change the protection on the dll - so it seemed - but when I looked at the address I changed, it seemed that windows had managed to page that section out - as a result of my call to VirtualProtect.

If anybody could please provide some help, and preferably an example of how to use VirtualProtect (as the experience above left me somewhat confused), I'd be rather grateful.

Oh, and before the "old cranky bastard" comes threatening me with whatever, let me assure you that there is no illegal intent involved. What I'm trying to do is fix a bug M$ has left in their Messenger, and the dll in question is Wsock32.dll. The bug has to do with file transferring - when running a local network thru a cisco 677, it's not possible to send files thru Messenger, but it's possible to work around this, thru some api hooking.

Regards
Fake
Posted on 2002-02-28 22:35:48 by Fake51
Never fear Fake51, thanks for letting us know what you are doing with this idea. I am sure many people have suffered problems like this with M$ operating systems.

Regards,

hutch@movsd.com
Posted on 2002-03-01 01:14:30 by hutch--
Damn, would've thought that more ppl had experiences with this.
Anyway, I've resolved to patching the exe instead of the dll, so with a bit of luck my problem is solved.
I'd still like whatever info people have to offer on this one, tho.

Regards
Fake
Posted on 2002-03-02 10:24:05 by Fake51
I think you're right fake51, that there must be more people who have experience with that sort of thing. Unfortunately I'm not one of them. :)

In fact, I've only used (or should I say tried to use) VirtualProtect once in a failed attempt to port roy's notepad add-on patch to nt. It kept failing and I never did figure out why. It just kept returning 0.

But if/when you solve your problem I'd be interested to hear how you did it.
Posted on 2002-03-02 11:02:54 by Will
API hooking can (sanely) be done with either IAT redirection or patching of the API in memory. There are many more methods, but these are the ones that would probably fit you best.
To do IAT redirection, first of all, obtain the address of the API you wish to hook. Allocate memory into the foreign process using VirtualAllocEx() (only on Windows 2000/XP as far as I know, on Windows 9x/ME I heard you can use file mapping which is visible to all processes but I've never tried) and WriteProcessMemory() there your hook callee routine, which will be called instead of the original API. Somewhere in that routine, write the old address of API. So do something like:
mov eax, 00000000h

jmp eax

at the end of your routine, and dynamically replace 00000000h with the old address of the API.
Then read the PE header from the process in question (usually read the DOS header at 00400000h first, then use e_lfanew to get to PE header). In the OptionalDirectory.DataDirectory[12*8], find the address to the import address table and its size. From there on, read size/4 dwords from the IAT and compare each with the address of the function you wish to hook. When found, write the new address (the address of your hook routine) in that place in the IAT. Voila! You're done! To undo, replace the IAT with the old address of the API and deallocate memory you've been using.
The second method involves patching the API itself to something like:


push OFFSET HookProc
ret

That takes up 6 bytes (5 for push, 1 for ret), so you need to save the 6 old bytes and restore them in your HookProc. But then you also have to write that forwarder again when the hook is done! This can be done by spoofing the return address in your HookProc to ReinstallHookProc where you reinstall the hook and then jump back where you're supposed to.
Clearly the IAT hooking method is much easier and cleaner to implement, but it may not work if the program is importing functions dynamically and/or not using the IAT.
Posted on 2002-03-03 00:22:09 by comrade


The second method involves patching the API itself to something like:


push OFFSET HookProc
ret

That takes up 6 bytes (5 for push, 1 for ret), so you need to save the 6 old bytes and restore them in your HookProc. But then you also have to write that forwarder again when the hook is done! This can be done by spoofing the return address in your HookProc to ReinstallHookProc where you reinstall the hook and then jump back where you're supposed to.


Hi comrade,
when u set a global api hook as u wrote before u've to remember to put the hook handling code in a section visible to all process that have loaded the dll and thats shared
U've to put that code in the .text section this way every process calls the api u r hooking (so it means that code is executed from different contexts) u always jump to execute code thats accessible
If u would put it in some VirtualAlloc() mem the code would be visible only in the context of the process that has allocated it
It means u've to put ur code somewhere in the .text section and there u should put sorta stub that will call to the real hooking code in some dll u've written loading it with LoadLibrary() and calling the hooking function
This way u wont have any limitation about ur code lenght

See ya
NikDH
Posted on 2002-03-03 08:34:50 by NikDH
fake51,

you should use CreateRemoteThread() and VirtualAllocEx() to run your code in the different process.

but, if you resolve to stick with the first way, VirtualProtect() dont affect memory from kernel32. you can use vxdcall0 to unprotect the api address you want patch, and make it point to shared memory.

vxdcall0 is a w9x-only method, and CreateRemoteThread() exists only in nt ;)

but you can use a elicz library to emulate CreateRemoteThread() in w9x, or use debug api and context changes to emulate it by your own.

in iczelion site there's hideproc.zip, that show how hook api globally using vxdcall0

ancev

ps: isnt better use directly:


db 0e9h
patch dd (ofs patch+4)-old_api_addy

instead of weird pushs and rets, or jmps to registers, that make evident to the vict... ermm... user, that the api was hooked(and so disinfe... ermm... unhook they)? ;)

nah, i am kidding... i am sure you will use this hooks for good :alright:
Posted on 2002-03-03 09:12:11 by ancev
Cheers for the replies

Basically, what I started out to do was pacthing the api in mem (was gonna replace first five bytes with e9xxxxxxxx) and this is what gave me problems, since 1) I needed to find a way to get permission to install the hook cross-windows (both 9x and nt-based) and 2) I can't rely on anything other than what a normal user can execute .... which is ofcourse everything under 9x, but NT has a different perspective on things.

So, I guess my original question boils down to: is it possible to write to the codespace of an api (in this case wsock32.dll) after use of either VirtualProtect or VirtualProtectEx?

It is by now of a more theoretical interest to me, since I've opted to go for the IAT hooking way.

Blue skies
Fake
Posted on 2002-03-03 13:28:37 by Fake51
fake51 is a good boy and will not go and do evil things - welcome onboard, falske ;).

As for writing to the API stuff... I assume that is possible to do it
on all windows versions fake51 is a good boy and will not go and do evil things - welcome onboard, falske ;).

As for writing to the API stuff... I assume that is possible to do it
on all windows versions if you only patch the stuff in the context of
your own process (ie, copy-on-write). Writing to other processes memory
is probably not possible on NT without admin privileges, and I don't
know if you can patch the DLL in the context of another application
without doing code injection.

As for code injection, it can be done cross-windows if you can CreateProcess
the target (look at my XCOM bugfix loaders). I don't know whether this
will work without administrator privileges, but I find it likely.
Once the injected DLL runs in the context of your target app, you
should be able to do the VirtualProtect and patching stuff, without
too much sweat.

If you need to do global API hooking... ugh. Better turn to elicz then ;).
Posted on 2002-03-03 13:39:56 by f0dder
Thanx for the reply f0dd, glad to join you.

Anyway, I've sneaked a peak at your (stole from them is more the word I guess ;) ) and my method of action is pretty much the same: to create the process suspended, patch it, and then let it run. Seems to work on win9x, gonna see if it'll run on 2000/xp.

Fake
Posted on 2002-03-03 16:46:05 by Fake51
It works fine for me on w2k, haven't tested as non-admin though.
Posted on 2002-03-03 16:51:10 by f0dder
NikDH, both of the methods are described are local and in no-way are global. You may be lead to thinking that the second method of replacing the API code with your own is global, but you are mistaken. Windows keeps a separate copy of DLLs for each application in memory, so changes made to kernel32 or any other loaded library are only visible to the application in which address space they are loaded in. At least that is the case with Windows NT/2000/XP. Perhaps Windows 9x/ME has the same copy of DLLs, but hey those aren't really OSes. :)
Posted on 2002-04-20 20:11:53 by comrade
Only changed pages should be per-process, clean pages should
be shared... the "global memory" should only be a problem if you
patch circumventing Copy-On-Write (dunno if there's a non-ring0
way of doing that).

I dunno how fake's patch is done, but I'd opt for IAT patching if
possible, or even better, fixing the exe (though that might not be
a good option with windows file protection on :/ ).
Posted on 2002-04-21 11:11:57 by f0dder