Chrome IPC Internals – Part II

In this part, we will see how to write a simple client/server component interacting using Chrome IPC. This is a very basic one. I have never found a tutorial to create one such PoC. By extending this, we can use Chrome IPC in private projects.

IPCMessage.h

#pragma once

#define IPC_MESSAGE_START TestMsgStart

// Generic message class that is an int followed by a wstring.
IPC_MESSAGE_CONTROL2(MsgClassIS, int, std::wstring)

// Generic message class that is a wstring followed by an int.
IPC_MESSAGE_CONTROL2(MsgClassSI, std::wstring, int)

// Used to generate an ID for a message that should not exist.
IPC_MESSAGE_CONTROL0(MsgUnhandled)

IPCClient1.cc

#include <iostream>
#include <string.h>

#include “base/basictypes.h”
#include “ipc/ipc_message.h”
#include “ipc/ipc_message_utils.h”
#include “ipc/ipc_channel.h”
#include “base/logging.h”
#include “base/threading/platform_thread.h”
#include “base/message_loop.h”

const char kFuzzerChannel[] = “channelName”;

#define IPC_MESSAGE_IMPL
#include “ipc/ipc_message_macros.h”

#include <IPCMessage.h>

/* Listener */
class SimpleListener : public IPC::Listener {
    public:
        SimpleListener() : other_(NULL) {}
   
        void Init(IPC::Sender* s)
        {
            other_ = s;
        }
       
        virtual bool OnMessageReceived(const IPC::Message& msg) {
            std::cout << “Listener::OnMessageReceived(): Message Received” << std::endl;
            return true;
        }
       
        virtual void OnChannelConnected(int32 peer_pid)
        {
            std::cout << “Listener::OnChannelConnected(): Channel Connected” << std::endl;
           
            IPC::Message* msg = NULL;
            int value = 43;
            msg = new MsgClassIS(value, L”expect 43″);
            if(! other_->Send(msg)){
                std::cout << “Error in sending MsgClassIS” << std::endl;
                return;
            }
            std::cout << “Sent MsgClassIS” << std::endl;
           
            msg = new MsgClassSI(L”expect 44″, ++value);
            if(! other_->Send(msg)){
                std::cout << “Error in sending MsgClassSI” << std::endl;
                return;
            }
            std::cout << “Sent MsgClassSI” << std::endl;
        }
       
        virtual void OnChannelError()
        {
            std::cout << “Listener::OnChannelError(): Channel Error” << std::endl;
            exit(0);
        }
    protected:
        IPC::Sender* other_;
};

/* Main */
void main()
{
    SimpleListener clientListener;
    MessageLoopForIO main_message_loop;
   
    std::cout << “Client: Creating IPC channel ” << kFuzzerChannel << std::endl;
    IPC::Channel clientChannel(kFuzzerChannel, IPC::Channel::MODE_SERVER, &clientListener);
   
    //std::cout << “Waiting for IPC Server to come up ” << std::endl;
    //base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(5));
    std::cout << “Client: Connecting to IPC channel ” << kFuzzerChannel << std::endl;
    if(! clientChannel.Connect()){
        std::cout << “Error in connecting to the channel ” << kFuzzerChannel << std::endl;
        return;
    }
    std::cout << “Client: Connected to IPC channel ” << kFuzzerChannel << std::endl;
   
    std::cout << “Initializing listener” << std::endl;
    clientListener.Init(&clientChannel);
   
    std::cout << “Starting the MessageLoop” << std::endl;
    MessageLoop::current()->Run();
}

IPCServer.cc

#include <iostream>
#include <string.h>

#include “base/basictypes.h”
#include “ipc/ipc_message.h”
#include “ipc/ipc_message_utils.h”
#include “ipc/ipc_channel.h”
#include “base/logging.h”
#include “base/threading/platform_thread.h”
#include “base/message_loop.h”

const char kFuzzerChannel[] = “channelName”;

#define IPC_MESSAGE_IMPL
#include “ipc/ipc_message_macros.h”

#include <IPCMessage.h>

/* Listener */
class SimpleListener : public IPC::Listener {
    public:
        SimpleListener() : other_(NULL) {}
   
        void Init(IPC::Sender* s)
        {
            other_ = s;
        }
       
        virtual bool OnMessageReceived(const IPC::Message& msg) {
            std::cout << “Listener::OnChannelConnected(): Message Received” << std::endl;
            IPC_BEGIN_MESSAGE_MAP(SimpleListener, msg)
                IPC_MESSAGE_HANDLER(MsgClassIS, classIS)
                IPC_MESSAGE_HANDLER(MsgClassSI, classSI)
            IPC_END_MESSAGE_MAP()
            return true;
        }
       
        virtual void OnChannelConnected(int32 peer_pid)
        {
            std::cout << “Listener::OnChannelConnected(): Channel Connected” << std::endl;
        }
       
        virtual void OnChannelError()
        {
            std::cout << “Listener::OnChannelConnected(): Channel Error” << std::endl;
            exit(0);
        }
       
        void classIS(int myint, std::wstring mystring) {
            std::cout << “classIS(): Received==> Int:” << myint << ” String:” << mystring << std::endl;
        }
       
        void classSI(std::wstring mystring,int myint) {
            std::cout << “classSI(): Received==> String:” << mystring << ” Int:” << myint << std::endl;
        }
   
    protected:
        IPC::Sender* other_;
};

/* Main */
void main()
{
    SimpleListener serverListener;
    MessageLoopForIO main_message_loop;
   
    std::cout << “Server: Creating IPC channel ” << kFuzzerChannel << std::endl;
    IPC::Channel serverChannel(kFuzzerChannel, IPC::Channel::MODE_CLIENT, &serverListener);

    std::cout << “Server: Connecting to IPC channel ” << kFuzzerChannel << std::endl;
    if(! serverChannel.Connect()){
        std::cout << “Server: Error in connecting to the channel ” << kFuzzerChannel << std::endl;
        return;
    }
    std::cout << “Server: Connected to IPC channel ” << kFuzzerChannel << std::endl;
   
    std::cout << “Initializing listener” << std::endl;
    serverListener.Init(&serverChannel);

    std::cout << “Starting the MessageLoop” << std::endl;
    MessageLoop::current()->Run();
}

To compile:

(You need both Chrome’s base library and Chrome’s IPC library.)

cl /Zi /D “_UNICODE” /D “UNICODE” -I. IPCClient1.cc /link /LIBPATH:build\Release\lib psapi.lib Advapi32.lib Dbghelp.lib Shell32.lib User32.lib base.lib ipc.lib

cl /Zi /D “_UNICODE” /D “UNICODE” -I. IPCServer.cc /link /LIBPATH:build\Release\lib psapi.lib Advapi32.lib Dbghelp.lib Shell32.lib User32.lib base.lib ipc.lib

Advertisements
This entry was posted in C/C++, Chrome, Cr-48, Internals and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s