Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

problem in hooking cocreateinstance

137 views
Skip to first unread message

chom

unread,
Jun 16, 2010, 3:23:38 AM6/16/10
to nob...@nowhere.in.the.net
hi..
iam trying to hook cocreateinstance . iam able to hook it if i call
cocreateinstance from same application where my function is .. but if
i call frm another application iam not able to get the call to my
function.. the virtual address space of another application will be
different frm my application .. is there any kind of virtual address
space funda comes in this situation .. please help..how to hook and
get calls even if cocreateinstance is called frm another
application ??
thanks and regards
sridhar
On Dec 8 2004, 11:15 pm, "Alessandro Angeli [MVP::DigitalMedia]"

- Hide quoted text -
<nob...@nowhere.in.the.net> wrote:
> Chris P. [MVP] wrote:
> > I would be interesting in taking a look when you have
> > time.
> The idea to not use Detours is simple: do the same stuff
> Detours does on my own.
> In the very end, what Detours does is quite "easy": Detours
> copies N bytes from the start of the function (F) to
> somewhere else (G), then overwrites the first 5 bytes of F
> with a jump instruction to your function (H) and last
> appends to G a jump to &F[N]. The difficulty is only in the
> choice of N: N must be >= 5, it must not go beyond the end
> of F and must contain an integral number of instructions.
> This last part requires the code of F to be disassembled and
> it is not difficult but very long to write given the mess of
> the IA-32 opcodes. Of course, you need to VirtualProtect()
> both the segments of F and G so that you can write to them
> and them VirtualProtect() them as they were before.
> Since I didn't want to write a table of IA-32 opcodes by
> hand, I decided that I would copy the whole body of F, that
> is N = size_of_body(F). This would also make the appended
> jump not needed. Of course, there is no way to know where F
> ends without disassembling the code. But I could then copy
> the whole code segment where F resides (practically the
> whole DLL code chunk). This wastes some memory, but doesn't
> require me to know anything about IA-32 opcodes (but the
> jump opcode I have to write). The idea is that either F lies
> wholly inside this segment, or it has to perform an absolute
> jump somewhere else sooner or later, and this jump would
> still work to the original code I didn't copy. Since I copy
> the whole segment, this works even if F jump backwards in
> the segment.
> I had to make an assumption that F contains at least 5
> bytes, but this quite a safe assumptions (Detours actually
> checks) given that shorter-than-5-bytes instructions are not
> unconditional jumps and thus there must be other
> instructions that follow.
> So, let's say I want to detour F with my function H and get
> a pointer to the original function in G, I do the following
> (no error-checking or resource releasing):
> VOID AxlDetourFunction(
> LPVOID F, /// function to detour
> LPVOID H, /// my new function
> LPVOID* pG) /// old function
> {
> LPVOID pv;
> DWORD dw, ul;
> MEMORY_BASIC_INFORMATION mbi;
> /// find out about F's segment
> VirtualQuery(F,&mbi,sizeof(mbi));
> /// allocate a new writable segment
> pv = VirtualAlloc(NULL,mbi.RegionSize,
> MEM_COMMIT,PAGE_READWRITE);
> /// copy F's segment to the new one
> MoveMemory(pv,mbi.BaseAddress,mbi.RegionSize);
> /// make the new segment read/exec-only
> VirtualProtect(pv,mbi.RegionSize,
> PAGE_EXECUTE_READ,&dw);
> /// the old function starts at the same offset
> /// in the new segment where it started in the old one
> *pG = (LPBYTE)pv + ((LPBYTE)F - (LPBYTE)mbi.BaseAddress);
> /// make F's segment writable
> VirtualProtect(mbi.BaseAddress,mbi.RegionSize,
> PAGE_EXECUTE_READWRITE,&dw);
> /// write the jump opcode
> ((LPBYTE)F)[0] = (BYTE)0xE9;
> /// calculate the jump offset
> ul = (LPBYTE)H - &((LPBYTE)F)[6];
> /// write the jump offset (since there is no guarantee
> /// that the offset's DWORD is DWORD aligned, this is
> /// safer even if not really needed on modern CPUs)
> MoveMemory(((LPBYTE)F)[1],&ul,sizeof(ul));
> /// protected F's segment as it was before
> VirtualProtect(mbi.BaseAddress,
> mbi.RegionSize,dw,&dw);
> }
> --
> // Alessandro Angeli
> // MVP :: Digital Media
> // a dot angeli at psynet dot net

