MAPITRACE

From OpenChange wiki

Jump to: navigation, search


Contents

Purpose and Scope

MAPITRACE is an exprimental MAPI tracing tool that help MAPI developers investigate throught MAPI PCAP files or scenarios and have a better overview of how things work. There is two layers of analysis which help to decode serialized packets or have a general overview of the global MAPI calls interaction along the whole communication.

This tool is a PERL wrapper over ndrdump output and assume the scenario has initially been split into ndrdump files whether manually using wireshark or with rpcextract.

Requirements

Mapitrace requires you have the following PERL packages installed:

Mapitrace also requires you to download and install the following tools and solutions:

Installation

The tool is currently only available on the MAILOOK branch

$ cd utils/mapitrace
$ perl Makefile.PL
$ make
# make install

Modules Overview

Tracing and Searching

trace

The tracing module can be called using the --trace command line option. The trace option only works at serialization level. It takes a request and its associated response, inpect the calls, return values and the handles they are using so it can dump the mapi call hierarchy throught the MAPI packet.

This option doesn't intend to provide a global overview of the mapi communication but focus on how mapi calls interacts together within a single packet using the handle hierarchy mechanism.

search-call

The --search-call option provides a mechanism allowing the user to dig into decoded MAPI packets and search for a particular MAPI calls. It takes the mapi call to search as parameter and return the braces where the call can be found.

dump-call

The --dump-call option used with --search-call and --inout provides a way to dump all the ndrdump packets where the searched call is located.

Graph

graph

The --graph option generates a png file graphic from the parsed data. It maps mapi calls as nodes and add edges between them. The objective is to have a global overview of the mapi calls interaction and see how calls depends on each other.

highlight

The --highlight option has to be used concurrently with the graph one and takes a mapi call name as parameter. This option highlight all nodes occurences holding the same name within the graph so it gets easier for developers to search specific calls.

Statistic and Error Report

stats

The statistic option --stats currently only provides trivial information. It calculates the number of request/responses that have been decoded and reports success rates.

error_report

The --error_report option can take in and out as parameter. (e.g: --error_report=in,out). It is used to identify files ndrdump had troubles with, so we can next investigate manually (fix the call IDL or implement the unknown call one)

Command Line Options

[jkerihuel@localhost branches]$ mapitrace --help
mapi call hierarchy tracing tool and IDL regression support
Copyright (C) Julien Kerihuel <j.kerihuel@openchange.org>

Usage: mapitrace [options]

Generic Options:
--help                 this help page
--outputdir=OUTDIR     put output in OUTDIR/ []
--graph                create a png graph
--trace                dump the mapi call hierarchy on command line
--verbose              verbose output

Tracing Options:
--search-call=CALL     trace a single call though a scenario
--dump-call            dump all the packets containing the call specified
--highlight=CALL       highlight a call in the generated graph
--inout=INOUT          filter either requests (in) or response (out)
Regression Options:
--error_report=in,out  Investigate invalid packets
--stats                Display statistics for a given scenario

Study Case

Here is a sample working session output for a small scenario:

Environment

Prior you can run mapitrace, you need to explode pcap files in ndrdump files using rpcextract:

 rpcextract -i MAPI-FOLDER.pcap -d MAPI-FOLDER -p Mapi

graph option

[jkerihuel@localhost MAPI_torture]$ mapitrace --trace MAPI-FOLDER
MAPI-FOLDER torture test graph
MAPI-FOLDER torture test graph

highlight graph option

[jkerihuel@localhost MAPI_torture]$ mapitrace --graph --highlight=CreateFolder MAPI-FOLDER
MAPI-FOLDER torture test graph with CreateFolder call highlighted
MAPI-FOLDER torture test graph with CreateFolder call highlighted

search option

[jkerihuel@localhost MAPI_torture]$ mapitrace --search-call=OpenMsgStore MAPI-FOLDER
[X] Call found in [ MAPI-FOLDER ]:
        OpenMsgStore: 29_in_Mapi_EcDoRpc / 30_out_Mapi_EcDoRpc
[jkerihuel@localhost MAPI_torture]$ 


trace option

[jkerihuel@localhost MAPI_torture]$ mapitrace --trace MAPI-FOLDER
29_in_Mapi_EcDoRpc / 30_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0xfe)              OpenMsgStore (handle_idx = 0x00)

