aboutsummaryrefslogtreecommitdiffhomepage
path: root/ext/detours/samples/commem/commem.cpp
blob: 677984382fd4517e2835c82fa7634ef7781d76e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//////////////////////////////////////////////////////////////////////////////
//
//  Detour functions of a COM interface (commem.cpp of commem.exe)
//
//  Microsoft Research Detours Package
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
//
#include <stdio.h>

//////////////////////////////////////////////////////////////////////////////
//
//  WARNING:
//
//  CINTERFACE must be defined so that the lpVtbl pointer is visible
//  on COM interfaces.  However, once we've defined it, we must use
//  coding conventions when accessing interface members, for example:
//      i->lpVtbl->Write
//  instead of the C++ syntax:
//      i->Write.
//  We must also pass the implicit "this" parameter explicitly:
//      i->lpVtbl->Write(i, pb, 0, NULL)
//  instead of the C++ syntax:
//      i->Write(pb, 0, NULL)
//
#define CINTERFACE
#include <ole2.h>
#include <windows.h>
#include <detours.h>

//////////////////////////////////////////////////////////////////////////////
//
HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
                                              const void *pv,
                                              ULONG cb,
                                              ULONG *pcbWritten) = NULL;

HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
                                           const void *pv,
                                           ULONG cb,
                                           ULONG *pcbWritten)
{
    HRESULT hr;
    ULONG cbWritten = 0;
    if (pcbWritten == NULL) {
        pcbWritten = &cbWritten;
    }

    printf("commem:   %p->IStreamWrite(pv=%p, cb=%ld)\n", This, pv, cb);
    hr = RealIStreamWrite(This, pv, cb, pcbWritten);
    printf("commem:   %p->IStreamWrite -> %08lx (pcbWritten=%ld)\n", This, hr, *pcbWritten);

    return hr;
}

//////////////////////////////////////////////////////////////////////////////
//
int main(int argc, char **argv)
{
    HRESULT hr;

    (void)argc;
    (void)argv;

    LPSTREAM pStream = NULL;
    ULARGE_INTEGER ul;
    LARGE_INTEGER li;

    CoInitialize(NULL);

    hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);

    RealIStreamWrite = pStream->lpVtbl->Write;

    ul.QuadPart = 512;
    hr = pStream->lpVtbl->SetSize(pStream, ul);
    li.QuadPart = 0;
    hr = pStream->lpVtbl->Seek(pStream, li, STREAM_SEEK_SET, NULL);

    printf("commem: Calling Write w/o before attach.\n");

    li.QuadPart = 0;
    hr = pStream->lpVtbl->Write(pStream, &ul, sizeof(ul), NULL);

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
    DetourTransactionCommit();

    printf("commem: Calling Write w/o after attach.\n");

    li.QuadPart = 1;
    hr = pStream->lpVtbl->Write(pStream, &li, sizeof(li), NULL);

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourDetach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
    DetourTransactionCommit();

    printf("commem: Calling Write w/o after detach.\n");

    li.QuadPart = 2;
    hr = pStream->lpVtbl->Write(pStream, &li, sizeof(li), NULL);

    hr = pStream->lpVtbl->Release(pStream);
    pStream = NULL;

    CoUninitialize();

    return 0;
}