Alessandro Angeli

unread,
Jun 16, 2010, 1:07:21 PM6/16/10
to
From: "chom"

> iam trying to hook cocreateinstance . iam able to hook it if i call
> cocreateinstance from same application where my function is .. but if
> i call frm another application iam not able to get the call to my
> function.. the virtual address space of another application will be
> different frm my application .. is there any kind of virtual address
> space funda comes in this situation .. please help..how to hook and
> get calls even if cocreateinstance is called frm another
> application ??

Each process has its own virtual memory space and, since user-mode API
hooking involves re-writing some memory, it can only work from inside a
process.

Injecting code into a running process is not easy.

Detours and other hooking libraries include facilities to start a new
process with your DLL injected into it.

Otherwise you can force the injection of your DLL into all future
processes (not currently running ones) as a side-effect of using
SetWindowsHookEx(). This may only work with processes running in the
same desktop and that load User32.dll.

Another way to force processes that load User32.dll to load your DLL is
AppInit_DLLs, but it is dangerous.

Depending on the application, it is possible to make it load your code
if it can be configured to autoload plugins/extensions/addons (a lot of
apps can do that).

As a last resort, you can use WriteProcessMemory() to inject whatever
code you want, but you need to know *a lot* about executable code to
manage that.


--
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm


chom

unread,
Jun 18, 2010, 8:01:58 AM6/18/10
to
On Jun 16, 10:07 pm, "Alessandro Angeli" <nob...@nowhere.in.the.net>
wrote:
> From: "chom"
>
> > iam trying to hookcocreateinstance. iam able to hook it if i call
> >cocreateinstancefrom same application where my function is .. but if

> > i call frm another application iam not able to get the call to my
> > function.. the virtual address space of another application will be
> > different frm my application .. is there any kind of virtual address
> > space funda comes in this situation .. please help..how to hook and
> > get calls even ifcocreateinstanceis called frm another
> > application ??
>
> Each process has its own virtual memory space and, since user-mode APIhookinginvolves re-writing some memory, it can only work from inside a

> process.
>
> Injecting code into a running process is not easy.
>
> Detours and otherhookinglibraries include facilities to start a new

> process with your DLL injected into it.
>
> Otherwise you can force the injection of your DLL into all future
> processes (not currently running ones) as a side-effect of using
> SetWindowsHookEx(). This may only work with processes running in the
> same desktop and that load User32.dll.
>
> Another way to force processes that load User32.dll to load your DLL is
> AppInit_DLLs, but it is dangerous.
>
> Depending on the application, it is possible to make it load your code
> if it can be configured to autoload plugins/extensions/addons (a lot of
> apps can do that).
>
> As a last resort, you can use WriteProcessMemory() to inject whatever
> code you want, but you need to know *a lot* about executable code to
> manage that.
>
> --
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> //http://www.riseoftheants.com/mmx/faq.htm

Thanks for the reply ..
Iam using the code from following link..
http://www.codeguru.com/cpp/com-tech/activex/misc/article.php/c2631
I want to intercept future processes only .. not current one..
if any process calls cocreateinstance , my local function should get
the call ..
please help..

Thanks and Regards
Sridhar

Alessandro Angeli

unread,
Jun 18, 2010, 12:35:54 PM6/18/10
to
From: "chom"

[...]


> Iam using the code from following link..
> http://www.codeguru.com/cpp/com-tech/activex/misc/article.php/c2631
> I want to intercept future processes only .. not current one..
> if any process calls cocreateinstance , my local function should get
> the call ..

That is just a basic hooking technique, no different from any other and,
as previously written, only works in-process. So you still need to
inject your code into other processes and I already gave you several
pointers on how to do that.

Tim Roberts

unread,
Jun 20, 2010, 12:57:56 AM6/20/10
to