handles array (1):
        [00] 0xffffffff -> 0x000000b5


31_in_Mapi_EcDoRpc / 32_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x27)          GetReceiveFolder (handle_idx = 0x00)

handles array (1):
        [00] 0x000000b5 -> 0x000000b5


33_in_Mapi_EcDoRpc / 34_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x02)                OpenFolder (handle_idx = 0x00) (self_handle_idx = 0x01)

handles array (2):
        [00] 0x000000b5 -> 0x000000b5
        [01] 0xffffffff -> 0x000000ad


35_in_Mapi_EcDoRpc / 37_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x1c)              CreateFolder (handle_idx = 0x00) (self_handle_idx = 0x01)

handles array (2):
        [00] 0x000000ad -> 0x000000ad
        [01] 0xffffffff -> 0x000000ab


38_in_Mapi_EcDoRpc / 39_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x1c)              CreateFolder (handle_idx = 0x00) (self_handle_idx = 0x01)

handles array (2):
        [00] 0x000000ab -> 0x000000ab
        [01] 0xffffffff -> 0x000000a4


40_in_Mapi_EcDoRpc / 41_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x58)               EmptyFolder (handle_idx = 0x00)

handles array (1):
        [00] 0x000000ab -> 0x000000ab


42_in_Mapi_EcDoRpc / 43_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x04)         GetHierarchyTable (handle_idx = 0x00) (self_handle_idx = 0x01)

handles array (2):
        [00] 0x000000ab -> 0x000000ab
        [01] 0xffffffff -> 0x000000a3


44_in_Mapi_EcDoRpc / 45_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x17)               GetRowCount (handle_idx = 0x00)

handles array (1):
        [00] 0x000000a3 -> 0x000000a3


46_in_Mapi_EcDoRpc / 47_out_Mapi_EcDoRpc
----------------------------------------------
serialized mapi calls (count = 01):
        [0x00] [MAPI_E_SUCCESS] (opnum = 0x1d)              DeleteFolder (handle_idx = 0x00)

handles array (1):
        [00] 0x000000ad -> 0x000000ad

dump-call option

[jkerihuel@host MAPI_torture]$ mapitrace --search-call=OpenFolder --dump-call --inout=in MAPI-FOLDER
   0x2: struct EcDoRpc
       in: struct EcDoRpc
           handle                   : *
               handle: struct policy_handle
                   handle_type              : 0x00000000 (0)
                   uuid                     : 76398088-7413-430b-89a6-d2c5cb533f10
           size                     : 0x00000500 (1280)
           offset                   : 0x00000000 (0)
           mapi_request             : *
               mapi_len                 : 0x00000017 (23)
               length                   : 0x000f (15)
                   mapi_request: struct EcDoRpc_MAPI_REQ
                       opnum                    : 0x02 (2)
                       mapi_flags               : 0x00 (0)
                       handle_idx               : 0x00 (0)
                       u                        : union EcDoRpc_MAPI_REQ_UNION(case 2)
                       mapi_OpenFolder: struct OpenFolder_req
                           handle_idx               : 0x01 (1)
                           folder_id                : 0x1d28000000000001 (2100929226168336385)
                           unknown                  : 0x00 (0)
                   mapi_request             : (handles) number=2
                       handle                   : 0x000000b5 (181)
                       handle                   : 0xffffffff (4294967295)
               length                   : *
                   length                   : 0x0017 (23)
               max_data                 : 0x0500 (1280)
pull returned NT_STATUS_OK
dump OK
[X] Call found in [ MAPI-FOLDER ]:
       OpenFolder: 33_in_Mapi_EcDoRpc / 34_out_Mapi_EcDoRpc


stats option

[jkerihuel@localhost MAPI_torture]$ mapitrace --stats MAPI-FOLDER
+-----[ Scenario: MAPI-FOLDER ]-----+
[statistic]: We have 18 packets (request: 50%, response: 50%)
[statistic]: request success rate: 100
[statistic]: response success rate: 100
[statistic]: success brace analysis rate: 100%
[statistic]: no braces skipped
+--------------------------------------------------------------+

TODO

  • Clean up the code
  • Fix many small bugs
  • add a shell module so any mapitrace operation can be done within a small shell
  • add a fuzzer module able to detect unknown mapi call and generate pseudo-IDL or gather the amount of data necessary to write the IDL for the unknown call.
Personal tools
Toolbox