silverf0x / RpcView

RpcView is a free tool to explore and decompile Microsoft RPC interfaces
GNU General Public License v3.0
920 stars 250 forks source link

[WIP] DecompileIt : console line tool to decompile rpc interface #8

Open 1orenz0 opened 6 years ago

1orenz0 commented 6 years ago

Hi,

I wanted to extract and decompile some RPC interfaces from MIDL_STUB_DESC structures embedded in a binary. However the binary in question is the client side, and RpcView don't decompile the interface since it's server-oriented.

Anyway I ripped the code I needed from the codebase and I wrote a console line utility for it. Basically you need to feed the target process PID, the specified module name, offsets to the MIDL_STUB_DESC descriptor and StringFormat, and the offsets table for StringFormat.

The output is close to RpcView server-side decompilation, with some interesting differences :

Client side

DecompileIt.exe --pid EXPLORER_PID --module ResourcePolicyClient.dll --descriptor 0xf410 --format-str 0x11ba2 --format-str-offsets 0,0x30,0x66,0x90,0xc0

[
uuid(88abcbc3-34ea-76ae-8215-767520655a23),
version(0.0),
]
interface DecompileItInterface
{

        typedef struct Struct_12_t
        {
                long    StructMember0;
                short   StructMember1;
                short   StructMember2;
                byte    StructMember3[8];
        }Struct_12_t;

        typedef struct Struct_156_t
        {
                long    StructMember0;
                [unique] /* [DBG] FC_BOGUS_ARRAY */ [size_is(StructMember3)]/*[range(0,0)]*/ [length_is( arg_0)] /*  */ /* FC_ZERO */;
                long    StructMember2;
                /* enum_16 */ short     StructMember3;
                [unique][string] wchar_t*       StructMember4;
                [unique][string] wchar_t*       StructMember5;
                long    StructMember6;
        }Struct_156_t;

long Proc0(
        [in]/* simple_ref */struct Struct_12_t* arg_2,
        [in][out]/* simple_ref */long *arg_4);

long Proc1(
        [in]/* simple_ref */struct Struct_12_t* arg_2,
        [in][out]/* simple_ref */long *arg_4,
        [in][out]/* simple_ref */[size_is(*arg_4)]/*[range(0,0)]*/ /* FC_ZERO */);

long Proc2(
        [in][out]/* simple_ref */long *arg_2);

long Proc3(
        [in][out]/* simple_ref *//*[range(0,1048576)] */long *arg_2,
        [out]/* simple_ref */[size_is(*arg_2)]/*[range(1,0)]*/ error_status_t *arg_4);

long Proc4(
        [in]/* simple_ref */struct Struct_12_t* arg_2,
        [in]/* simple_ref */struct Struct_156_t* arg_4);

...
}

Server side

[
uuid(88abcbc3-34ea-76ae-8215-767520655a23),
version(0.0),
]
interface DefaultIfName
{

    typedef struct Struct_12_t
    {
        long    StructMember0;
        short   StructMember1;
        short   StructMember2;
        byte    StructMember3[8];
    }Struct_12_t;

    typedef struct Struct_98_t
    {
        long    StructMember0;
        [unique][string] wchar_t*   StructMember1;
    }Struct_98_t;

    typedef struct Struct_156_t
    {
        long    StructMember0;
        [unique] /* [DBG] FC_BOGUS_ARRAY */ [size_is(StructMember2)]/*[range(0,0)]*/  /*  */ struct Struct_98_t*    StructMember1;
        long    StructMember2;
        /* enum_16 */ short     StructMember3;
        [unique][string] wchar_t*   StructMember4;
        [unique][string] wchar_t*   StructMember5;
        long    StructMember6;
    }Struct_156_t;

long Proc0(
    [in]struct Struct_12_t* arg_1, 
    [in][out]long *arg_2);

long Proc1(
    [in]struct Struct_12_t* arg_1, 
    [in][out]long *arg_2, 
    [in][out][size_is(*arg_2)]/*[range(0,0)]*/ byte *arg_3);

long Proc2(
    [in][out]long *arg_1);

long Proc3(
    [in][out]/*[range(0,1048576)] */long *arg_1, 
    [out][size_is(*arg_1)]/*[range(0,1048576)]*/ byte *arg_2);

long Proc4(
    [in]struct Struct_12_t* arg_1, 
    [in]struct Struct_156_t* arg_2);

...
}

If you're interested in merging it in RpcView in some way and have questions, please hit me with it. If you have no love for this, I'm also cool with it (this tool already served its purpose).

bibis,

L