chom <sridhar....@gmail.com> wrote:
>
>Thanks for the reply ..
>Iam using the code from following link..
>http://www.codeguru.com/cpp/com-tech/activex/misc/article.php/c2631
>I want to intercept future processes only .. not current one..
>if any process calls cocreateinstance , my local function should get
>the call ..

Alessandro has told you twice, but I'll try to put more directly.

Your task, as you have described it, is impossible. I don't mean it's
hard, I mean it cannot be done. The article you quoted hooks the CURRENT
one only. There is no connection between processes.

You can use a Windows hook to inject a DLL into other processes, then use
the code in that article to install the your hook. You could then send a
message back to your process for processing, if you need to.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

chom

unread,
Jun 21, 2010, 4:55:59 AM6/21/10
to ti...@probo.com, nob...@nowhere.in.the.net
thanks for the reply .. ok ..now i understood that i need to inject my
dll into target process in order to hook
the required API running in other process..
i will explain my problem clearly here ... so that u can suggest me a
right way..


i want to implement video streaming but dont want to capture the
uncompressed media ( at the renderer) which results in poor FPS. so
the better way (as per my understanding)is to capture the compressed
media when any media player application is playing the media on host.

so in order to achieve this i thought of placing my own capture filter
after the sourcefilter.


in this way if host starts wmp or any other player .. the client
should get the compressed video ..where decoding can be carried out.
But i need to support .wmv format files, it is not easy to replace
source filter becoz in wmv formats source filter is demuxer too ..
later we found a post saying that we can hook cocreateinstance and add
a sample grabbler between demuxer and video decoder..
the link is
http://www.eggheadcafe.com/software/aspnet/31775470/-hooking-igraphbuilder.aspx

so now i am trying to do the same?

can u please explain me the hooking process which will help me in my
implementation as i am novice to the hooking procedures.

chom

unread,
Jun 22, 2010, 10:39:49 AM6/22/10
to Tim Roberts
Similar kind of thing is done by other products also .. for example
citrix.. it provides video streaming ..
http://community.citrix.com/display/ocb/2008/02/11/(Video)+SpeedScreen+Multimedia+Acceleration+and+RAVE

RAVE is a strategic technology for Citrix, and the SpeedScreen
Multimedia Acceleration feature is in the process of being implemented
on XenDesktop. This will provide high quality audio and video support
for a wide variety of streaming media formats supported by players
based on DirectShow, DirectX Media Objects (DMO), or Media Foundation
(MF) filter technology.

How citrix is able to do this and support a wide variety of media
formats..??

http://support.citrix.com/article/CTX104912

Alessandro Angeli

unread,
Jun 22, 2010, 11:59:42 PM6/22/10
to
From: "chom"

[...]


> How citrix is able to do this and support a wide variety of media
> formats..??

If you capture the input to the decoder, the format doesn't really
matter. Of course a decoder can be any of:

1. a DirectShow filter in a DirectShow graph

2. a DMO in a DirectShow graph

3. a VCM codec in a DirectShow graph

4. an ACM codec in a DirectShow graph

5. a DMO in the WMReader

6. a VCM codec in the WMReader

7. an ACM codec in the WMReader

8. an MFT in a MediaFoundation pipeline

WMP uses 5-7 when playing a WMA/ASF/WMV file on XP or older and 8 on
Vista or newer, while it uses 1-4 to play any other file on XP or older
and either 8 or 1-4 on Vista or newer.

Also, WMP has some anti-hooking checks to prevent ripping of DRM'ed
WMA/WMV files.

Other players mostly use 1-4.

Plus there are many players that do not use any of those, for example
QuickTime, RealPlayer, Flash, Silverlight...

chom

unread,
Jun 23, 2010, 9:38:22 AM6/23/10
to
my task is explained above.. please suggest me a way to complete it ..
My aim is only wmv format for now..


On Jun 23, 8:59 am, "Alessandro Angeli" <nob...@nowhere.in.the.net>
wrote:

Alessandro Angeli

unread,
Jun 23, 2010, 11:41:09 AM6/23/10
to
From: "chom"

