пятница, 8 марта 2013 г.

UCXFunctions.idc

It seems that KMDF has possibility to register extension drivers with undocumented (as usually) function WdfRegisterClassLibrary
For example driver Ucx01000.sys (USB host controller extension) contains functions table which I named UCXFUNCTIONS. I wrote simple IDC script to find and add this structure (in addition to ordinary WDFFUNCTIONS) in clients drivers of this extension
#include <idc.idc>

static add_struct(size)
{
 auto id;
 id = AddStrucEx(-1,"UCXFUNCTIONS",0);
 if ( -1 == id )
   id = GetStrucIdByName("UCXFUNCTIONS");
 if ( -1 == id )
   return -1;
 AddStrucMember(id,"UcxIoDeviceControl",    0X0,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxControllerCreate",    0X4,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxControllerNeedsReset",    0X8,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxControllerResetComplete",0Xc,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxControllerSetFailed",    0X10,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxRootHubCreate",        0X14,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxRootHubPortChanged",    0X18,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxUsbDeviceCreate",    0X1c,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxUsbDeviceInitSetEventCallbacks",    0X20,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxUsbDeviceRemoteWakeNotification",    0X24,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointCreate",        0X28,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointGetStaticStreamsReferenced",    0X2c,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointNeedToCancelTransfers",    0X30,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointInitSetEventCallbacks",    0X34,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxDefaultEndpointInitSetEventCallbacks",    0X38,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointSetWdfIoQueue",    0X3c,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointPurgeComplete",    0X40,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointStartComplete",    0X44,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointAbortComplete",    0X48,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxEndpointNoPingResponseError",    0X4c,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxStaticStreamsSetStreamInfo",    0X50,    0x20000400,    -1,    4);
 AddStrucMember(id,"UcxStaticStreamsCreate",    0X54,    0x20000400,    -1,    4);
  return id;
}

static main(void)
{
  auto data_start;
  auto data_end;
  auto idx;
  // out data
  auto wdf_size;
  auto wdf_func;

  data_end = data_start = BADADDR;
  wdf_size = 0;
  wdf_func = BADADDR;
  // find .data section
  for ( idx = FirstSeg(); idx != BADADDR; idx = NextSeg(idx) )
  {
    auto sname;
    sname = SegName(idx);
    if ( (strlen(sname) == 5) &&
         strstr(sname, ".data") != 0
       )
    {
      data_start = SegStart(idx);
      data_end   = SegEnd(idx);
      break;
    }
  }
  if ( data_start == BADADDR )
    return;
  // find "Ucx" unicode string in .data section
  idx = data_start;
  while(1)
  {
    auto addr, id;
    idx = FindBinary(idx, SEARCH_DOWN, "55 00 63 00 78 00 00 00");
    if ( idx == BADADDR )
      break;
    Message("found at %X\n", idx);
    addr = DfirstB(idx);
    if ( addr != BADADDR )
    {
      id = 0;
      Message("ref from %X\n", addr);
      wdf_size = Dword(addr + 0x14);
      wdf_func = Dword(addr + 0x10);
      if ( wdf_size != 0 )
      {
        id = add_struct(wdf_size);
      }
      if ( id != 0 )
      {
        auto ssize;
        ssize = GetStrucSize(id);
        MakeUnknown(wdf_func, ssize, 0);
        if ( MakeData(wdf_func, FF_STRU, ssize, id) )
        {
          return;
        }
        Message("MakeData failed at %X, size %X\n", wdf_func, ssize);
      }
    }
    idx = idx + 6; /* length of unicode string Ucx */
  }
}

Комментариев нет:

Отправить комментарий