> my task is explained above.. please suggest me a way to complete it ..
> My aim is only wmv format for now..

No, your task is not explained above.

Are you trying to rip the elementary audio/video streams or the whole
WMV file?

Are you trying to rip it off WMP only or any application?

Is WMP embedded or stand-alone?

Is the source a file or a network stream?

If it is a stream, is it HTTP or RTSP or MMS?

What should happen when the user seeks ahead or backwards?

And so on...

In any case, I already gave you an idea about the internals of WMP and
other players. If you are serious abot this, you should stop asking
vague questions and instead provide detailed specs and be prepared to
spent months in studying those APIs and in reverse-engineering the apps
you want to hook to figure out what exactly you need to do. You will not
find a short easy solution.

chom

unread,
Jun 23, 2010, 4:14:53 PM6/23/10
to
We r developing a project similar to Remote Desktop..now we are
capturing the screenshots of host display,compressing and then sending
them to the client..
I want to enhance the quality as the display is poor while video is
being played ..
In part of that i need to implement video streaming kind of thing..
if user plays a video file(using any player) on the host we should get
the video on the client side.
if user seeks also we should get that..
as we get uncompressed data before decoders and renderers,i thought of
getting data from source filter to get compressed data
using compressed data can provide good FPS..
i thought of replacing the source filter by increasing its merit ..
later i came to know that our main focus is on wmv formats..source
filter in wmv is demuxer and came to know that it is very difficult to
replace that ..
i wanted to capture video data coming frm demuxer ..and send to the
client..
for that i wnted to hook cocreateinstance and add source grabbler
filter..
i read this procedure in some post ..
http://www.eggheadcafe.com/software/aspnet/31775470/-hooking-igraphbuilder.aspx
i could hook from same process .. and rest all u know ..

Alessandro Angeli

unread,
Jun 24, 2010, 1:48:15 PM6/24/10
to
From: "chom"

[...]


> i wanted to capture video data coming frm demuxer ..and send to the
> client..

That would be pointless: in WMP, the source/demux outputs decompressed
data so you need to hook the input to the decoders, as I already told
you.

> for that i wnted to hook cocreateinstance and add source grabbler
> filter..
> i read this procedure in some post ..
> http://www.eggheadcafe.com/software/aspnet/31775470/-hooking-igraphbuilder.aspx
> i could hook from same process .. and rest all u know ..

I wrote that, no need to quote it to me. Hooking CoCreateInstance() is
not enough: that will allow you to intercept the creation of the object,
but then you will need to hook selected methods on the object's
interfaces (quicker) or to wrap the object in your own implementation
(safer).

Let's say you want to rip WMV files in WMP:

1. inject your code in WMP

2. hook CoCreateInstance()

3a. when the WMV decoder is created, wrap it in your own object (that
implements the same interfaces and simply forwards all the calls to the
real object) and return your wrapper

3b. insteads of wrapping the object, you can hook the methods you are
interested in

Assume the object is used as a DMO (WMV files in WMP up to v10 on XP or
older). You will need to intercept *at least* the following methods in
IMediaObject: SetInputType(,,0), ProcessInput(), Discontinuity(),
Flush() and SetInputMaxLatency().

If it is used as an MFT (WMV files in WMP starting with v11 on Vista or
newer), you will need to intercept the equivalent methods in
IMFTransform.

If the files are protected, the anti-hacking techniques in WMP will get
in the way.

Most DirectShow-based players (e.g. MPC or MPC-HC) will use the DMO.
Other players (VLC or RealPlayer or whatever) will use whatever they
like: it may be the DMO or something else entirely, you'll have to find
out yourself.

IMHO the whole thing is pointless.

If the file has high quality, than it also has a high bitrate, which
requires a large bandwidth, common only on LANs. If such large bandwidth
is available, then probably you can just send the recompressed screen
grabs without too much loss in quality.

If the file has low quality so that it doesn't need a large bandwidth,
sending recompressing screen grabs won't make much of a difference.

I think this is more than enough to get you started and I will not be
replying to any further questions unless they are very specific ones,
showing that you are doing your homework.

0 new messages